|
Startseite | Registrieren | Hilfe | Benutzerliste | Kalender | Suchen | Heutige Beiträge | Alle Foren als gelesen markieren |
Programmierung MQL5 Hier gehts rund ums Programmieren in MQL5. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
|||
Array-Wert trotz fortlaufender Bars "behalten"
Es ist der Klassiker - Außenstab und seine Range vom Hoch zum Tief.
Ich wollte und habe den Code selber geschrieben und mein Vorhaben nahezu komplett gelöst. Nun ist aber doch noch ein kleines, aber entscheidendes Problem aufgetaucht: Wenn die Range vom Außenstab verlassen wird, soll der EA dies mit einem Print ausweisen und ab da an auch wieder Trades erlauben. Ich habe hierzu einen Array erstellt und fülle diesen Array mit Kursinformationen vom aktuellen Chart an. Mit open der aktuellen Bar[0] wird der Außenstab Bar[2] ausgewiesen (Bar[1] entsprechend als Innenstab). Das klappt soweit alles. Nun soll der EA wie oben erwähnt bei verlassen der Range vom Außenstab dies mitteilen und den Handel wieder erlauben. Das funktioniert ebenfalls, aber nur, wenn die Range mit der Bar[0], die den Außenstab deklariert hat, geschieht. Erfolgt der Range-Ausbruch ein oder mehrere Kerzen später, passiert nichts. Ich vermute, dass der Fehler darin liegt, dass ich zwar die Bar[2] auslese und die Werte eine Variablen zuordne, doch beim öffnen der nächsten Bar passen die werte nicht mehr. Anders ausgedrückt: die Werte werden nur verwendet, solange es keine neue Bar gibt. Kann man die Werte aus dem Array irgendwie fixieren, dass sie dauerhaft bleiben - zumindest bis sie getriggert werden? Hier der Code dazu (der Code dient lediglich zu Lernzwecken und stellt keine Strategie dar): --> es geht vermutlich hauptsächlich um die Bereiche calcSetup() calcOutsideBarRange() Code:
//+------------------------------------------------------------------+ //| lern- und test-EA.mq5 | //| Copyright 2024, Anfänger | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Anfänger" #property version "1.10" #include <Trade/Trade.mqh> enum ENUM_LOT {LOT_FIX,LOT_AMOUNT,LOT_PERCENT}; enum ENUM_SL {SL_FIX,SL_CANDLE}; input group "SIGNAL" input string TimeRangeStart = "11:02"; input string TimeRangeEnd = "11:12"; input group "RISIKO" input ENUM_LOT Lotcalculation = LOT_AMOUNT; input double RiskInLots = 0.2; input double RiskInAmount = 10.00; input double RiskInPercent = 0.25; input group "HANDEL" input ENUM_SL SlVariable = SL_CANDLE; input uint SlInitial = 1500; input uint TpInitial = 3000; input group "DIVERS" input uint SymbolBuffer = 100; input ulong Magic = 202403271656; CTrade trade; ulong buyTicket; ulong sellTicket; double high1; double low1; static double outsideBarHigh; static double outsideBarLow; bool outsideBar; bool outsideBarRange; bool noSignal; bool longSignal; bool shortSignal; datetime timeRangeStart; datetime timeRangeEnd; datetime timeSignal; int OnInit(){ static bool isInit = false; if(!isInit){ isInit = true; Print(__FUNCTION__," > EA (re)start"); } return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ } void OnTick(){ //---TimeRange if(timeRangeStart != StringToTime(TimeRangeStart)){ calcTimes(); } //---Signal if(TimeCurrent() >= timeRangeStart && TimeCurrent() < timeRangeEnd){ timeSignal = iTime(_Symbol,PERIOD_CURRENT,0); static datetime timestapSignal; if(timestapSignal != timeSignal){ timestapSignal = timeSignal; calcSetup(); } } //---Range Outsidebar if(outsideBar == true){ calcOutsideBarRange(); } //---Order if(longSignal == true){ executeBuy(); } longSignal = false; if(shortSignal == true){ executeSell(); } shortSignal = false; //---Close Order double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); if(OrderSelect(buyTicket) && bid <= OrderGetDouble(ORDER_SL)){ closeOrder(); } if(OrderSelect(sellTicket) && bid >= OrderGetDouble(ORDER_SL)){ closeOrder(); } } void calcTimes(){ timeRangeStart = StringToTime(TimeRangeStart); timeRangeEnd = StringToTime(TimeRangeEnd); } void calcSetup(){ double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Array erstellen MqlRates priceInformation[]; // Abwärts sortieren ArraySetAsSeries(priceInformation,true); // Preisdaten in das Array kopieren int Data = CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),priceInformation); // Outsidebar[2] prüfen if(priceInformation[2].high >= priceInformation[1].high && priceInformation[2].low <= priceInformation[1].low){ outsideBar = true; outsideBarHigh = priceInformation[2].high; outsideBarLow = priceInformation[2].low; Print(priceInformation[2].time," no signal - outsideBar (H ",outsideBarHigh,"; L ",outsideBarLow,")"); Print(priceInformation[1].time," no signal - insideBar"); }else outsideBar = false; //---Candle 1 double open1 = iOpen(_Symbol,PERIOD_CURRENT,1); high1 = iHigh(_Symbol,PERIOD_CURRENT,1); low1 = iLow(_Symbol,PERIOD_CURRENT,1); double close1 = iClose(_Symbol,PERIOD_CURRENT,1); //---Candle 2 double open2 = iOpen(_Symbol,PERIOD_CURRENT,2); double high2 = iHigh(_Symbol,PERIOD_CURRENT,2); double low2 = iLow(_Symbol,PERIOD_CURRENT,2); double close2 = iClose(_Symbol,PERIOD_CURRENT,2); //---No Signal bool higherLowerBar = (high1 > high2 && low1 < low2); bool doji = (open1 == close1); if(higherLowerBar == true){ noSignal = true; if(outsideBar == true){ Print(priceInformation[1].time," no signal (H/L-Bar) - inside an outsideBar "); }else Print(priceInformation[1].time," no signal - higherLowerBar "); return; } if(doji == true){ noSignal = true; if(outsideBar == true){ Print(priceInformation[1].time," no signal (doji) - inside an outsideBar "); }else Print(priceInformation[1].time," no signal - doji "); return; } //---Long Signal bool lowerLow = (low1 < low2 && high1 <= high2); if(lowerLow == true){ if(outsideBarRange == true){ Print(priceInformation[1].time," no long signal - inside an outsideBarRange "); }else if(outsideBarRange == false){ longSignal = true; Print(priceInformation[1].time," !!! LONG SIGNAL"); } } //---Short Signal bool higherHigh = (high1 > high2 && low1 >= low2); if(higherHigh == true){ if(outsideBarRange == true){ Print(priceInformation[1].time," no short signal - inside an outsideBarRange "); }else if(outsideBarRange == false){ shortSignal = true; Print(priceInformation[1].time," !!! SHORT SIGNAL"); } } } void calcOutsideBarRange(){ double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); if(bid <= outsideBarHigh && bid >= outsideBarLow){ outsideBarRange = true; }else if(bid > outsideBarHigh || bid < outsideBarLow){ outsideBarRange = false; outsideBar =false; Print(" left OutsideBarRange"); } } void executeBuy(){ double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); double spread = roundUp(ask - bid); double sl = 0; double entry = roundUp(high1 + spread + SymbolBuffer * _Point); if(SlVariable == SL_FIX){ sl = entry - SlInitial * _Point; }else sl = roundUp(low1 - SymbolBuffer * _Point); double tp = roundUp(entry + TpInitial * _Point); Print(" Long: entry ",entry," (spread ",spread,"), sl ",sl,", tp ",tp); double lots = calclots(entry - sl); double price = SymbolInfoDouble(_Symbol,SYMBOL_BID); if(price < entry){ if(trade.BuyStop(lots,entry,_Symbol,sl,tp,0,0)){ if(trade.ResultRetcode() == TRADE_RETCODE_DONE){ buyTicket = trade.ResultOrder(); Print(" --> Buy-Stop-Order #",buyTicket," was sent"); } } } if(price >= entry){ if(trade.Buy(lots,_Symbol,entry,sl,tp)){ if(trade.ResultRetcode() == TRADE_RETCODE_DONE){ buyTicket = trade.ResultOrder(); Print(" --> Buy-Market-Order #",buyTicket," was sent"); } } } } void executeSell(){ double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); double spread = roundUp(ask - bid); double sl = 0; double entry = roundDn(low1 - SymbolBuffer * _Point); if(SlVariable == SL_FIX){ sl = entry + SlInitial * _Point; }else sl = roundDn(high1 + spread + SymbolBuffer * _Point); double tp = roundDn(entry - TpInitial * _Point); Print(" Short: entry ",entry,", sl ",sl," (spread ",spread,"), tp ",tp); double lots = calclots(sl - entry); double price = SymbolInfoDouble(_Symbol,SYMBOL_BID); if(price > entry){ if(trade.SellStop(lots,entry,_Symbol,sl,tp,0,0)){ if(trade.ResultRetcode() == TRADE_RETCODE_DONE){ sellTicket = trade.ResultOrder(); Print(" --> Sell-Stop-Order #",sellTicket," was sent"); } } } if(price <= entry){ if(trade.Sell(lots,_Symbol,entry,sl,tp)){ if(trade.ResultRetcode() == TRADE_RETCODE_DONE){ sellTicket = trade.ResultOrder(); Print(" --> Sell-Market-Order #",sellTicket," was sent"); } } } } void closeOrder(){ for(int i = OrdersTotal()-1; i >= 0; i--){ buyTicket = OrderGetTicket(i); if(OrderGetString(ORDER_SYMBOL) != _Symbol && OrderGetInteger(ORDER_MAGIC) != Magic) continue; if(OrderSelect(buyTicket) && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP){ if(trade.OrderDelete(buyTicket)){ Print(" -x-> Buy-Stop-Order #",buyTicket," gelöscht da SL erreicht"); } } } for(int i = OrdersTotal()-1; i >= 0; i--){ sellTicket = OrderGetTicket(i); if(OrderGetString(ORDER_SYMBOL) != _Symbol && OrderGetInteger(ORDER_MAGIC) != Magic) continue; if(OrderSelect(sellTicket) && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP){ if(trade.OrderDelete(sellTicket)){ Print(" -x-> Sell-Stop-Order #",sellTicket," gelöscht da SL erreicht"); } } } } double roundUp(double price){ double ticksize = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE),_Digits); price = NormalizeDouble(price,_Digits); double rest = price - NormalizeDouble(price/ticksize,0) * ticksize; rest = NormalizeDouble(rest,_Digits); if(rest != 0){ for (double i = _Point; i <= ticksize; i += _Point){ price = NormalizeDouble(price + _Point,_Digits); rest = price - NormalizeDouble(price/ticksize,0) * ticksize; rest = NormalizeDouble(rest,_Digits); if(rest == 0) break; } } return price; } double roundDn(double price){ double ticksize = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE),_Digits); price = NormalizeDouble(price,_Digits); double rest = price - NormalizeDouble(price/ticksize,0) * ticksize; rest = NormalizeDouble(rest,_Digits); if(rest != 0){ for (double i = _Point; i <= ticksize; i += _Point){ price = NormalizeDouble(price - _Point,_Digits); rest = price - NormalizeDouble(price/ticksize,0) * ticksize; rest = NormalizeDouble(rest,_Digits); if(rest == 0) break; } } return price; } double calclots(double slPoints){ // slPoints = Strecke (entry - sl; sl - entry) double lots = 0; double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); double moneyPerLotstep = slPoints / ticksize * tickvalue * lotstep; if(Lotcalculation == LOT_FIX){ lots = NormalizeDouble(RiskInLots,_Digits); Print(" Fixe Lotsize: ",lots," lots"); } if(Lotcalculation == LOT_AMOUNT){ lots = NormalizeDouble(MathFloor(RiskInAmount / moneyPerLotstep) * lotstep,_Digits); Print(" Lotsize berechnet über Betrag: ",lots," lots"); } if(Lotcalculation == LOT_PERCENT){ // ACCOUNT_EQUITY = inkl. offene Positionen; ACCOUNT_BALANCE = ohne offene Positionen double riskPerTrade = AccountInfoDouble(ACCOUNT_EQUITY) * RiskInPercent / 100; lots = NormalizeDouble(MathFloor(riskPerTrade / moneyPerLotstep) * lotstep,_Digits); Print(" Lotsize prozentual berechnet: ",lots," lots"); } lots = MathMin(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX)); lots = MathMax(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN)); return lots; } |
|
|||
Evtl. wird mein Problem anhand von folgendem Beispiel deutlicher:
In obigem Bild (Grafik) wird mit open Kerze C die Kerze A als outsidebar deklariert. Da noch innerhalb der Kerze C der Kurs das High der outsidebar verlässt, wird dies im Journal um 11:02:28 Uhr auch korrekt wiedergegeben: Mit open der Kerze 3 wird Kerze 1 als outsidebar deklariert. Hier verlässt der Kurs die Range der outsidebar erst mit Kerze 5 (11:08 Uhr) - und im Journal wird nichts ausgewiesen: Das Ziel war, dass auch in diesem Beispiel irgendwann innerhalb der Minutenkerze um 11:08 Uhr die Meldung "left OutsideBarRange" kommt. Was aber nicht passiert. ... sorry, merke eben, dass ich nicht fähig bin, Bilder direkt zwischen den Text zu integrieren - obwohl ich [IMG] vor der URL und [/IMG] danach geschrieben habe ... |
Lesezeichen |
Themen-Optionen | Thema durchsuchen |
Ansicht | |
|
|