Diskussion zum Artikel "Entwicklung eines Wiedergabesystems — Marktsimulation (Teil 10): Nur echte Daten für das Replay verwenden"

 

Neuer Artikel Entwicklung eines Wiedergabesystems — Marktsimulation (Teil 10): Nur echte Daten für das Replay verwenden :

Hier werden wir uns ansehen, wie wir zuverlässigere Daten (gehandelte Ticks) im Wiedergabesystem verwenden können, ohne uns Gedanken darüber zu machen, ob sie angepasst sind oder nicht.

Im folgenden Video können Sie das Ergebnis der in diesem Artikel vorgestellten Arbeit sehen. Einige Dinge sind vielleicht noch nicht sichtbar, aber wenn Sie sich die Videos ansehen, können Sie sich ein klares Bild von den Fortschritten bei der Wiedergabe/Simulation machen, die in all diesen Artikeln beschrieben werden. Sehen Sie sich einfach das Video an und vergleichen Sie die Veränderungen von Anfang an bis heute.



Im nächsten Artikel werden wir das System weiterentwickeln, da es noch einige wirklich notwendige Funktionen zu implementieren gibt.

Autor: Daniel Jose

 

Hallo Daniel, guten Abend!

Daniel, ich habe die folgende Situation: Ich kann den Dienst ausführen und debuggen. Aber ich kann den Indikator nicht debuggen, denn wenn ich den Dienst ausführe, lädt er bereits die ausführbare Datei des Indikators.

Ich weiß nicht, was ich falsch mache, aber soweit ich weiß, kann man den Indikatorcode nicht ausführen, um ihn zu debuggen. Ist dies wirklich der Fall? Könnten Sie mir einen Hinweis geben?

 
fernandomsoares #:

Hallo Daniel, guten Abend!

Daniel, ich habe die folgende Situation: Ich kann den Dienst ausführen und debuggen. Aber ich kann den Indikator nicht debuggen, denn wenn ich den Dienst ausführe, lädt er bereits die ausführbare Datei des Indikators.

Ich weiß nicht, was ich falsch mache, aber soweit ich weiß, kann man den Indikatorcode nicht ausführen, um ihn zu debuggen. Ist dies wirklich der Fall? Könnten Sie mir einen Hinweis geben?

Sie machen absolut NICHTS falsch.

Tatsächlich initialisiert der Dienst den Kontrollindikator, sobald alles bereit ist, damit der Benutzer den Dienst abspielen kann.

Ich verstehe nicht ganz, warum Sie den Indikator debuggen wollen. Es läuft praktisch nichts auf ihm. Er dient lediglich der Interaktion zwischen dem Benutzer und dem Dienst. Ohne ihn wäre es sehr schwierig zu steuern, wann wir den Dienst abspielen oder pausieren wollen. Auf jeden Fall machst du nichts falsch, wenn du versuchst zu studieren, wie das System funktioniert. Aber als Tipp rate ich Ihnen, die Artikel sorgfältig zu lesen. Sie erklären detailliert, wie das System funktioniert, was Ihnen viel Mühe ersparen wird, wenn Sie versuchen zu verstehen, wie die Interaktionen ablaufen. 😁👍

 

Hallo Daniel, guten Morgen!

Daniel, ich habe einige Nachforschungen über deinen Code und die Entwicklung auf der Metatrader 5-Plattform angestellt, um einen Roboter auf dem in deinen Artikeln vorgeschlagenen Replay/Simulator zum Laufen zu bringen.

Der Roboter basiert auf dem Fluss der eingehenden Daten, d.h. er zählt die eingehenden Ticks und führt Berechnungen durch, um anzuzeigen, ob die Trades ausgeführt werden sollen.

Ich habe mich bereits in anderen Beiträgen mit demselben Problem befasst, und ich entschuldige mich im Voraus für meine Beharrlichkeit. Tatsache ist, dass ich ein wenig mehr studiert und die Implementierungen vorgenommen habe, die ich für notwendig hielt, damit der Roboter (EA) die Ticks vom Replay-Dienst empfangen kann.

Aber ich habe folgendes Problem: Der Roboter empfängt die ersten Ticks korrekt, einen nach dem anderen, aber nach den ersten 47 empfangenen Ticks (ich habe einen Zähler gesetzt), beginnt er die Ticks in großen Abständen zu empfangen, und ich kann nicht verstehen, warum.

Ich möchte Ihnen die Implementierungen zeigen und Sie um Ihre Hilfe bei der Lösung des Problems bitten, falls möglich.

Hier sind die Änderungen, die ich vorgenommen habe:

- In der Klasse C_Replay (Zeilen in gelb):

- In der Methode Event_OnTime:

- Ich habe eine Variable vom Typ MqlTick erstellt, um den Tick zu empfangen, der an das Diagramm gesendet wird;

- Nach dem Senden der Balkenaktualisierung(CustomRatesUpdate) habe ich einen Code eingefügt, um den Tick an das Diagramm zu senden und darauf zu warten, dass er über die globale Variable "def_GlobalVariableTick" verarbeitet wird;

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);
                        }


- Code für den Roboter (EA), der den Tick zur Verarbeitung erhält:

#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);
   // .
   // .
   // Code für die Tick-Verarbeitung
   // .
   // .
   // Ändern Sie den Wert der globalen Variable auf Null, um den nächsten Tick zu erhalten
   GlobalVariableSet(def_GlobalVariableTick, 0);
}
 

Fortsetzung ....

Wenn Sie den Roboter zum Debuggen anhalten müssen, wartet die Wiedergabe auf diese Weise, bis Sie die Zeile übergeben, die die globale Variable "def_GlobalVariableTick" auf NULL setzt;

Haben Sie das verstanden?

 
fernandomsoares #:

weiter ....

Auf diese Weise würde die Wiedergabe, wenn ich den Roboter zum Debuggen anhalten müsste, warten, bis ich die Zeile passiere, die die globale Variable "def_GlobalVariableTick" auf NULL setzt;

Verstanden?

Das Detail ist, dass dieser Mechanismus Änderungen erfahren hat. Schauen Sie sich die neueren Artikel an, da sie Ihnen zeigen, wie die Ticks korrekt ausgelöst werden. Sie können sie sogar im Marktbeobachtungsfenster, dem DOM, verfolgen. Im Moment haben wir den Artikel für Teil 28 bereits auf Portugiesisch veröffentlicht. Der Code, den Sie versuchen zu verändern und zu manipulieren, ist also bereits völlig veraltet. Sie müssen die Artikel verfolgen, um mit der Entwicklung des Systems Schritt zu halten. Hängen Sie sich nicht an den Code in einem der Artikel, bis die Serie vollständig veröffentlicht ist. Denn sie werden im Laufe der Zeit mehrere Änderungen erfahren, um das Versprochene erfüllen zu können: ENTWICKELN SIE EIN REPLAY / SIMULATOR, der es Ihnen ermöglichen soll, alles, was Sie bereits haben oder entwickeln, auf einem DEMO- oder REAL-Konto zu verwenden. Entweder auf dem Aktienmarkt oder auf FOREX.

Versuchen Sie NICHT, Ihren Expert Advisor, Indikator oder Ihr Skript mit dem REPLAY / SIMULATOR zu kombinieren, zumindest noch nicht. Denn es werden große Änderungen am Code vorgenommen ... Erstellen Sie einfach Ihren Code, ohne sich um das REPLAY / SIMULATOR zu kümmern ... Es wird eine Zeit kommen, in der ich die Entwicklung kurz unterbrechen werde, um Ihnen zu zeigen, wie Sie einige Unterstützungsmodule erstellen können. Wenn das passiert, können Sie anfangen, Ihren Code darin zu integrieren. Und selbst dann nur sehr langsam, denn wenn die Module, die ich Ihnen zeige, wie man sie entwickelt, ein bestimmtes Funktionsniveau erreicht haben, werden sie in den REPLAY / SIMULATOR integriert ... das ist der Zeitpunkt, an dem Sie wirklich verstehen müssen, wie das ganze System funktionieren wird. Andernfalls werden Sie nicht in der Lage sein, Ihren Code in den REPLAY / SIMULATOR SERVICE zu integrieren.

Also nimm es gelassen und studiere die Artikel, um immer auf dem Laufenden zu bleiben, was entwickelt wird ... 😁👍