MetaEditor build 1490 - pagina 3

 
fxsaber:
Non c'è modo di definirlo. SL e TP sono solo l'essenza del server MT.
Il modo più affidabile (a meno che il broker non cambi il formato dei commenti, che è un evento improbabile).
 

È così che funziona:

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);
           }
        }
     }
  }
 
Opzione di lavoro per la vita reale (non per il 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:
Variante funzionante per la realtà (non per i 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.");    
  }
}
Ho controllato nel tester - non funziona, penso che non funzionerà anche per la realtà, perché la posizione per la quale è controllato non esiste più.
 
Andrey Dik:
Ho controllato nel tester - non funziona, e penso che non funzionerà sul reale, perché la posizione per la quale sta andando il test già non esiste.
Questo è un errore artificiale del tester (per non rallentarlo affatto). Solo per logica, tutto è corretto.
 
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);
}

Sembra che la selezione della cronologia delle transazioni per ID di posizione sia stata interrotta.

La stampa a volte (e a volte no) scrive

2016.12.05 11:26:11.767 1

2016.12.05 11:26:11.767 Ottenere la commissione attuale della pos (GBPUSD,M5) GBPUSD

2016.12.05 11:26:11.767 Posizione trovata

2016.12.05 11:26:11.767 Totale operazioni in posizione: 0


Bugiardo sfacciato, la posizione è ancora lì!
 
Andrey Dik:

Sembra che la selezione della cronologia delle transazioni per ID di posizione si sia interrotta.

Se succede dopo OrderSend, va bene.
 
fxsaber:
Se succede dopo OrderSend, è normale.
No, non è normale in nessun modo. In ogni caso, c'è una posizione, e quindi ci sono accordi che hanno partecipato alla sua "vita". Ma ciò che è più strano è che il codice non vede accordi anche se l'EA è già in posizione, lo vediamo nei log, il numero di posizioni è definito, la posizione per il simbolo è selezionata, ma non ci sono accordi...
 
Andrey Dik:
No, non è normale in nessun modo. In ogni caso, c'è una posizione e quindi ci sono accordi che hanno partecipato alla sua "vita". Quello che è strano è che il codice non vede i trade anche se l'Expert Advisor ha già avuto una posizione...
Renat dice che è normale, non discutere! Ecco la soluzione per OrderSend

Forum sul trading, sistemi di trading automatico e test di strategia

Come lavorare correttamente in MT5 con OrderSend

fxsaber, 2016.11.19 23:59

Rippato OrderSendSync dalla libreria qui
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
L'idea del codice dovrebbe essere chiara. Forse mi è sfuggito qualcosa. Non ho notato alcun errore di funzionamento.

Se usate questo OrderSend, non avrete questi problemi.

O aspettare i messaggi appropriati in OnTradeTransaction.

 
fxsaber:
Renat dice che è normale, non discutere! Ecco la soluzione per OrderSend

Se usate questo OrderSend, non ci saranno questi problemi.

Oppure aspettare i messaggi appropriati in OnTradeTransaction.

No, questo non è normale.

C'è una posizione. Stiamo inviando l'Expert Advisor al grafico. Non abbiamo una storia di trading per la posizione selezionata. Cosa è normale qui?)))