|
Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
||||
Kerzen übergreifende Indikatorenberechnung!
Ahoi zusammen
Ich bin auf der Suche nach jemandem der vielleicht eine Lösung für mein Problem hat. Im Anhang ein VolumenIndikator den ich modifizieren möchte. Er gibt bei Überkauft bzw Überverkauft ein Signal in Form eines Punktes+Pfeils aus. Dieser funktioniert auch soweit. Zum Problem: Ich will erst einen Alarm+Pfeil wenn der Indikator 3 oder 4 Kerzen(einstellbar) in Folge! einen Punkt angezeigt hat und das erst dann ein akustischer Ton+Pfeil ausgegeben wird. Hier der Code: Code:
#property copyright "Copyright © 2015 - R.Staufenberg" #property link "" #property indicator_separate_window #property indicator_minimum -35.0 #property indicator_maximum 35.0 #property indicator_buffers 5 #property indicator_color1 clrDodgerBlue #property indicator_color2 clrDodgerBlue #property indicator_color3 clrRed #property indicator_color4 clrLime #property indicator_level2 12.0 #property indicator_level3 -12.0 #property indicator_style1 2; extern int Period =5; extern ENUM_MA_METHOD MaMethod=MODE_SMA; extern ENUM_APPLIED_PRICE MaPrice = PRICE_MEDIAN; extern double Level =24.0; extern int ArrowSize =2; extern int ArrowcodeBUY =225; extern int ArrowcodeSELL =226; extern string ArrowcodeLink ="http://forex-tutor.com/mql4/arrows4.png"; extern color ArrowColorSELL =clrRed; extern color ArrowColorBUY =clrLime; extern bool alertsOn = true; extern bool alertsOnCurrent = true; extern bool alertsMessage = true; extern bool alertsSound = false; extern bool alertsEmail = false; extern bool alertsNotification = false; double AboveBuff[],ShortBuff[],LongBuff[],BelowBuff[]; double RSIBuffer[]; static int act_bars; string prefix="SimilarFx"; datetime alertcandle,lastalertime,arrowcandle; // --- int init() { SetIndexBuffer(0, AboveBuff); SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 2); // Lime Above 0 SetIndexBuffer(1, BelowBuff); SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 2); // Lime Below 0 SetIndexBuffer(2, ShortBuff); SetIndexStyle(2, DRAW_ARROW, EMPTY, 1); SetIndexArrow(2, 108); // Red SetIndexBuffer(3, LongBuff); SetIndexStyle(3, DRAW_ARROW, EMPTY, 1); SetIndexArrow(3, 108); // Blue SetIndexLabel(0, "Above"); SetIndexLabel(1, "Below"); SetIndexLabel(2, "SHORT"); SetIndexLabel(3, "LONG"); SetIndexBuffer(4,RSIBuffer); SetIndexStyle(4,DRAW_NONE); SetLevelStyle(STYLE_DOT, 0, SteelBlue); IndicatorShortName("Similar to Fx MTN"); return (0); } // --- int deinit() { ObjectDeleteByPrefix(prefix); return(0); } // --- int start() { int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-1); for (int i = limit; i >=0; i--) { //double Temp = 0.0; for (int j = i; j < i + Per; j++) Temp += (High[j] + Low[j]) / 2.0; //rsi: double Main =iMA(NULL,0,Period,0,MaMethod,MaPrice,i) ;//Temp / Per; // Temp = 0.0; for (j = i; j < i + Per; j++) Temp += High[j] - Low[j]; double Minr = 0.2 * iATR(NULL,0,Period,i);//(Temp / Per); if (Minr!=0) { AboveBuff[i] = 3.0 * (High[i] - Main) / Minr; BelowBuff[i] = 3.0 * (Low[i] - Main) / Minr; } ShortBuff[i] = EMPTY_VALUE; LongBuff[i] = EMPTY_VALUE; if (AboveBuff[i] > Level) {ShortBuff[i] = Level+1; DrawArrow(prefix+Time[i],"SELL",i,"down");} if (BelowBuff[i] < -Level) {LongBuff[i] = -(Level+1); DrawArrow(prefix+Time[i],"BUY",i,"up");} // if (AboveBuff[i] > Level) {ShortBuff[i] = Level+1; DrawArrow(prefix+Time[i],"SELL",i,"down + RSI overbought @ Level " +RsiOverBoughtLevel);} // if (BelowBuff[i] < -Level) {LongBuff[i] = -(Level+1);if(GetRsiAlert(i)==OP_BUY)DrawArrow(prefix+Time[i],"BUY",i,"up + RSI oversold @ Level " +RsiOverSoldLevel);} } manageAlerts(); return(0); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- void manageAlerts() { if (alertsOn) { if (alertsOnCurrent) int whichBar = 0; else whichBar = 1; if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuff[whichBar] != EMPTY_VALUE) { if (ShortBuff[whichBar] != EMPTY_VALUE==OP_SELL) { if(Bars!=act_bars){ doAlert(whichBar,"down"); act_bars=Bars;} } if (LongBuff[whichBar] != EMPTY_VALUE==OP_BUY) { if(Bars!=act_bars){ doAlert(whichBar,"up"); act_bars=Bars;} } } } } // // // // // void doAlert(int forBar, string doWhat) { static string previousAlert="nothing"; static datetime previousTime; string message; if (previousAlert != doWhat || previousTime != Time[forBar]) { previousAlert = doWhat; previousTime = Time[forBar]; // // // // // /*if(StringFind(doWhat,"overbought")>=0){ DrawArrow(prefix+Time[forBar],"SELL",forBar,doWhat); } else if(StringFind(doWhat,"oversold")>=0){ DrawArrow(prefix+Time[forBar],"BUY",forBar,doWhat); }*/ message = StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," SimilarFxMNT signal ",doWhat); if (alertsMessage) Alert(message); if (alertsEmail) SendMail(StringConcatenate(Symbol()," SimilarFxMNT "),message); if (alertsSound) PlaySound("alert2.wav"); if (alertsNotification) SendNotification(message); } } void DrawArrow(string name,string direction,int shifts,string desc){ int anchor=0; int arrowcode=0; double price=0; color mycolor=clrNONE; //if(Time[shifts]>arrowcandle){ if(direction=="SELL"){anchor=ANCHOR_BOTTOM;arrowcode=ArrowcodeSELL;price=High[shifts]+iATR(NULL,0,5,shifts)/2;mycolor=ArrowColorSELL;} if(direction=="BUY"){anchor=ANCHOR_TOP;arrowcode=ArrowcodeBUY;price=Low[shifts]-iATR(NULL,0,5,shifts)/2;mycolor=ArrowColorBUY;} if(ObjectFind(name)<0){ObjectCreate(name,OBJ_ARROW,0,0,0); ObjectSetInteger(0,name,OBJPROP_WIDTH,ArrowSize); } ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor); ObjectSet(name,OBJPROP_PRICE1,price); ObjectSet(name,OBJPROP_TIME1,Time[shifts]); ObjectSetInteger(0,name,OBJPROP_ARROWCODE,arrowcode); ObjectSetInteger(0,name,OBJPROP_COLOR,mycolor); ObjectSetString(0,name,OBJPROP_TEXT,desc); arrowcandle=Time[shifts]; //} } void ObjectDeleteByPrefix(string myprefix) { string ObjName; int strLength = StringLen(myprefix); int Count = 0; while (Count < ObjectsTotal()) { ObjName = ObjectName(Count); if (StringSubstr(ObjName, 0, strLength) != myprefix) Count++; else ObjectDelete(ObjName); } } Screenshot by Lightshot Wie setzt man sowas um? Ist sowas überhaupt machbar? Im Anhang der Indikator selbst. Würde mich über eine Antwort freuen Geändert von Nap$ter (16.10.15 um 17:34 Uhr) |
|
|||
Zitat:
Grobskizziert: - die Bufferarrays suchen, die für das Zeichnen der Pfeile (akust. Signal) benutzt werden. - eine Zählschleife einbauen der Art, dass falls ein gleiches Signal dem vorhergehenden folgt -> den Zähler hochsetzen, bis der Zähler den voreingestellten Wert erreicht hat. Dann erst Pfeil zeichnen lassen und den Zähler wieder auf 0 setzen. Sollte vor dem Zeichnen ein Gegensignal kommen, ebenfalls den Pfeilzähler wieder auf 0 setzen. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
||||
@traderdoc
Danke für den Tipp. Also die Bufferarrays hab ich gefunden.Die Pfeile sind an den Punkt gekettet das heisst man muss nur die eigentliche Indikatorberechnug (Punktberechnung) anpassen. Aber ich weiss nicht wie so eine Zählerschleife aussieht die erkennt das die vorige Kerze ein Signal hatte? Hier der Code der Berechnung der aber nicht die vorige Kerze miteinbezieht. Code:
// --- int start() { int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-1); for (int i = limit; i >=0; i--) { //double Temp = 0.0; for (int j = i; j < i + Per; j++) Temp += (High[j] + Low[j]) / 2.0; //rsi: double Main =iMA(NULL,0,Period,0,MaMethod,MaPrice,i) ;//Temp / Per; // Temp = 0.0; for (j = i; j < i + Per; j++) Temp += High[j] - Low[j]; double Minr = 0.2 * iATR(NULL,0,Period,i);//(Temp / Per); if (Minr!=0) { AboveBuff[i] = 3.0 * (High[i] - Main) / Minr; BelowBuff[i] = 3.0 * (Low[i] - Main) / Minr; } ShortBuff[i] = EMPTY_VALUE; LongBuff[i] = EMPTY_VALUE; if (AboveBuff[i] > Level) {ShortBuff[i] = Level+1; DrawArrow(prefix+Time[i],"SELL",i,"down");} if (BelowBuff[i] < -Level) {LongBuff[i] = -(Level+1); DrawArrow(prefix+Time[i],"BUY",i,"up");} } manageAlerts(); return(0); } //+------------------------------------------------------------------- void manageAlerts() { if (alertsOn) { if (alertsOnCurrent) int whichBar = 0; else whichBar = 1; if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuff[whichBar] != EMPTY_VALUE) { if (ShortBuff[whichBar] != EMPTY_VALUE==OP_SELL) { if(Bars!=act_bars){ doAlert(whichBar,"down"); act_bars=Bars;} } if (LongBuff[whichBar] != EMPTY_VALUE==OP_BUY) { if(Bars!=act_bars){ doAlert(whichBar,"up"); act_bars=Bars;} } } } } |
|
|||
Zitat:
traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
||||
Erstmal dickes Danke für die Schleife
Hab alles in den Indikator eingebaut und der Zähler funktioniert auch soweit. Der Counter zählt die Punkte. Leider erkennt er nicht wenn eine Lücke zwischen den Signalen ist. Also er zählt die Punkte aber nicht die Punkte in Folge. (LastBar zählen?) Bei einem GegenSignal in der zwischen Zeit funktioniert es aber. Wäre cool wenn du da vielleicht nochmal kurz schauen könntest Der Screen zeigt was ich meine: Screenshot by Lightshot Code:
// --- int start() { int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-1); for (int i = limit; i >=0; i--) { //double Temp = 0.0; for (int j = i; j < i + Per; j++) Temp += (High[j] + Low[j]) / 2.0; //rsi: double Main =iMA(NULL,0,Period,0,MaMethod,MaPrice,i) ;//Temp / Per; // Temp = 0.0; for (j = i; j < i + Per; j++) Temp += High[j] - Low[j]; double Minr = 0.2 * iATR(NULL,0,Period,i);//(Temp / Per); if (Minr!=0) { AboveBuff[i] = 3.0 * (High[i] - Main) / Minr; BelowBuff[i] = 3.0 * (Low[i] - Main) / Minr; } ShortBuff[i] = EMPTY_VALUE; LongBuff[i] = EMPTY_VALUE; //so in etwa, ohne es getestet zu haben! //in den externen Variablen z.B. int Counter = 3; definieren //außerhalb start() in den globalen Vairablen die Variablen int cntlong = 0; und cntshort = 0; deklarieren und initialisieren if (AboveBuff[i] > Level) { cntlong = 0; cntshort++; if (cntshort == Counter) { ShortBuff[i] = Level+1; DrawArrow(prefix+Time[i],"SELL",i,"down"); cntshort = 0; } } if (BelowBuff[i] < -Level) { cntshort = 0; cntlong++; if (cntlong == Counter) { LongBuff[i] = -(Level+1); DrawArrow(prefix+Time[i],"BUY",i,"up"); cntlong = 0; } } } manageAlerts(); return(0); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- void manageAlerts() { if (alertsOn) { if (alertsOnCurrent) int whichBar = 0; else whichBar = 1; if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuff[whichBar] != EMPTY_VALUE) { if (ShortBuff[whichBar] != EMPTY_VALUE==OP_SELL) { if(Bars!=act_bars){ doAlert(whichBar,"down"); act_bars=Bars;} } if (LongBuff[whichBar] != EMPTY_VALUE==OP_BUY) { if(Bars!=act_bars){ doAlert(whichBar,"up"); act_bars=Bars;} } } } } |
|
|||
"Leider erkennt er nicht wenn eine Lücke zwischen den Signalen ist. Also er zählt die Punkte aber nicht die Punkte in Folge. (LastBar zählen?) Bei einem GegenSignal in der zwischen Zeit funktioniert es aber."
Verstehe ich jetzt nicht ganz, da bei den Shortpunkten auch Lücken dazwischen sind. Oder welche Lücken meinst Du konkret? traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
||||
Ja das stimmt bei den Shortpunkten sind auch Lücken.
Also ich möchte ein Signal wenn 4 Kerzen direkt nebeneiander sind! Wie auf dem Bild unten die 4 Punkte bei Short. Die oberen roten Punkte sind nicht direkt nebeneinander sondern nacheinander.Zwischen den Punkten gibt es Kerzen ohne Punkt, das meine ich mit Lücken. Die Schleife soll wenn eine Kerze ohne Punkt kommt den Counter wieder auf 0 setzen. Geht das? Hier das Bild mit allen Erklärungen. Screenshot by Lightshot Hoffe das ist verständlich |
|
|||
Code:
// --- int start() { int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=MathMin(Bars-counted_bars,Bars-1); for (int i = limit; i >=0; i--) { //double Temp = 0.0; for (int j = i; j < i + Per; j++) Temp += (High[j] + Low[j]) / 2.0; //rsi: double Main =iMA(NULL,0,Period,0,MaMethod,MaPrice,i) ;//Temp / Per; // Temp = 0.0; for (j = i; j < i + Per; j++) Temp += High[j] - Low[j]; double Minr = 0.2 * iATR(NULL,0,Period,i);//(Temp / Per); if (Minr!=0) { AboveBuff[i] = 3.0 * (High[i] - Main) / Minr; BelowBuff[i] = 3.0 * (Low[i] - Main) / Minr; } ShortBuff[i] = EMPTY_VALUE; LongBuff[i] = EMPTY_VALUE; //so in etwa, ohne es getestet zu haben! //in den externen Variablen z.B. int Counter = 3; definieren //außerhalb start() in den globalen Vairablen die Variablen int cntlong = 0; und cntshort = 0; deklarieren und initialisieren if (AboveBuff[i] > Level) { cntlong = 0; cntshort++; if (cntshort == Counter) { ShortBuff[i] = Level+1; DrawArrow(prefix+Time[i],"SELL",i,"down"); cntshort = 0; } } else cntshort = 0; if (BelowBuff[i] < -Level) { cntshort = 0; cntlong++; if (cntlong == Counter) { LongBuff[i] = -(Level+1); DrawArrow(prefix+Time[i],"BUY",i,"up"); cntlong = 0; } } else cntlong = 0; } manageAlerts(); return(0); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- void manageAlerts() { if (alertsOn) { if (alertsOnCurrent) int whichBar = 0; else whichBar = 1; if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuff[whichBar] != EMPTY_VALUE) { if (ShortBuff[whichBar] != EMPTY_VALUE==OP_SELL) { if(Bars!=act_bars){ doAlert(whichBar,"down"); act_bars=Bars;} } if (LongBuff[whichBar] != EMPTY_VALUE==OP_BUY) { if(Bars!=act_bars){ doAlert(whichBar,"up"); act_bars=Bars;} } } } } Na dann, viel Erfolg! traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
Lesezeichen |
Stichworte |
berechnung kerzen, kerzen einstellbar, kerzenübergreifend, mql4, programmierung, programmierung metatrader |
|
|