MetaEditor Build 1490 - Seite 3

 
fxsaber:
Es gibt keine Möglichkeit, sie zu definieren. SL und TP sind nur das Wesentliche des MT-Servers.
Das ist der zuverlässigste Weg (es sei denn, der Makler ändert das Kommentarformat, was unwahrscheinlich ist).
 

So funktioniert es:

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      datetime end=TimeCurrent();
      datetime start=end-end%PeriodSeconds(PERIOD_D1);
      ResetLastError();
      if(!HistorySelect(start,end))
        {
         Print("Getting deals history failed. Error ",GetLastError());
         return;
        }
      ulong ticket=HistoryDealGetTicket(HistoryDealsTotal()-1);
      if(ticket==trans.deal)
        {
         if(HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT &&
            (StringFind(HistoryDealGetString(ticket,DEAL_COMMENT),"tp")!=-1
            || StringFind(HistoryDealGetString(ticket,DEAL_COMMENT),"sl")!=-1))
           {
            Print(HistoryDealGetString(ticket,DEAL_SYMBOL),"  Profit= ",HistoryDealGetDouble(ticket,DEAL_PROFIT),"  ticket=",ticket);
           }
        }
     }
  }
 
Arbeitsoption für das wirkliche Leben (nicht für den Tester)
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
  if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
       PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
       (PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
  {
    const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
    
    if (Price == PositionGetDouble(POSITION_TP))
      Print("Position #" + (string)Trans.position + " - triggered TP.");    
    else if (Price == PositionGetDouble(POSITION_SL))
      Print("Position #" + (string)Trans.position + " - triggered SL.");    
  }
}
 
fxsaber:
Arbeitsvariante für echte (nicht für Tester)
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
  if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
       PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
       (PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
  {
    const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
    
    if (Price == PositionGetDouble(POSITION_TP))
      Print("Position #" + (string)Trans.position + " - triggered TP.");    
    else if (Price == PositionGetDouble(POSITION_SL))
      Print("Position #" + (string)Trans.position + " - triggered SL.");    
  }
}
Ich habe es im Testprogramm überprüft - es funktioniert nicht, und ich denke, es wird auch in der Realität nicht funktionieren, weil die Position, für die es überprüft wird, nicht mehr existiert.
 
Andrey Dik:
Ich habe es im Testprogramm überprüft - es funktioniert nicht, und ich denke, es wird auch in der Realität nicht funktionieren, weil die Position, für die der Test durchgeführt wird, noch nicht existiert.
Dies ist ein künstlicher Fehler des Testers (um ihn nicht zu verlangsamen). Allein von der Logik her ist alles richtig.
 
void OnTick ()
{
  string s = DoubleToString(PosTotalCommissSwap (Symbol (), true, true), 4);
  
  Comment (s);
}
//+------------------------------------------------------------------+


// Подсчет комиссий и свопов указанной позиции по символу
double PosTotalCommissSwap (string symb, bool commiss, bool swap)
{
  int posTotal = PositionsTotal (); //всего открытых позиций
  Print (posTotal);
  
  //пройдем по всем открытым позициям
  for(int i = posTotal - 1; i >=0; i--)
  {
    string posSymb = PositionGetSymbol (i);
    Print (posSymb);
    
    //если найдена позиция по указанному символу
    if(symb == posSymb)
    {
      Print ("Позиция найдена");
      long posID  = PositionGetInteger (POSITION_IDENTIFIER);
      
      //выберем историю сделок, относящуюся к выбранной позиции
      if(HistorySelectByPosition (posID))
      {
        int dealsTotal = HistoryDealsTotal ();  //всего сделок в истории позиции
        Print ("Всего сделок в позиции: " + dealsTotal);
        double fees = 0.0; //все комиссии и свопы
        
        //пройдем по всем сделкам позиции
        for(int k = 0; k < dealsTotal; k++)
        {
          ulong dealTicket = HistoryDealGetTicket (k); //тикет сделки
          
          if(commiss)
            fees += HistoryDealGetDouble (dealTicket, DEAL_COMMISSION);
            
          if(swap)
            fees += HistoryDealGetDouble (dealTicket, DEAL_SWAP);
        }
        
        return (fees);
      }
      else
        Print ("Историю сделок выбрать не удалось");
    }
  }
  
  return (0.0);
}

Die Auswahl der Transaktionshistorie nach Positions-ID scheint nicht mehr möglich zu sein.

Drucken schreibt manchmal (und manchmal nicht)

2016.12.05 11:26:11.767 Erhalte aktuelle Kommission von pos (GBPUSD,M5) 1

2016.12.05 11:26:11.767 Abfrage der aktuellen Provision von pos (GBPUSD,M5) GBPUSD

2016.12.05 11:26:11.767 Erhalte aktuelle Provision von pos (GBPUSD,M5) Position gefunden

2016.12.05 11:26:11.767 Abfrage der aktuellen Provision der Position (GBPUSD,M5) Total Trades in Position: 0


Frecher Lügner, die Stelle ist immer noch da!
 
Andrey Dik:

Es sieht so aus, als ob die Auswahl der Transaktionshistorie nach Positions-ID zusammengebrochen ist.

Wenn dies nach OrderSend geschieht, ist es in Ordnung.
 
fxsaber:
Wenn dies nach OrderSend geschieht, ist das normal.
Nein, das ist in keiner Weise normal. In jedem Fall gibt es eine Position, und deshalb gibt es Geschäfte, die an ihrem "Leben" teilgenommen haben. Aber was ist seltsam ist, dass der Code nicht sehen, Geschäfte, auch wenn der EA bereits in einer Position ist, sehen wir dies in den Protokollen, die Anzahl der Positionen definiert ist, die Position für das Symbol ausgewählt ist, aber es gibt keine Geschäfte in es...
 
Andrey Dik:
Nein, das ist in keiner Weise normal. In jedem Fall gibt es eine Position und daher gibt es Geschäfte, die an ihrem "Leben" teilgenommen haben. Was seltsam ist, ist, dass der Code keine Trades sieht, auch wenn der Expert Advisor bereits eine Position hatte...
Renat sagt, das ist normal, keine Widerrede! Hier ist die Lösung für OrderSend

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Wie man im MT5 mit OrderSend korrekt arbeitet

fxsaber, 2016.11.19 23:59

OrderSendSync aus der Bibliothek hier entnommen
uint OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

const bool IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
                       ::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));
                      
                      

bool Waiting( const bool FlagInit = false )
{
  static ulong StartTime = 0;

  if (FlagInit)
    StartTime = ::GetMicrosecondCount();

  const bool Res = (::GetMicrosecondCount() - StartTime < OrderSend_MaxPause);

  if (Res)
    ::Sleep(0);

  return(Res);
}

bool EqualPrices( const double Price1, const double Price2, const int digits)
{
  return(::NormalizeDouble(Price1 - Price2, digits) == 0);
}

#define WHILE(A) while (!(Res = (A)) && Waiting())

bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
  bool Res = ::OrderSend(Request, Result);

  if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (OrderSend_MaxPause > 0))
  {
    Res = (Result.retcode == TRADE_RETCODE_DONE);
    Waiting(true);

    if (Request.action == TRADE_ACTION_DEAL)
    {
      WHILE(::HistoryOrderSelect(Result.order))
        ;

      Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
                    ((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));

      if (Res)
        WHILE(::HistoryDealSelect(Result.deal))
          ;
    }
    else if (Request.action == TRADE_ACTION_PENDING)
    {
      if (Res)
        WHILE(::OrderSelect(Result.order))
          ;
      else
      {
        WHILE(::HistoryOrderSelect(Result.order))
          ;

        Res = false;
      }
    }
    else if (Request.action == TRADE_ACTION_SLTP)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
        {
          EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
          EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
          {
            EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
            EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_MODIFY)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if (::OrderSelect(Result.order))
        {
          EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
          EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if (::OrderSelect(Result.order))
          {
            EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
            EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_REMOVE)
      if (Res)
        WHILE(::HistoryOrderSelect(Result.order))
          ;
  }

  return(Res);
}

#undef WHILE
Die Idee des Codes sollte klar sein. Vielleicht habe ich etwas übersehen. Ich habe keine Fehler im Betrieb festgestellt.

Wenn Sie diesen OrderSend verwenden, werden Sie solche Probleme nicht haben.

Entweder warten Sie auf entsprechende Meldungen in OnTradeTransaction.

 
fxsaber:
Renat sagt, das sei normal, keine Widerrede! Hier ist die Lösung für OrderSend

Wenn Sie diesen OrderSend verwenden, wird es keine solchen Probleme geben.

Oder warten Sie auf entsprechende Meldungen in OnTradeTransaction.

Nein, das ist nicht normal.

Es gibt eine Position. Wir senden den Expert Advisor an den Chart. Wir haben keine Handelshistorie für die ausgewählte Position. Was ist hier normal?)))