マーケットクローズ - ページ 5

 

開発者の皆様へ

このメッセージは必ずお読みください。

時間のズレが現れる理由がわかった気がします!!!

今日は

ターミナル

23:49:58.148    Trades  'xxxxx': buy limit 2.00 UCHF-3.18 at 0.9310
23:49:58.154    Trades  'xxxxx': accepted buy limit 2.00 UCHF-3.18 at 0.9310
23:49:58.156    Trades  'xxxxx': buy limit 2.00 UCHF-3.18 at 0.9310 placed for execution in 8.040 ms

専門家

2017.09.21 23:49:58.182 trader (UCHF-3.18,H1)     StopTrading: Время сервера = 23:50:00; Статус ордера = BUY_ORDER; Билет = 77833993  Buy ордер отклонён.
2017.09.21 23:49:58.182 trader (UCHF-3.18,H1)     Alert: Эксперт остановлен. Инструмент UCHF-3.18
2017.09.21 23:49:58.182 trader (UCHF-3.18,H1)     OnTradeTransaction: Buy ордер отклонён брокером(биржей). Билет = 77833993 Причина: 0 0

タイムチェック機構。

シンボルのDepth of Marketが変更された場合(私はDepth of Marketのみで作業して います)。

//+------------------------------------------------------------------+
// Expert Book event function                                        |
//+------------------------------------------------------------------+  
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol()))
  {
    if(CheckMarketTime(symbol)
    {
      //Выставление ордеров и т.д.
    }
  }     
}

CheckMarketTime 関数が呼び出されます。

//+------------------------------------------------------------------+
//| Expert Check Market Time function                                |
//+------------------------------------------------------------------+
bool CheckMarketTime(const string a_symbol)
{
  if(SymbolInfoTick(a_symbol, cur_tick))
  {
    sv_time.year = 0;
    TimeToStruct(cur_tick.time, sv_time);
    if(sv_time.year > 0)
    {
      if((sv_time.day_of_week == int(FirstDay)) ||
         (sv_time.day_of_week == int(SecondDay))) return(false);
      tts_time.year = 0;
      TimeTradeServer(tts_time);
      if(tts_time.year > 0)
      {   
        if((tts_time.day_of_week == sv_time.day_of_week) &&
           (tts_time.hour == sv_time.hour) &&
           (tts_time.min == sv_time.min))
        {
          ulong cur_time = sv_time.hour * 3600 + sv_time.min * 60 + sv_time.sec;
          if(((cur_time >= time_st_mon) && (cur_time < 50370)) ||
             ((cur_time >= time_st_day) && (cur_time < 67470)) ||
             ((cur_time >= time_st_evn) && (cur_time < 85770)))
          {
            return(true);
          }
        }
      }
    }
  }
  return(false);
}

シンボルの最新ティックのデータを取得した後

if(SymbolInfoTick(a_symbol, cur_tick))

時間軸を確認しますが、(VERY IMPORTANT)!!!!

MqlTick(IMMEDIATELY)が最新のタイムフレームを含んでいない場合

のDepth of Marketが同価格の数量だけ変化して います。

がないため、このような仮定をしています。

TICK_FLAG_ASK_VOLUME TICK_FLAG_BID_VOLUMEフラグ

OnBookEvent関数が 動作した(こんな値段の出来高が変化した)けど

MqlTickはこの変更の時刻を登録しなかった。

MqlTickにこれらのフラグを追加し、それぞれ時間を更新してください。

追加

なぜかCDに記録することができません。

 
prostotrader:

MqlTick (RIGHT HERE) は以下の場合、最新時刻を記録 しません。

は、価格カップONLYで同価格の数量が変化 しています。

全くその通り です。そして、これは正しい振る舞いです。MqlTickは、ティックヒストリーが充填されるのと同じソースからデータを取得します。MT5のティック履歴はベストバンドでも出来高を保存しないので、ティック履歴に重複はないはずです。

ティック履歴が対応する時刻を直接知る方法がないことは、以前から指摘されていたことです。別の方法で調べる。

 
fxsaber:

全くその通り です。そして、これが正しい振る舞いなのです。MqlTickは、ティックヒストリーが充填されるのと同じソースからデータを取得します。MT5のティック履歴はベストバンドでも出来高を保存しないので、ティック履歴に重複はないはずです。

ティック履歴が対応する時刻を直接知る方法がないことは、以前から指摘されていたことです。別の方法で調べる。


どれがいいのか、親切に教えていただけますか?

追加

もし、タカンの中で何かが変わったという通知を受けたら

便宜上、フィールドを追加するのはどうでしょう(「少量の血」)。

datetime book_change; ?

あるいは、もっと単純に、MqlBookInfoに以下のフィールドを追加する。

datetime book_change;

特に今回は交換で翻訳しているので。

 
prostotrader:

どれがそうなのか、教えていただけませんか?

// Время последнего тика символа
long GetSymbolTime( const string Symb )
{
  MqlTick Tick;
  
  return(SymbolInfoTick(Symb, Tick) ? Tick.time_msc : 0);
}

// Время последнего тика Обзора рынка
long GetMarketWatchTime( void )
{
  long Res = 0;
  
  for (int i = SymbolsTotal(true) - 1; i >= 0; i--)
  {
    const long TmpTime = GetSymbolTime(SymbolName(i, true));
    
    if (TmpTime > Res)
      Res = TmpTime;
  }
  
  return(Res);
}

// Текущее время на торговом сервере без учета пинга
long GetCurrenTime( void )
{
  static ulong StartTime = GetMicrosecondCount();
  static long PrevTime = 0;
  
  const long TmpTime = GetMarketWatchTime();
  
  if (TmpTime > PrevTime)
  {
    PrevTime = TmpTime;
    
    StartTime = GetMicrosecondCount();
  }
  
  return(PrevTime + (long)((GetMicrosecondCount() - StartTime) / 1000));
}

void OnInit()
{
  MarketBookAdd(_Symbol);
}

void OnDeinit( const int )
{
  MarketBookRelease(_Symbol);
}

string TimeToString( const long Value )
{
  return((string)(datetime)(Value / 1000) + "." + (string)IntegerToString(Value % 1000, 3, '0'));
}

void OnBookEvent( const string& )
{
  Comment(TimeToString(GetCurrenTime()));
}
 
fxsaber:

バカにするなよ...。:)

 
prostotrader:

もし、takanに何か変化があったことを通知されたのなら

便宜上、項目を追加しない。

datetime book_change; ?

あるいは、単純に、MqlBookInfo構造体を

datetime book_change;

特に、この時間が交換機によって変換されること。

datetime ではなく、long - milliseconds のみ。そして

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

マーケットクローズ

fxsaber さん 2017.09.22 09:17

ベッティングウィンドウが対応する時間を直接知る方法がないことは、以前から問題 視されていた。

同様の提案で

 

OnBookEventがトリガーされた後かもしれません。

このキャラクターにCopyTicksを要求しますか?

試してみるか...。

 
prostotrader:

OnBookEventがトリガーされた後かもしれません。

このキャラクターにCopyTicksを要求しますか?

もちろん、何の役にも立ちません。あとは、タンブラーを導いたタイミングを調べるしかない。

 
fxsaber:

もちろん、何の役にも立ちません。あとは、ガラスが導かれたタイミングを見極めるしかない。


面白いですよ :)

#property copyright "Copyright 2017 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//
MqlTick a_ticks[], b_ticks;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!MarketBookAdd(Symbol()))
   {
     Print("Book not added!");
     return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
    MarketBookRelease(Symbol());   
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(symbol == Symbol())
    {
      int res = CopyTicks(symbol, a_ticks, COPY_TICKS_ALL, 0, 1);
      if(res > 0)
      {
        if(SymbolInfoTick(symbol, b_ticks))
        {
          Print("CopyTicks time = ", TimeToString(a_ticks[0].time, TIME_SECONDS), "; SymbolInfoTick = ", TimeToString(b_ticks.time, TIME_SECONDS));
        }
      }
    }
  }

結果

2017.09.22 11:18:36.029 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:27; SymbolInfoTick = 11:18:35
2017.09.22 11:18:36.933 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:27; SymbolInfoTick = 11:18:35
2017.09.22 11:18:37.577 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:27; SymbolInfoTick = 11:18:37
2017.09.22 11:18:38.257 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:27; SymbolInfoTick = 11:18:37
2017.09.22 11:18:38.317 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:38
2017.09.22 11:18:38.511 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:38
2017.09.22 11:18:38.871 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:38
2017.09.22 11:18:39.071 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:38
2017.09.22 11:18:39.545 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:38
2017.09.22 11:18:39.655 Test_time (RTS-12.17,M1)        CopyTicks time = 11:18:38; SymbolInfoTick = 11:18:39

???????

なんて言ったらいいのかわからないくらい...。

 
prostotrader:

なんて言ったらいいのかわからないくらい...。

void OnInit()
{
  MarketBookAdd(_Symbol);
}

void OnDeinit( const int )
{
  MarketBookRelease(_Symbol);
}

string GetTickFlag( uint tickflag )
{
  string flag = "";

#define  TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
  TICKFLAG_MACRO(BID)
  TICKFLAG_MACRO(ASK)
  TICKFLAG_MACRO(LAST)
  TICKFLAG_MACRO(VOLUME)
  TICKFLAG_MACRO(BUY)
  TICKFLAG_MACRO(SELL)
#undef  TICKFLAG_MACRO

  if (flag == "")
    flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
     
  return(flag);
}

#define  TOSTRING(A) " " + #A + " = " + (string)Tick.A

string TickToString( const MqlTick &Tick )
{
  return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc % 1000, 3, '0') +
         TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}

void OnBookEvent( const string &Symb )
{
  if (Symb == _Symbol)
  {
    MqlTick Tick1, Tick2[];
    
    if (SymbolInfoTick(_Symbol, Tick1) && (CopyTicks(_Symbol, Tick2, COPY_TICKS_ALL, 0, 1) > 0))
      Print("\nMqlTick: " + TickToString(Tick1) + "\nCopyTick: " + TickToString(Tick2[0]));
  }
}

このような場合にのみ、タイミングが異なることがわかります。

Test3 (RTS-12.17,M1)    MqlTick:  time = 2017.09.22 11:21:50.668 bid = 112000.0 ask = 112010.0 last = 112000.0 volume = 5 FLAG_UNKNOWN (0)
Test3 (RTS-12.17,M1)    CopyTick:  time = 2017.09.22 11:21:50.572 bid = 112000.0 ask = 112010.0 last = 112000.0 volume = 5 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_SELL


MqlTickが そのままではtickを返さないことは何度か議論されています。気配値と取引という2つのティックストリームが存在すること。また、CopyTicksでは、ストリームが非同期であるため、時には遡ってマージされることがあります。また、MqlTickとCopyTicksの時刻が一致しない場合があること。

理由: