記事「リプレイシステムの開発 - 市場シミュレーション(第10回):リプレイで実データのみを使用する」についてのディスカッション

 

新しい記事「リプレイシステムの開発 - 市場シミュレーション(第10回):リプレイで実データのみを使用する」はパブリッシュされました:

ここでは、リプレイシステムで、調整されているかどうかを気にすることなく、より信頼性の高いデータ(取引されたティック)を使用する方法を見ていきます。

のビデオでは、この記事で紹介した作業の結果を見ることができます。まだ見えていない部分もあるかもしれませんが、ビデオを見ることで、これらすべての記事におけるリプレイ/シミュレーションシステムの進歩を明確に理解することができるでしょう。ビデオを見て、最初と今の変化を比べてみてください。



作者: Daniel Jose

 

ダニエル、こんばんは!

サービスを実行してデバッグすることはできますが、インジケーターをデバッグすることはできません。サービスを実行すると、すでにインジケーターの実行ファイルがロードされるからです。

何を間違えているのか分かりませんが、私の理解では、デバッグするためにインジケーターのコードを実行することはできません。本当にそうなのでしょうか?ヒントをいただけますか?

 
fernandomsoares #:

ダニエル、こんばんは!

サービスを実行してデバッグすることはできますが、インジケーターをデバッグすることはできません。サービスを実行すると、すでにインジケータの実行ファイルがロードされるからです。

何を間違えているのか分かりませんが、私の理解では、デバッグするためにインジケーターのコードを実行することはできません。本当にそうなのでしょうか?ヒントをいただけますか?

間違ったことはしていません

実際、ユーザーがサービスをプレイする準備がすべて整うと、サービスはコントロール・インジケータを初期化します。

なぜインジケーターをデバッグしたいのかよく理解できません。インジケーター上で動いているものはほとんど何もない。ユーザーとサービス間のインタラクションとして機能しているだけです。これがなければ、サービスを再生したり一時停止したりするタイミングをコントロールするのが非常に難しくなる。いずれにせよ、システムがどのように機能するかを研究しようとすることは、何も間違ったことではありません。しかし、ヒントとして、記事を注意深く読むことをお勧めする。システムの仕組みが詳しく説明されているので、相互作用がどのように起こるのかを理解しようとする労力を省くことができるだろう。😁👍

 

ダニエル、おはよう!

あなたの記事で提案されている再生/シミュレータでロボットを動作させるために、メタトレーダー5プラットフォームであなたのコードと開発について研究しました。

ロボットは受信データの流れに基づいています。つまり、受信ティックをカウントし、取引を実行するかどうかを示す計算を行います。

実は、もう少し勉強して、ロボット(EA)がReplayサービスからティックを受信できるように、必要と思われる実装を行いました。

しかし、次のような問題を抱えています:ロボットは最初のティックを1つずつ正しく受信しますが、最初の47ティックを受信した後(カウンターを入れました)、ティックを非常に間隔を空けて受信し始めます。

可能であれば、実装をお見せし、問題を解決するためのご協力をお願いしたいと思います。

以下は私が行った変更です:

- C_Replayクラス(黄色の行):

- Event_OnTimeメソッドの中で:

- グラフに送信されるティックを受け取るために、MqlTick型の変数を作成しました;

- バーの更新(CustomRatesUpdate)が送信された後、グローバル変数 "def_GlobalVariableTick "を介して、ティックをチャートに送信し、処理されるのを待つコードを入れた;

inline int Event_OnTime(void)
                        {
                                bool    bNew;
                                int     mili, iPos;
                                u_Interprocess Info;
                                MqlTick TickToAdd[1];
                                static MqlRates Rate[1];
                                static datetime _dt = 0;
                                
                                if (m_ReplayCount >= m_Ticks.nTicks) return -1;
                                if (bNew = (_dt != m_Ticks.Info[m_ReplayCount].time))
                                {
                                        _dt = m_Ticks.Info[m_ReplayCount].time;
                                        Rate[0].real_volume = 0;
                                        Rate[0].tick_volume = 0;
                                }
                                mili = (int) m_Ticks.Info[m_ReplayCount].time_msc;
                                do
                                {
                                        while (mili == m_Ticks.Info[m_ReplayCount].time_msc)
                                        {
                                                Rate[0].close = m_Ticks.Info[m_ReplayCount].last;
                                                Rate[0].open = (bNew ? Rate[0].close : Rate[0].open);
                                                Rate[0].high = (bNew || (Rate[0].close > Rate[0].high) ? Rate[0].close : Rate[0].high);
                                                Rate[0].low = (bNew || (Rate[0].close < Rate[0].low) ? Rate[0].close : Rate[0].low);
                                                Rate[0].real_volume += (long) m_Ticks.Info[m_ReplayCount].volume_real;
                                                bNew = false;
                                                m_ReplayCount++;
                                        }
                                        mili++;
                                }while (mili == m_Ticks.Info[m_ReplayCount].time_msc);
                                Rate[0].time = m_Ticks.Info[m_ReplayCount].time;
                                CustomRatesUpdate(def_SymbolReplay, Rate, 1);
                                iPos = (int)((m_ReplayCount * def_MaxPosSlider) / m_Ticks.nTicks);
                                GlobalVariableGet(def_GlobalVariableReplay, Info.u_Value.df_Value);
                                if (Info.s_Infos.iPosShift != iPos)
                                {
                                        Info.s_Infos.iPosShift = (ushort) iPos;
                                        GlobalVariableSet(def_GlobalVariableReplay, Info.u_Value.df_Value);
                                }
				// Apenas plotará o tick no grafico se o robo tiver criado a variavel "def_GlobalVariableTick"
                                if (GlobalVariableCheck(def_GlobalVariableTick))
                                {
                                	TickToAdd[0]=m_Ticks.Info[m_ReplayCount];
             				Print("Tick enviado: Time: ", TickToAdd[0].time, " Time_msc: ", TickToAdd[0].time_msc, " Bid: ", TickToAdd[0].bid, " Ask: ", TickToAdd[0].ask, " Last: ", TickToAdd[0].last, " Volume: ", TickToAdd[0].volume_real);
                                	GlobalVariableSet(def_GlobalVariableTick, 1); // Quando o EA receber o tick (OnTick) irá alterar para ZERO
             		  		CustomTicksAdd(def_SymbolReplay, TickToAdd);
                                        short ctd=0;
                                	while (GlobalVariableGet(def_GlobalVariableTick) > 0 && (!_StopFlag) && ctd <= 50) { ctd++; Sleep(50) };
                                }
                                return (int)(m_Ticks.Info[m_ReplayCount].time_msc < mili ? m_Ticks.Info[m_ReplayCount].time_msc + (1000 - mili) : m_Ticks.Info[m_ReplayCount].time_msc - mili);
                        }


- ティックを受信して処理するロボット(EA)用のコード:

#define  def_GlobalVariableTick       "ReplayTick"
//+------------------------------------------------------------------+
int OnInit()
{
        GlobalVariableTemp(def_GlobalVariableTick);
        Print("Variavel Criada: ", def_GlobalVariableTick);
                
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) 
{
   GlobalVariableDel(def_GlobalVariableTick);
}
//+------------------------------------------------------------------+
void OnTick() 
{
   MqlTick mTick;
   static int ctd=0;
   SymbolInfoTick(Symbol(),mTick);
   ctd++;
   Print(Symbol(), "   Tick Recebido ", ctd, ": Time: ", mTick.time, " Time_msc: ", mTick.time_msc, " Bid: ", mTick.bid, " Ask: ", mTick.ask, " Last: ", mTick.last, " Volume: ", mTick.volume);
   // .
   // .
   // ティック処理コード
   // .
   // .
   // 次のティックを受信するために、グローバル変数の値をゼロに変更する。
   GlobalVariableSet(def_GlobalVariableTick, 0);
}
 

を続ける。

こうすることで、デバッグのためにロボットを停止させる必要があるとき、グローバル変数「def_GlobalVariableTick」をゼロに設定する行を渡すまで、リプレイは待機しています;

わかりましたか?

 
fernandomsoares #:

引き続き.

こうすることで、デバッグのためにロボットを停止させる必要があるとき、グローバル変数「def_GlobalVariableTick」をゼロに設定する行を渡すまで、リプレイが待機するようになった;

わかった?

詳細は、このメカニズムに変更があったということだ。新しい記事には、ティックがどのように正しく放出されるかが示されているので、見てみてください。市場観察ウィンドウのDOMでそれらを追うこともできます。現在、第28回の記事はポルトガル語ですでに公開されています。ですから、あなたがいじったり操作しようとしているこのコードは、すでに完全に時代遅れになっています。システムの開発についていくためには、記事を追う必要がある。シリーズが完全に出版されるまでは、どの記事のどのコードにも執着しないでください。なぜなら、約束されたことを実現するために、時間の経過とともに何度か変更が加えられるからだ:リプレイ/シミュレーターを開発する ことで、あなたがすでに持っているもの、あるいはデモ口座やリアル口座で使用するために開発中のものを使用することが可能になるはずです。株式市場でも為替市場でも。

あなたのExpert Advisor、Indicator、スクリプトをREPLAY / SIMULATORと組み合わせないでください。それはコードに大きな変更を受けるからです...ただ、REPLAY / SIMULATORを気にせずにあなたのコードを作成する...サポートモジュールの作り方を紹介するために、開発を一時的に止める時が来るだろう。そうなったら、あなたのコードをそのモジュールに組み込むことができる。そして、そのときも非常にゆっくりと、私が開発方法を紹介するモジュールがあるレベルの機能を持つようになったら、それらはREPLAY / SIMULATORに統合されるからだ...このときこそ、システム全体がどのように機能するかを理解する必要があります。そうでなければ、あなたのコードをREPLAY / SIMULATORサービスに統合することはできません。

だから、のんびりと記事を勉強して、常に何が開発されているかを把握しておくこと...。😁👍