Probleme mit SL und TP

 

Seit Stunden kämpfe ich mit nachfolgendem Code, der das Öffnen einer Position vereinfachen sollte und eine Erweiterung von CTrade werden soll.

Die Fehler treten auf unterschiedlichen Währungspaaren unterschiedlich auf (zb USDJPY, EURUSD). Ausserdem hat dieser Code schon funktioniert!

Die Fehler sind auch unterschiedlich bei Trade.Buy() und Trade.PositionOpen(). Prüfroutine Report ist eingebaut, ich kann keine Fehler entdecken.

#include <Trade\Trade.mqh>          // include system library
CTrade Trade;                       // define instance of CTrade

//+------------------------------------------------------------------+
input double   inp_LS = 0.01;       // Lotsize
input uint     inp_SL =  150;       // Stop Loss (points)
input uint     inp_TP =  200;       // Take Profit (points)

//+------------------------------------------------------------------+
double slDist,tpDist,Volume;        // global variables
int    tick=0;                      // tick counter

//+------------------------------------------------------------------+
int OnInit()
{
   slDist=inp_SL*_Point;            // sl as price distance
   tpDist=inp_TP*_Point;            // tp as price distance
   Volume=NormalizeLots(inp_LS);    // check Volume
   return(INIT_SUCCEEDED);          // return ok
}

//+------------------------------------------------------------------+
void OnTick()
{
   tick++;
   if(tick==10)
      {
         DebugBreak();
         Check(BuyMarket (Volume,slDist,tpDist));
         Check(SellMarket(Volume,slDist,tpDist));
         Check(BuyMarket (Volume,slDist,NULL));
         Check(SellMarket(Volume,slDist,NULL));
         Check(BuyMarket (Volume,NULL,tpDist));
         Check(SellMarket(Volume,NULL,tpDist));
         ExpertRemove();
      }
}

//+------------------------------------------------------------------+
bool BuyMarket(double _lots, double _sl=NULL, double _tp=NULL, string _comment=NULL)
{
   double price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   if(_sl!=NULL) _sl=NormalizeDouble(price - _sl,_Digits);
   if(_tp!=NULL) _tp=NormalizeDouble(price + _tp,_Digits);

   #ifdef _DEBUG Report("BUY MARKET",price,_sl,_tp); #endif
   //return(Trade.Buy(_lots,_Symbol,price,_sl,_tp,_comment));
   return(Trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,_lots,price,_sl,_tp,_comment));
}
 
//+------------------------------------------------------------------+
bool SellMarket(double _lots, double _sl=NULL, double _tp=NULL, string _comment=NULL)
{
   double price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   if(_sl!=NULL) _sl=NormalizeDouble(price + _sl,_Digits);
   if(_tp!=NULL) _tp=NormalizeDouble(price - _tp,_Digits);

   #ifdef _DEBUG Report("SELL MARKET",price,_sl,_tp); #endif
   //return(Trade.Buy(_lots,_Symbol,price,_sl,_tp,_comment));
   return(Trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,_lots,price,_sl,_tp,_comment));
}

//+------------------------------------------------------------------+
double NormalizeLots(double vol)
{
   double VolMin =SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   double VolMax =SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   double VolStep=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);

   if(vol<VolMin) return(VolMin); else
   if(vol>VolMax) return(VolMax); else
                  return(NormalizeDouble(MathRound(vol/VolStep)*VolStep,2));
}

void Check(bool aOperation)
{
   Print(aOperation?"*OK*":"*ERROR*");
}

void Report(string _text, double _price, double _sl, double _tp)
{
   Print(_text,"   Price:",DoubleToString(_price,_Digits),"   SL:",DoubleToString(_sl,_Digits),"   TP:",DoubleToString(_tp,_Digits));
   //Print((_sl>_price)?"SL above price":(_sl<_price)?"SL below price":"SL is invalid");
   //Print((_tp>_price)?"TP above price":(_tp<_price)?"TP below price":"TP is invalid");
}
Dateien:
 

Ohne jetzt den Code studiert zu haben: Welcher Fehler genau?

Was erwartetest Du wo und wie und wann, aber Du kriegst dann was?

 
Carl Schreiber:

Ohne jetzt den Code studiert zu haben: Welcher Fehler genau?

Was erwartetest Du wo und wie und wann, aber Du kriegst dann was?

Die Fehler sind laut log [invalid stops]

Im Tester USDJPY M5 Start 2019.01.07 läuft das Programm ohne Fehler.

Im Tester EURUSD M5 Start 2019.01.07 läuft das Programmmit Fehlern in Zeilen 30,31,32

Mit den _Digits bzw. _Point dürfte es nicht zusammenhängen, es werden ja die _Points eingerechnet.

Ich mach es jetzt so, daß ich die Position ohne SL und TP eröffne und SL und TP erst beim nächsten Tick überprüfe bzw. verändere.

 
Danke für die Lot calc otto
 


Also ich seh da keinen Grund für einen Fehler.

Order und Positionen sind SELL, Preis: 1.14053

Der Take Profit ist mit Preis 1.13953 100 points unter dem Preis(Bid) und auch der Spread ist nicht störend.

 
amando:
Danke für die Lot calc otto

Aber immer gerne! Das ist auch nicht wirklich auf meinem Mist gewachsen.

Wart, ich such mal.......

https://www.mql5.com/de/articles/2281 da stecken einige Berechnungen drinnen.

Eine wahre Fundgrube!

Die Erstellung eines Helfers im manuellen Handeln
Die Erstellung eines Helfers im manuellen Handeln
  • www.mql5.com
In diesem Artikel werde ich ein weiteres Beispiel der Erstellung eines vollwertigen Handelspanels darstellen, welches den Anhänger des manuellen Tradings während der Arbeit in Forex hilft. 1. Bestimmen wir die gewünschte Funktionalität für das Handelspanel Zunächst müssen wir für uns selbst definieren, welches endgültiges Endergebnis wir...
 

Problem Gelöst!

Es liegt am Build 2280. Mit 2190 läuft alles einwandfrei!

Auch andere EAs aus der Codebase laufen mit 2280 nicht!

Ich gebe es Metaqoutes schriftlich: IHR SEID PFUSCHER, aber das mit Konsequenz!

Und die Systemlibrary gehört dringend überarbeitet.

Die ist dermaßen Grottenlangsam, daß ich mir die wichtigsten Teile neu schreibe.

Falls sich jemand dafür interessiert:

bool CTradeExt::PositionOpen(string aSymbol,ORDTYPE aOrderType, double aVolume, double aPrice, double aStop, double aTake, string aComment)
{
   ZeroMemory(m_request);
   ZeroMemory(m_result);
   m_request.action   =TRADE_ACTION_DEAL;
   m_request.symbol   =aSymbol;
   m_request.magic    =NULL;
   m_request.volume   =aVolume;
   m_request.type     =aOrderType;
   m_request.price    =aPrice;
   m_request.sl       =aStop;
   m_request.tp       =aTake;
   m_request.comment  =aComment;
   m_request.deviation=UINT_MAX;
   return(OrderSend(m_request,m_result));
}

bool CTradeExt::PositionModify(string aSymbol, double aStop, double aTake)
{
   ZeroMemory(m_request);
   ZeroMemory(m_result);
   m_request.action  =TRADE_ACTION_SLTP;
   m_request.symbol  =aSymbol;
   m_request.magic   =NULL;
   m_request.sl      =aStop;
   m_request.tp      =aTake;
   m_request.position=PositionGetInteger(POSITION_TICKET);
   return(OrderSend(m_request,m_result));
}

Und nur weil CTradeExt von CTrade abgeleitet ist verwende ich so vertrottelte Variablennamen die mit m_ beginnen. WOFÜR? Die sind so wie so im Object geschützt!

Die Parameternamen der Funktionen sind allerdings kritisch, da wird nix gemacht.

Detto der gleiche Unfug mit den EXTxxxx Variablennamen. inp_xxx wäre sinnvoller für Eingabeparameter.

Mann bin ich heiß auf die Brüder. Der Scheiss hat mich fast 2 Tage gekostet!

 


Ich lach mir einen Ast!

Mit dem guten alten XCOPY wird es rückgängig gemacht!

Grund der Beschwerde: