|
Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
|||
Problem mit SL-Setzung bei JPY-Paaren
Hallo zusammen,
ich habe einen relativ simplen EA geschrieben, der meine aktuellen Trades mit einem automatischen Stop versieht, falls noch kein SL festgelegt wurde. Soweit so gut. Mein Problem ist, dass ich falsche Stops erhalte, wenn ich z.B. den CHart EUR/USD geöffnet habe, der Trade aber im USD/JPY eröffnet wurde. Das Problem sind die unterschiedlichen Digits. Aber wie löse ich die SL-Setzung vom aktuell geöffneten Chart ab? So dass der EA automatisch erkennt, ob es 2 oder 4 Nachkommastellen sind? S. AutoSL-Funktion() Code:
//+------------------------------------------------------------------+ //| Overwatch_0.1.mq4 | //| | //| | //+------------------------------------------------------------------+ #property copyright "XX" #property link "" #property version "0.4" #property strict //+------------------------------------------------------------------+ //| Variablendefinitionen | //+------------------------------------------------------------------+ datetime LastActiontime; //Variable für Once-Per-Bar-Aktion int x ; //Platzhalter für OrderSend double StopSumme = 0; //Variable für StopSumme static bool flag_notification = false; //flag für Bericht //+------------------------------------------------------------------+ //| Unterprogramme | //+------------------------------------------------------------------+ void Testorders() { x=OrderSend(Symbol(),OP_BUY,0.01,Ask,500*Point,0,0,"",0); x=OrderSend(Symbol(),OP_SELL,0.01,Bid,500*Point,0,0,"",0); } void StopAddition() { if(Hour() == 17 && flag_notification == false) { for(int i=0;i<OrdersTotal();i++) { x=OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if(OrderType() == OP_BUY) { StopSumme = StopSumme + ((OrderOpenPrice() - OrderStopLoss()) /Point /10); } if(OrderType() == OP_SELL) { StopSumme = StopSumme + ((OrderStopLoss() - OrderOpenPrice()) /Point /10); } } SendNotification("Gesamtrisiko: "+NormalizeDouble(StopSumme,3)+" Pips / " + OrdersTotal() + " offene Orders"); Print("Gesamtrisiko: " + NormalizeDouble(StopSumme,3) + " Pips / " + OrdersTotal() + " offene Orders"); StopSumme = 0; flag_notification = true; } if(Hour() == 22) { flag_notification = false; } } void AutoSL() { for(int j=0;j<OrdersTotal();j++) { x=OrderSelect(j,SELECT_BY_POS,MODE_TRADES); if(OrderType() == OP_BUY && OrderStopLoss() == 0) { x=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice() - 500 * Point,OrderTakeProfit(),0,0); } if(OrderType() == OP_SELL && OrderStopLoss() == 0) { x=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice() + 500 * Point,OrderTakeProfit(),0,0); } } } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(LastActiontime!=Time[0]) { //Code to execute once in the bar START //Testorders(); AutoSL(); //AutoStoploss StopAddition(); //StopAddition //Code to execute once in the bar ENDE LastActiontime=Time[0]; } } //+------------------------------------------------------------------+ |
|
|||
Das einfachste dürfte NormalizeDouble sein.
https://docs.mql4.com/convert/normalizedouble Code:
//SLs auf 0 stellen, wenn oben = 0, //um irgendwelche Missverständnisse zu vermeiden. if(Stop_Loss==0){ Buy_SL=0.0; Sel_SL=0.0;} //Market Order SLs //einfacher Buy SL, der bei Open Buy gesendet werden soll. else{ Buy_SL=NormalizeDouble(Ask-Stop_Loss*_Point,_Digits); //einfacher Sell SL, der bei Open Sell gesendet werden soll. Sel_SL=NormalizeDouble(Bid+Stop_Loss*_Point,_Digits);} |
|
|||
[QUOTE=MA-EA;42996]Das einfachste dürfte NormalizeDouble sein.
https://docs.mql4.com/convert/normalizedouble Nein, das ist weder die einfachste noch überhaupt eine Lösung. Wenn aus einem EA in einem Chart heraus mit einem WP und einem Digit von 4 (EURUSD) ein WP mit einem Digit von 5 (USDJPY) angesprochen werden soll, dann darf da nicht Point oder Digits benutzt werden, weil die sich auf das WP beziehen, wo der EA gerade läuft (EURUSD), sondern dann muss auch das Point und Digit benutzt werden des entsprechend zu bearbeitenden WP (USDJPY). Und dazu müssen die Funktionen des MarketInfo() benutzt werden. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Das hätte ich auch vermutet, dass das Hauptproblem darin liegt die POINTS des Symbols des WP zu nutzen, obwohl ein anderes WP geöffnet ist.
Habe den Code wie folgt geändert, leider ohne Erfolg... Code:
void AutoSL() { for(int j=0;j<OrdersTotal();j++) { x=OrderSelect(j,SELECT_BY_POS,MODE_TRADES); if(OrderType() == OP_BUY && OrderStopLoss() == 0) { x=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice() - 500 * MarketInfo(Symbol(),MODE_POINT),OrderTakeProfit(),0,0); } if(OrderType() == OP_SELL && OrderStopLoss() == 0) { x=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice() + 500 * MarketInfo(Symbol(),MODE_POINT),OrderTakeProfit(),0,0); } } } Hoffe auf eure Hilfe (Will nämlcih nicht alle 28 WP-Charts öffnen müssen, um das Problem zu umgehen ) |
|
|||
Zitat:
MarketInfo(Symbol(),MODE_POINT) für das Symbol() (welches das Symbol des Charts darstellt) natürlich das Symbol des zu ändernden WP einsetzen. Dazu muss vorher das WP des Trades ermittelt werden und dann wird das statt Symbol() eingesetzt in " " geschrieben. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Wie wärs, bei OrderSelect auch zu prüfen, ob
Code:
OrderSymbol() == Symbol() |
|
|||
Zitat:
Tz. tz! Erstens habe ich das gerade geschrieben, dass er die WP prüfen muss aber nicht wie bei Dir, sondern string symbol = OrderSymbol(); und dann wird das symbol in MarketInfo eingesetzt. Und zweitens, wenn Du der Meinung bist, dass das nix mit Points oder Digits zu tun hast, dann brauchst Du Dich auch nicht über Deine nichtlaufenden EAs wundern. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Hi, hier funktionierender EA-Code, den mein Framework erzeugt. Achtung der EA setzt Pending Orders, nur Demo oder AutoTrading false!
+++++++++++++++++++++++++++++++++ #include <stdlib.mqh> #include <WinUser32.mqh> //------------------------------------------------ extern double LotSize = 0.1; extern int SLSize = 20; extern int TPSize = 30; extern int PriceOffset = 20; double PipValue=1; // this variable is here to support 5-digit brokers bool Terminated = false; string LF = "\n"; // use this in custom or utility blocks where you need line feeds int ObjCount = 0; // count of all objects created on the chart, allows creation of objects with unique names //------------------------------------------------ int init() { if (false) ObjectsDeleteAll(); // clear the chart Comment(""); // clear the chart return (0); } //------------------------------------------------ // Expert start int start() { if (Bars < 10) { Comment("Not enough bars"); return (0); } if (Terminated == true) { Comment("EA Terminated."); return (0); } OnEveryTick(); return (0); } //------------------------------------------------ void OnEveryTick() { PipValue = 1; if (Digits == 3 || Digits == 5) PipValue = 10; PrintFunctionsToChart(); IfNoOrderExist(); } //------------------------------------------------ void PrintFunctionsToChart() { string temp = "Show Points And Digits:\n"; temp = temp + "Points; " + DoubleToStr(Point, Digits) + "\n" + "Digits: " + DoubleToStr(Digits, 0) + "\n" + "------------------------------------------------\n"; Comment(temp); } //------------------------------------------------ void IfNoOrderExist() { bool exists = false; for (int i=OrdersTotal()-1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol()) { exists = true; } } else { Print("OrderSelect() error - ", ErrorDescription(GetLastError())); } if (exists == false) { BuyPendingOrder(); SellPendingOrder(); } } //------------------------------------------------ void BuyPendingOrder() { int expire = TimeCurrent() + 60 * 0; double price = NormalizeDouble(Ask, Digits) + PriceOffset*PipValue*Point; double SL = price - SLSize*PipValue*Point; if (SLSize == 0) SL = 0; double TP = price + TPSize*PipValue*Point; if (TPSize == 0) TP = 0; if (0 == 0) expire = 0; int ticket = OrderSend(Symbol(), OP_BUYSTOP, LotSize, price, 4, SL, TP, "Test Digits", 100, expire, Blue); if (ticket == -1) { Print("OrderSend() error - ", ErrorDescription(GetLastError())); } } //------------------------------------------------ void SellPendingOrder() { int expire = TimeCurrent() + 60 * 60; double price = NormalizeDouble(Bid, Digits) - PriceOffset*PipValue*Point; double SL = price + SLSize*PipValue*Point; if (SLSize == 0) SL = 0; double TP = price - TPSize*PipValue*Point; if (TPSize == 0) TP = 0; if (60 == 0) expire = 0; int ticket = OrderSend(Symbol(), OP_SELLSTOP, LotSize, price, 4, SL, TP, "Test Digits", 100, expire, Red); if (ticket == -1) { Print("OrderSend() error - ", ErrorDescription(GetLastError())); } } //------------------------------------------------ int deinit() { if (false) ObjectsDeleteAll(); return (0); } +++++++++++++++++++++++++++++++++ |
|
|||
Zitat:
Deshalb nochmal: Er muss nach OrderSelect() das WP auslesen und das Ergebnis der Funktion MarketInfo() übergeben, damit z.B. die Variable Point richtig berechnet wird und damit auch der SL und TP. Sonst wird das nix! traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Zitat:
|
Lesezeichen |
|
|