Was ist nur mit dem Reversal los?

 

Das hier ist ein momentanes Projekt, es handelt sich um eine OnTrade(), die prüfen soll, ob ein StopLoss gerissen wurde und dann eine entgegengesetzte Position aufmacht.
Nur leider funktioniert es nicht so wie es soll. Ich habe jetzt mal Comments und Prints an verschiedenen Stellen eingefügt, um zu sehen, ob Werte errechnet werden und die if-Bedingungen erreicht werden. Soweit, so gut bis auf den orangen Bereich. Ich sehe einfach nicht, wo der Fehler ist, aber vielleicht sitze ich auch schon so lange davor, dass mir etwas Offensichtliches nicht mehr auffällt. Er zählt die Deals und die Positionen, Er errechnet den Verlust pro Deal, dazu braucht er die Deal-Ticketnummer, also hat er die auch. Ich sehe einfach nicht mehr, warum er nicht die untersten Bedingungen überprüft und einen Reversal Trade eingeht.

void OnTrade()                                        
  {
   CheckReversal();
  }


void CheckReversal()
  {
//1{
//--- select history for access
   HistorySelect(0,TimeCurrent());
//---
   orders=HistoryDealsTotal();  // total history deals


   for(int i=deal_ticket; i<=orders-1; i++)
     {
      Print("Starting loop");                                                    //2{
      deal_ticket=HistoryDealGetTicket(i);
        {
         //3{
         Print("History Ticket Number",deal_ticket);
        }                                                                         //3}
      if(deal_ticket==0)
        {
         //3{
         Print("HistoryDealGetTicket failed, no trade history");
        }                                                                       //3}

      //--- check symbol
      if(HistoryDealGetString(deal_ticket,DEAL_SYMBOL)==_Symbol)               //Die Richtigkeit des Symbols wird per Print bestätigt
        {
         Print("Deal Symbol true");
         
        }
      //--- check profit
      double profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);             //hier spuckt er auch den Profit aus und zählt die Verlustdeals
      if(profit<0.0)                                                           //anderswo in einem Comment auf, er gibt auch die Deal Ticket # 
        {                                                                      //aus
         Print("History Deal #",deal_ticket,", Profit ",profit);
         losses++;
        }


      //---check type of lost history position                                     //dieser Bereich sollte eigentlich aus den selben Gründen
      if((HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==DEAL_TYPE_BUY)             //funktionieren wie die beiden darüber. Zumindest sehe 
         && (HistoryDealGetInteger(deal_ticket,DEAL_REASON)==DEAL_REASON_SL))      //ich den Grund nicht
        {
         Trade.Sell(Lots,_Symbol,Bid,Bid+SL*_Point,Bid-TP01*_Point,NULL);
         Print("History Deal #",deal_ticket," ***TYPE BUY, STOPPED OUT*** ");
         Print("Reversal Sell");
        }

      else
         if((HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==DEAL_TYPE_SELL)
            && (HistoryDealGetInteger(deal_ticket,DEAL_REASON)==DEAL_REASON_SL))
           {
            Trade.Buy(Lots,_Symbol,Ask,Ask-SL*_Point,Ask+TP01*_Point,NULL);
            Print("Reversal Buy");
           }
     }
  }
//+------------------------------------------------------------------+

Also wenn Ihr eine Idee habt bin ich echt gespannt, danke für Eure Hilfe.

 
Ich glaube OnTrade() könnte für Dich die falsche Funktion sein, ich würde OnTradeTransaktion() nehmen.
Dokumentation zu MQL5: Ereignisbehandlung / OnTradeTransaction
Dokumentation zu MQL5: Ereignisbehandlung / OnTradeTransaction
  • www.mql5.com
OnTradeTransaction - Ereignisbehandlung - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
Carl Schreiber:
Ich glaube OnTrade() könnte für Dich die falsche Funktion sein, ich würde OnTradeTransaktion() nehmen.

in OnTradeTransaction kannst Du die letzte Transaktion auslesen.

alternativ kannst Du in OnTick prüfen, ob eine Position offen ist.


oder du willst Spread sparen, dann machst die die neue Position gleich mit  ORDER_POSITION_BY_ID auf. das spart den halben spread, geht aber nur auf netting

 
Carl Schreiber:
Ich glaube OnTrade() könnte für Dich die falsche Funktion sein, ich würde OnTradeTransaktion() nehmen.
Okay dachte weil in der OnTrade Doku steht wenn ein deal getätigt wird und dieser Teil funktioniert ja auch. Muss ich mir anschauen, danke.
amando:

in OnTradeTransaction kannst Du die letzte Transaktion auslesen.

alternativ kannst Du in OnTick prüfen, ob eine Position offen ist.


oder du willst Spread sparen, dann machst die die neue Position gleich mit  ORDER_POSITION_BY_ID auf. das spart den halben spread, geht aber nur auf netting

Ja, ich habe es zuerst in OnTick programmiert bis mir durch einen Fehler ich losses++ dalsch eingegeben hatte klar wurde, dass der bei jedem Tick läuft weil er die Ticks zählt. Das wollte ich dann doch sparsamer lösen. Danke Dir.
 

Naja gut, jetzt geht er. Gibt es irgendwo gutes Material über die OnTrade Transaction Funktion? Diese Doku ist etwas dürftig, es fehlen vor Allem Beispiele für verschiedene Aktionen. Da ist dann ein Beispiel dabei, was aber nicht immer hilft, zumal es ja bei manchen Funktionen viele Möglichkeiten gibt, sie einzusetzen.

Ich wette selbst erfahrene Programmierer fragen sich manchmal was sie da eigentlich durchgelesen haben...

Also gut, wie es scheint, kann man StopLoss sowohl als Trade als auch als Trade Transaction behandeln, dort würde man wahrscheinlich TRADE_TRANSACTION_DEAL_ADD auswählen, da mit der Auslösung des StopLoss ein neuer Deal in der Historie erscheint.

Also wenn ich es richtig verstanden habe, ist eine Order eine Anfrage oder Bestellung. Einen Deal hat man, wie man so schön sagt: "Deal or no deal?" wenn die Anfrage akzeptiert wurde, also das Ergebnis positiv ist. damit hat man kaufmännisch gesehen einen Vertrag.

Ein Trade kann anscheinend auch aus mehreren Deals bestehen, zum Beispiel wenn eine Position geteilt und oder teilweise aufgelöst wird, stimmt das noch?

Dann ist mir aufgefallen, dass POSITION_TYPE_BUY nicht das Gleiche ist wie DEAL_TYPE_BUY:

Eine Buy Position wird zwar mit einem Deal des Typs Buy eröffnet, sie wird jedoch mit einem Deal Typ Sell geschlossen!!!

Okay nun zum Code.

enum TRADE_DIRECTION   
  {
// 
   BUY,      
   SELL,     
   NONE      
  };         

#include <Trade/Trade.mqh>
input int   SL=600;
input int   TP01=2400;
input int   BS=1;
input int   Candle_Reset=20;
input int pos_max=20;
input double   snap_factor = 1.04;
input double   Lots=0.01;


// Die hier gespeicherten Werte sind die Besten
MqlRates rates[];
datetime Time[], TimeValue, PosTime;
double Ask, Bid, TP01ValueBuy, SLValueBuy;
double TP01ValueSell, SLValueSell, Equity, Balance, EquityRatio;
int TickCount, CandleCount, orders, losses=0;
uint deal_ticket, pos_num;

string signal="";

CTrade Trade;
CPositionInfo PositionInfo;
int OnInit()
  {
//---

   /* Trade.SetTypeFilling(ORDER_FILLING_RETURN);*/


//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   CopyTime(_Symbol,_Period,0,3,Time);
   ArraySetAsSeries(Time,true);
   CopyRates(_Symbol,_Period,0,3,rates);
   ArraySetAsSeries(rates,true);

   Ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   Bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   pos_num=PositionsTotal();

   Equity=AccountInfoDouble(ACCOUNT_EQUITY);
   Balance=AccountInfoDouble(ACCOUNT_BALANCE);
   EquityRatio=NormalizeDouble(Equity/Balance,4);

   TP01ValueBuy=Ask+TP01*_Point;
   TP01ValueSell=Bid-TP01*_Point;

   SLValueBuy=Ask-SL*_Point;
   SLValueSell=Bid+SL*_Point;

   TickCount++;
   if(newBar()==true)// wenn der TickCount auf Null gesetzt wird, geht der CandleCount eins hoch
     {
      TickCount=0;
      CandleCount++;
      }

   if(CandleCount==Candle_Reset)
     {
      CandleCount=0;
      }



     
   if((CandleCount==5)&&(TickCount==BS))    //Es wird nur alle zehn Kerzen gehandelt
     {
      ExecuteTrade();
      }


   TimeValue=rates[0].time;

   Comment("                                 TickCount ",TickCount,"\n",
           "                                 CandleCount ",CandleCount,"\n",
           "                                 Ask ",Ask,"\n",
           "                                 Bid ",Bid,"\n",
           "                                 pos_num ",pos_num,"\n",
           "                                 EquityRatio= ",EquityRatio,"\n",
           "                                 Equity= ",Equity,"\n", 
           "                                 Balance= ",Balance,"\n", 
           "                                 PosTime ",PosTime,"\n",
           "                                 TimeValue ",TimeValue,"\n",
           "                                 deal_ticket ",deal_ticket,"\n",
           "                                 HistoryDealsTotal ",orders,"\n",
           "                                 Losses ",losses,"\n"
          );


  }

//+------------------------------------------------------------------+
//|  On Trade Functionactivates when ever deal is done               |
//+------------------------------------------------------------------+
  
void OnTrade()
{
 CheckReversal();
 }
 
 
//+------------------------------------------------------------------+
bool newBar()
  {
   static datetime TimeBar=0;
   bool flag=false;
   if(TimeBar!=iTime(Symbol(),Period(),0))
     {
      TimeBar=iTime(Symbol(),PERIOD_CURRENT,0);
      flag=true;
      }
// return true if you are in new bar.
   return (flag);
   }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ExecuteTrade()
  {
   Trade.Buy(Lots,_Symbol,Ask,Ask-SL*_Point,Ask+TP01*_Point,NULL);

   /*Trade.Sell(Lots,_Symbol,Bid,Bid+SL*_Point,Bid-TP01*_Point,NULL);*/
   }


//+------------------------------------------------------------------+
/*void CloseAllPositions()
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(PositionInfo.SelectByIndex(i))     // selects the position by index for further access to its properties
         Trade.PositionClose(PositionInfo.Ticket()); // close a position by
   } */
//+------------------------------------------------------------------+

    
void CheckReversal()
{
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
             orders=HistoryDealsTotal();  // total history deals


      for(int i=deal_ticket;i<=orders-1;i++)
        {Print("***Starting loop");
         deal_ticket=HistoryDealGetTicket(i);
         {
          Print("***History Ticket Number",deal_ticket);
          }
         if(deal_ticket==0)
           {
            Print("***HistoryDealGetTicket failed, no trade history");
            }
           
         //--- check symbol
         if(HistoryDealGetString(deal_ticket,DEAL_SYMBOL)==_Symbol)
         {
          Print("***Deal Symbol true");
          
          }
         //--- check profit
         double profit=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
         if(profit<0.0)
           {
            Print("***History Deal #",deal_ticket,", Profit ",profit);
            losses++;}
            

         //---check type of lost history position
        if ((HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==DEAL_TYPE_SELL)    //Buy Positionen werden mit Sell Deals geschlossen u. vis versa
        &&  (HistoryDealGetInteger(deal_ticket,DEAL_REASON)==DEAL_REASON_SL)) 
        {
         Trade.Sell(Lots,_Symbol,Bid,Bid+SL*_Point,Bid-TP01*_Point,NULL);
         Print("***History Deal #",deal_ticket," ***TYPE BUY, STOPPED OUT*** ");         //Man beachte die hübsche Auskommentierung per Print
         Print(">>>***Reversal Sell");
         }
         
   else if ((HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==DEAL_TYPE_BUY)
        &&  (HistoryDealGetInteger(deal_ticket,DEAL_REASON)==DEAL_REASON_SL)) 
        {
        Trade.Buy(Lots,_Symbol,Ask,Ask-SL*_Point,Ask+TP01*_Point,NULL);
        Print("***History Deal #",deal_ticket," ***TYPE SELL, STOPPED OUT*** ");  
        Print(">>>***Reversal Buy");
        }
        }}
 
pennyhunter:

Naja gut, jetzt geht er. Gibt es irgendwo gutes Material über die OnTrade Transaction Funktion? Diese Doku ist etwas dürftig, es fehlen vor Allem Beispiele für verschiedene Aktionen. Da ist dann ein Beispiel dabei, was aber nicht immer hilft, zumal es ja bei manchen Funktionen viele Möglichkeiten gibt, sie einzusetzen.

Ich wette selbst erfahrene Programmierer fragen sich manchmal was sie da eigentlich durchgelesen haben...

Also gut, wie es scheint, kann man StopLoss sowohl als Trade als auch als Trade Transaction behandeln, dort würde man wahrscheinlich TRADE_TRANSACTION_DEAL_ADD auswählen, da mit der Auslösung des StopLoss ein neuer Deal in der Historie erscheint.

Also wenn ich es richtig verstanden habe, ist eine Order eine Anfrage oder Bestellung. Einen Deal hat man, wie man so schön sagt: "Deal or no deal?" wenn die Anfrage akzeptiert wurde, also das Ergebnis positiv ist. damit hat man kaufmännisch gesehen einen Vertrag.

Ein Trade kann anscheinend auch aus mehreren Deals bestehen, zum Beispiel wenn eine Position geteilt und oder teilweise aufgelöst wird, stimmt das noch?

Dann ist mir aufgefallen, dass POSITION_TYPE_BUY nicht das Gleiche ist wie DEAL_TYPE_BUY:

Eine Buy Position wird zwar mit einem Deal des Typs Buy eröffnet, sie wird jedoch mit einem Deal Typ Sell geschlossen!!!

Okay nun zum Code.

Du musst unterscheiden zwischen Order, Position und Deal

Deal ist eine Transaktion, Position ist eine Offene Position und eine Order ist eine noch nicht ausgelöste Position wobei zu beachten ist, eine Position die du direkt eingibst hat auch eine Order Nummer.


bei einer Pending order hast du demzufolge

Du gibst eine Order eine

die wird wenn sie getigert wird eine Position

die Transaktion wenn sie getriggert wird ist der Deal

beim schließen ist das der Deal was die Position beendet.


Bei einer Market Order hast Du die Order Position und Deal gleichzeitig, jedes mit einer eigenen Nummer


in der History kannst du ja auch unterscheiden zwischen 

Deal History

Order History und

Position History

 
Orders, Positions und Abschlüsse in MetaTrader 5
Orders, Positions und Abschlüsse in MetaTrader 5
  • www.mql5.com
Einen robusten Handelsroboter zu erzeugen geht nicht ohne das Verständnis der Mechanismen des MetaTrader 5 Handelssystems. Der Client-Terminal erhält vom Handelsserver Informationen über die Positions, Orders und Abschlüsse. Um diese Daten mittels MQL5 entsprechend verarbeiten zu können, ist ein gutes Verständnis der Interaktion zwischen dem mql5-Programm und dem Client-Terminal unabdingbar.
 
pennyhunter:

Das hier ist ein momentanes Projekt, es handelt sich um eine OnTrade(), die prüfen soll, ob ein StopLoss gerissen wurde und dann eine entgegengesetzte Position aufmacht.
Nur leider funktioniert es nicht so wie es soll. Ich habe jetzt mal Comments und Prints an verschiedenen Stellen eingefügt, um zu sehen, ob Werte errechnet werden und die if-Bedingungen erreicht werden. Soweit, so gut bis auf den orangen Bereich. Ich sehe einfach nicht, wo der Fehler ist, aber vielleicht sitze ich auch schon so lange davor, dass mir etwas Offensichtliches nicht mehr auffällt. Er zählt die Deals und die Positionen, Er errechnet den Verlust pro Deal, dazu braucht er die Deal-Ticketnummer, also hat er die auch. Ich sehe einfach nicht mehr, warum er nicht die untersten Bedingungen überprüft und einen Reversal Trade eingeht.

Also wenn Ihr eine Idee habt bin ich echt gespannt, danke für Eure Hilfe.

   Hallo,

   Sie können doch den letzten Type Order überprüfen  und danach einen entgegengesetzten Order setzen.

   Es gibt viel einfachere Methode. Hier in Code.

      if(tipe_letzte_position==POSITION_TYPE_BUY) {

       Trade.Sell(Lots,_Symbol,Bid,Bid+SL*_Point,Bid-TP01*_Point,NULL);

      }else if(tipe_letzte_position==POSITION_TYPE_SELL) {
       
      Trade.Buy(Lots,_Symbol,Ask,Ask-SL*_Point,Ask+TP01*_Point,NULL);
 
       }

   Gruß Igor.

 
Pay24Money:

   Hallo,

   Sie können doch den letzten Type Order überprüfen  und danach einen entgegengesetzten Order setzen.

   Es gibt viel einfachere Methode. Hier in Code.

   Gruß Igor.

Jetzt würde mich doch interessieren, wie man in der history den position type auslesen tut

 
amando:

Jetzt würde mich doch interessieren, wie man in der history den position type auslesen tut

 Ah ja. Sie benutzen Ctrade Trade und CPositionInfo PositionInfo Funktion.





CSymbolInfo m_symbol;

int OnInit()
  {
//---

   /* Trade.SetTypeFilling(ORDER_FILLING_RETURN);*/
//---
   if(!m_symbol.Name(_Symbol)) // sets symbol name
      return(INIT_FAILED);

   


Trade.SetExpertMagicNumber(Magic);
//---
   if(IsFillingTypeAllowed(SYMBOL_FILLING_FOK))
      Trade.SetTypeFilling(ORDER_FILLING_FOK);
   else if(IsFillingTypeAllowed(SYMBOL_FILLING_IOC))
      Trade.SetTypeFilling(ORDER_FILLING_IOC);
   else
      Trade.SetTypeFilling(ORDER_FILLING_RETURN);


//---
   return(INIT_SUCCEEDED);
  }
static
ENUM_POSITION_TYPE tipe_letzte_position=-1;       for(int i=PositionsTotal()-1; i>=0; i--) // Gibt die Anzahl der aktuellen Positionen zurück          if(PositionInfo.SelectByIndex(i)) // wählt die Position nach Index für den weiteren Zugriff auf seine Eigenschaften aus             if(PositionInfo.Symbol()== _Symbol && PositionInfo.Magic()==Magic) {                tipe_letzte_position=PositionInfo.PositionType();  // Ruft den Positionstyp ab                return;             } if(tipe_letzte_position==POSITION_TYPE_BUY) {        Trade.Sell(Lots,_Symbol,Bid,Bid+SL*_Point,Bid-TP01*_Point,NULL);       }else if(tipe_letzte_position==POSITION_TYPE_SELL) {              Trade.Buy(Lots,_Symbol,Ask,Ask-SL*_Point,Ask+TP01*_Point,NULL);        }

Habe jetzt an Ihre Bedürfnisse angepasst.

Gruß Igor.

 
Pay24Money:

 Ah ja. Sie benutzen Ctrade Trade und CPositionInfo PositionInfo Funktion.


Habe jetzt an Ihre Bedürfnisse angepasst.

Gruß Igor.

Das. Etrifft nur aktive positionen, nicht geschlossene

geschlossene  können so nicht ausgelesen werden

Grund der Beschwerde: