MetaEditor build 1490 - ページ 3

 
fxsaber:
定義しようがない。SLとTPはあくまでMTサーバーのエッセンスです。
最も信頼性の高い方法 です(ブローカーがコメントフォーマットを変更しない限り、ありえないことですが)。
 

そういうことなんです。

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);
           }
        }
     }
  }
 
実生活に役立つ作業用オプション(テスター用ではありません)
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:
実稼働中のバリアント(テスター用ではない)
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.");    
  }
}
テスターで確認したところ、動作しませんでした。確認した位置がもう存在しないので、実際の動作もしないと思います。
 
Andrey Dik:
私はテスターでチェックしました - それは動作しませんし、私はテストが起こっている位置が既に存在しないため、それは、実で動作しないと思います。
これは、テスターの人為的なエラーです(全く遅くならないようにするため)。理屈だけで、すべてが正しいのです。
 
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);
}

ポジションIDによる取引履歴の 選択が壊れているようです。

プリントは時々(そして時々)書き込みます

2016.12.05 11:26:11.767 pos (GBPUSD,M5)の現在のコミッションを取得する 1

2016.12.05 11:26:11.767 現在のposの手数料を取得(GBPUSD,M5) GBPUSD

2016.12.05 11:26:11.767 Get current commission of pos (GBPUSD,M5) ポジションが見つかりました。

2016.12.05 11:26:11.767 posの現在の手数料を取得 (GBPUSD,M5) ポジション内の総取引数:0件


生意気な嘘つき!ポジションはまだあるんだぞ
 
Andrey Dik:

役職IDによる取引履歴の 選択が崩れたようです。

OrderSendの後に発生するのであれば問題ありません。
 
fxsaber:
OrderSendの後に発生する場合は、正常です。
いや、どう考えても普通じゃない。いずれにせよ、ポジションがあり、その「人生」に参加した案件がある。しかし、EAがすでにポジションにある場合でも、コードが取引を見ないことが不思議です。ログでこれを見ると、ポジション数は 定義され、シンボルのポジションは選択されていますが、取引はありません...
 
Andrey Dik:
いや、どう考えても普通じゃない。いずれにせよ、ポジションがあるから、その「人生」に参加した案件があるのです。このコードでは、Expert Advisorがすでにポジションを持っていても、取引が表示されないのが不思議です。
レナートが普通だって言ってるんだから、反論するなよ!以下は、OrderSendのソリューションです。

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

MT5でOrderSendを正しく動作させる方法

fxsaber, 2016.11.19 23:59

ライブラリからOrderSendSyncを抜き出したものです。
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
コードの考え方は明確であるべきです。何か見落としているかもしれません。動作に不具合は感じない。

このOrderSendを使えば、そのような問題は起きません。

OnTradeTransactionで適切なメッセージを待つかのどちらかです。

 
fxsaber:
レナートは正常だと言っている、反論するな!以下は、OrderSendのソリューションです。

このOrderSendを使用すれば、そのような問題は発生しません。

またはOnTradeTransactionで適切なメッセージが出るのを待つ。

いいえ、これは普通ではありません。

位置づけがある。Expert Advisorをチャートに送信しています。選択したポジションの取引履歴が ありません。ここは普通なのか)))

理由: