//--- Beschreibung #property description "Das Skript erstellt ein graphisches Objekt \"Andrew's Pitchfork\"." #property description "Koordinaten des Bezugspunktes werden in Prozent von" #property description "der Größe des Chartfensters eingegeben." //--- Zeigen den Fenster von Eingabeparametern in der Skript-Startup #property script_show_inputs //--- Eingangsparameter von Skript input string InpName="Pitchfork"; // Name input int InpDate1=14; // Datum des ersten Punktes in % input int InpPrice1=40; // Preis des ersten Punktes in % input int InpDate2=18; // Datum des zweiten Punktes in % input int InpPrice2=50; // Preis des zweiten Punktes in % input int InpDate3=18; // Datum des dritten Punktes in % input int InpPrice3=30; // Preis des dritten Punktes in % input color InpColor=clrRed; // Farbe input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Linienstil input int InpWidth=1; // Linienbreite input bool InpBack=false; // Pitchfork im Hintergrund input bool InpSelection=true; // Wählen um zu bewegen input bool InpRayLeft=false; // Fortsetzung von Pitchfork nach links input bool InpRayRight=false; // Fortsetzung von Pitchfork nach rechts input bool InpHidden=true; // Ausgeblendet in der Objektliste input long InpZOrder=0; // Priorität auf Mausklick //+------------------------------------------------------------------+ //| Erstellt Andrew's Pitchfork auf angegebenen Koordinaten | //+------------------------------------------------------------------+ bool PitchforkCreate(const long chart_ID=0, // ID des Charts const string name="Pitchfork", // Name const int sub_window=0, // Nummer des Unterfensters datetime time1=0, // Zeit des ersten Punktes double price1=0, // Preis des ersten Punktes datetime time2=0, // Zeit des zweiten Punktes double price2=0, // Preis des zweiten Punktes datetime time3=0, // Zeit des dritten Punktes double price3=0, // Preis des dritten Punktes const color clr=clrRed, // Linienfarbe const ENUM_LINE_STYLE style=STYLE_SOLID, // Linienstil const int width=1, // Linienbreite const bool back=false, // In der Hintergrund const bool selection=true, // Wählen um zu bewegen const bool ray_left=false, // Fortsetzung von Pitchfork nach links const bool ray_right=false, // Fortsetzung von Pitchfork nach rechts const bool hidden=true, // Verborgen in der Liste der Objekten const long z_order=0) // Priorität für Mausklick { //--- Die Koordinaten der Bezugspunkte angeben, wenn sie nicht gesetzt sind ChangeChannelEmptyPoints(time1,price1,time2,price2,time3,price3); //--- Setzen den Wert des Fehlers zurück ResetLastError(); //--- Andrew's Pitchfork auf angegebenen Koordinaten erstellen if(!ObjectCreate(chart_ID,name,OBJ_PITCHFORK,sub_window,time1,price1,time2,price2,time3,price3)) { Print(__FUNCTION__, ": Objekt \" Andrew's Pitchfork\" konnte nicht erstellt werden! Fehlercode = ",GetLastError()); return(false); } //--- Farbe setzen ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- Linienstil setzen ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- Linienbreite angeben ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- Im Vordergrund (false) oder Hintergrund (true) anzeigen ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- aktivieren (true) oder deaktivieren (false) Wählen von Andrew's Pitchfork für Bewegung //--- Wenn Sie ein grafisches Objekt durch Funktion ObjectCreate erstellen, das Objekt //--- kann nicht ausgewählt und verschoben werden. Innerhalb dieser Methode ist der Standardwert des Parameters selection //--- true, was Sie das Objekt auswählen und verschieben erlaubt ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- aktivieren (true) oder deaktivieren (false) Fortsetzung von Andrew's Pitchfork nach links ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left); //--- aktivieren (true) oder deaktivieren (false) Fortsetzung von Andrew's Pitchfork nach rechts ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); //--- Verbergen (true) oder Anzeigen (false) den Namen des graphischen Objektes in der Objektliste ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- setzen die Priorität für eine Mausklick-Ereignisse auf dem Chart ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- die erfolgreiche Umsetzung return(true); } //+------------------------------------------------------------------+ //| Gibt Anzahl der Niveaus von "Andrew's Pitchfork" und Parameter an| //+------------------------------------------------------------------+ bool PitchforkLevelsSet(int levels, // Anzahl der Niveaulinien double &values[], // Werte der Linien color &colors[], // Farbe der Linien ENUM_LINE_STYLE &styles[], // Linienstil int &widths[], // Linienbreite const long chart_ID=0, // ID des Charts const string name="Pitchfork") // Name { //--- Überprüfen wir die Größe des Arrays if(levels!=ArraySize(colors) || levels!=ArraySize(styles) || levels!=ArraySize(widths) || levels!=ArraySize(widths)) { Print(__FUNCTION__,": Länge des Arrays entspricht nicht der Anzahl der Niveaus, Fehler!"); return(false); } //--- Die Anzahl der Ebenen angeben ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels); //--- die Eigenschaften der Ebenen im Zyklus angeben for(int i=0;i<levels;i++) { //--- Wert der Ebene ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]); //--- Farbe der Ebene ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]); //--- Stil der Ebene ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]); //--- Stärke der Ebene ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]); //--- Beschreibung der Ebene ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1)); ;} //--- die erfolgreiche Umsetzung return(true); } //+------------------------------------------------------------------+ //| Verschiebt den Ankerpunkt von Andrew's Pitchfork | //+------------------------------------------------------------------+ bool PitchforkPointChange(const long chart_ID=0, // ID des Charts const string name="Pitchfork", // Kanalname const int point_index=0, // Nummer des Ankerpunktes datetime time=0, // Zeitkoordinate des Punktes double price=0) // Preiskoordinate des Punktes { //--- Wenn die Koordinaten des Punktes nicht angegeben sind, dann verschieben wir es an den aktuellen Bar mit dem Preis Bid if(!time) time=TimeCurrent(); if(!price) price=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- Setzen den Wert des Fehlers zurück ResetLastError(); //--- bewegen den Bezugspunkt if(!ObjectMove(chart_ID,name,point_index,time,price)) { Print(__FUNCTION__, ": der Bezugspunkt konnte nicht bewegt werden! Fehlercode = ",GetLastError()); return(false); } //--- die erfolgreiche Umsetzung return(true); } //+------------------------------------------------------------------+ //| Löscht das Objekt "Andrew's Pitchfork" | //+------------------------------------------------------------------+ bool PitchforkDelete(const long chart_ID=0, // ID des Charts const string name="Pitchfork") // Kanalname { //--- Setzen den Wert des Fehlers zurück ResetLastError(); //--- den Kanal löschen if(!ObjectDelete(chart_ID,name)) { Print(__FUNCTION__, ": Objekt \" Andrew's Pitchfork\" konnte nicht gelöscht werden! Fehlercode = ",GetLastError()); return(false); } //--- die erfolgreiche Umsetzung return(true); ;} //+------------------------------------------------------------------+ //| Überprüft die Werte der Ankerpunkten von Andrew's Pitchfork | //| und setzt Standardwerte für leere Werte | //+------------------------------------------------------------------+ void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2, double &price2,datetime &time3,double &price3) { //--- wenn die Zeit des zweiten (rechten oberen) Punktes nicht angegeben ist, wird sie auf dem aktuellen Bar sein if(!time2) time2=TimeCurrent(); //--- wenn der Preis des zweiten Punktes nicht angegeben ist, wird er dem Bid-Wert gleich sein if(!price2) price2=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- wenn die Zeit des ersten (linken) Punktes nicht angegeben ist, wird sie auf 9 Baren nach links sein if(!time1) { //--- Array um Eröffnungszeit der letzten 10 Bars aufzunehmen datetime temp[10]; CopyTime(Symbol(),Period(),time2,10,temp); //--- stellen wir den ersten Punkt 9 Baren links dem zweiten Punkt time1=temp[0]; } //--- wenn der Preis des ersten Punktes nicht angegeben ist, bewegen wir ihn 200 Punkte niedriger als der zweite if(!price1) price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT); //--- wenn die Zeit des dritten Punktes nicht angegeben ist, wird sie der Zeit des zweiten Punktes gleich sein if(!time3) time3=time2; //--- wenn der Preis des dritten Punktes nicht angegeben ist, bewegen wir ihn 200 Punkte niedriger als der erste if(!price3) price3=price1-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Überprüfen die Richtigkeit der Eingabeparameter if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 || InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 || InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100) { Print("Fehler! Ungültige Eingabeparameter! "); return; } //--- Die Anzahl der sichtbaren Bars im Chart-Fenster int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS); //--- Größe des Arrays price int accuracy=1000; //--- Arrays für Werte von Daten und Preise, die für Setzung und Änderung //--- der Koordinaten der Ankerpunkten von Andrew's Pitchfork verwendet werden datetime date[]; double price[]; //--- Speicher reservieren ArrayResize(date,bars); ArrayResize(price,accuracy); //--- Füllen die Anordnung von Daten ResetLastError(); if(CopyTime(Symbol(),Period(),0,bars,date)==-1) { Print("Kann nicht den Wert der Zeit kopieren! Fehlercode = ",GetLastError()); return; } //--- Füllen den Array der Preise //--- den Minimal- und Maximalwert der Charts finden double max_price=ChartGetDouble(0,CHART_PRICE_MAX); double min_price=ChartGetDouble(0,CHART_PRICE_MIN); //--- Schritte der Preisänderung finden und das Array füllen double step=(max_price-min_price)/accuracy; for(int i=0;i<accuracy;i++) price[i]=min_price+i*step; //--- Definieren die Punkte um Andrew's Pitchfork zu zeichnen int d1=InpDate1*(bars-1)/100; int d2=InpDate2*(bars-1)/100; int d3=InpDate3*(bars-1)/100; int p1=InpPrice1*(accuracy-1)/100; int p2=InpPrice2*(accuracy-1)/100; int p3=InpPrice3*(accuracy-1)/100; //--- Andrew's Pitchfork erstellen if(!PitchforkCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3], InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder)) { return; } //--- den Chart neu zeichnen und 1 Sekunde warten ChartRedraw(); Sleep(1000); //--- jetzt bewegen wir die Ankerpunkte //--- Schleifenzähler int v_steps=accuracy/10; //--- den ersten Punkt bewegen for(int i=0;i<v_steps;i++) { //--- den nächsten Wert nehmen if(p1>1) p1-=1; //--- den Punkt bewegen if(!PitchforkPointChange(0,InpName,0,date[d1],price[p1])) return; //--- Überprüfen die Fakten von Zwangsabschaltung der Skript if(IsStopped()) return; //--- den Chart neu zeichnen ChartRedraw(); } //--- 1 Sekunde Verzögerung Sleep(1000); //--- Schleifenzähler int h_steps=bars/8; //--- den dritten Punkt bewegen for(int i=0;i<h_steps;i++) { //--- den nächsten Wert nehmen if(d3<bars-1) d3+=1; //--- den Punkt bewegen if(!PitchforkPointChange(0,InpName,2,date[d3],price[p3])) return; //--- Überprüfen die Fakten von Zwangsabschaltung der Skript if(IsStopped()) return; //--- den Chart neu zeichnen ChartRedraw(); //--- den Chart neu zeichnen ChartRedraw(); // Verzögerung 0.05 Sekunden Sleep(50); } //--- 1 Sekunde Verzögerung Sleep(1000); //--- Schleifenzähler v_steps=accuracy/10; //--- den zweiten Punkt bewegen for(int i=0;i<v_steps;i++) { //--- den nächsten Wert nehmen if(p2>1) p2-=1; //--- den Punkt bewegen if(!PitchforkPointChange(0,InpName,1,date[d2],price[p2])) return; //--- Überprüfen die Fakten von Zwangsabschaltung der Skript if(IsStopped()) return; //--- den Chart neu zeichnen ChartRedraw(); } //--- 1 Sekunde Verzögerung Sleep(1000); //--- Andrew's Pitchfork aus dem Chart löschen PitchforkDelete(0,InpName); ChartRedraw(); //--- 1 Sekunde Verzögerung Sleep(1000); //--- } |