Diskussion zum Artikel "Cross-Platform Expert Advisor: Signale" - Seite 2

 

Danke Enrico,

Ich versuche zu verstehen, ob ich ein Signal als zusätzlichen Filter für ein anderes Signal verwenden kann...

Zum Beispiel habe ich ein Hauptsignal und es gibt Einstiegssignal Long. Dann wird das zweite Signal geprüft. Und wenn es auch Long ergibt, wäre das gesamte Signal Long. Aber wenn das zweite Signal Long gibt, aber das erste Signal neutral ist, muss das Gesamtsignal auch neutral sein, da das zweite Signal nur ein zusätzlicher Filter für das erste Signal ist und nicht das Einstiegssignal selbst ist.

Gibt es außerdem eine Möglichkeit, das Money Management auf der Grundlage eines bestimmten Signals zu steuern. Zum Beispiel wäre bei diesem Signal das Lot 1, bei einem anderen Signal das Lot 2 und so weiter. In Verbindung mit meiner ersten Frage wäre das Standard-Lot für das 1. Signal, aber im Falle einer Bestätigung durch das 2. Signal würde das Lot zum Beispiel verdoppelt werden.

Vielen Dank!

 
mbjen:

Ich versuche zu verstehen, ob ich ein Signal als einen zusätzlichen Filter für ein anderes Signal verwenden kann...

Zum Beispiel habe ich ein Hauptsignal und es gibt Einstiegssignal Long. Dann wird das zweite Signal geprüft. Und wenn es auch Long ergibt, wäre das gesamte Signal Long. Aber wenn das zweite Signal Long gibt, aber das erste Signal neutral ist, muss das Gesamtsignal auch neutral sein, da das zweite Signal nur ein zusätzlicher Filter für das erste Signal ist und es selbst kein Einstiegssignal ist.

Das ist möglich. Der einfachste Weg ist, die beiden Signale in einer einzigen Instanz des CSignal-Abkömmlings zu kombinieren. Sie können auch eine Instanz von CSignals innerhalb des CSignal-Abkömmlings erstellen und die Unterfilter das übergeordnete Signal entsprechend ändern lassen.

mbjen:

Gibt es auch eine Möglichkeit, das Geldmanagement auf der Grundlage eines bestimmten Signals zu steuern. Zum Beispiel mit diesem Signal wäre das Lot 1, mit einem anderen Signal wäre das Lot 2 und so weiter. In Verbindung mit meiner ersten Frage wäre das Standard-Lot für das 1. Signal, aber wenn das 2. Signal bestätigt wird, würde das Lot zum Beispiel verdoppelt werden.

Ja, das ist möglich. Der Container der CSignals-Instanz ist eine Instanz von CExpertAdvisor, während jede CSignal-Instanz die gleiche Instanz von CSignals als Elternteil hat. Sie müssen nur die übergeordnete Instanz/Container holen, bis Sie zur CExpertAdvisor-Instanz gelangen, den Zeiger auf den Geldverwalter holen und dann die gewünschte Geldverwaltungsmethode per Index oder Name zuweisen.

 
Enrico Lambino:

Das ist möglich. Am einfachsten ist es, die beiden Signale in einer einzigen Instanz des CSignal-Abkömmlings zu kombinieren. Sie können auch eine Instanz von CSignals innerhalb des CSignal-Abkömmlings erstellen und die Unterfilter das übergeordnete Signal entsprechend ändern lassen.

Ja, das ist möglich. Der Container der CSignals-Instanz ist eine Instanz von CExpertAdvisor, während jede CSignal-Instanz dieselbe Instanz von CSignals als Elternteil hat. Sie müssen nur die übergeordnete Instanz/Container holen, bis Sie zur CExpertAdvisor-Instanz gelangen, den Zeiger auf den Geldverwalter holen und dann die gewünschte Geldverwaltungsmethode per Index oder Name zuweisen.


Danke Enrico, ich werde das versuchen.

 

Ich habe gerade begonnen, die Cross-Plattform von EA-Framework zu verwenden.

Ich habe TEMA und MA Indikatoren in ein kombiniertes SignalTEMA_MA. Der Calculate und die LongCondition und ShortCondition wie unten. Ich habe auch den EA-Code angehängt.


bool SignalTEMA_MA::Calculate(void)
{
   int   tema_ma_state_current=0;
   bool  ret;
   
   if(m_ma.Main(m_signal_bar) >= m_tema.Main(m_signal_bar))
      tema_ma_state_current = 1;
   else
      tema_ma_state_current = -1;

   if (m_tema_ma_state != tema_ma_state_current) {
      ret = m_tema_ma_state == 0 ? false : true;
      m_tema_ma_state = tema_ma_state_current;
   }
   else {
      ret = false;
   }
   return ret;      
}

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) > m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) < m_ma.Main(m_signal_bar);
  }


Der EA scheint zu funktionieren, aber ich bekomme eine unerwünschte Verzögerung zwischen der Kreuzung der TEMA/MA-Indikator und die Reihenfolge, wie unten zu sehen ist.
Dieses Beispiel wurde mit MT5 EURUSD 15 min Zeitraum vom 4. bis 6. Dezember 2017 durchgeführt.

Meine Frage ist, wie kann ich den Auftrag so nah wie möglich an der Kreuzung wie möglich eingegeben werden?

Sobald ich das geschafft habe, werde ich die EA-Strategie weiter implementieren, um hoffentlich mit zusätzlichen Einstiegs-/Ausstiegsbedingungen und Filtern sowie Geldmanagement profitabel zu werden.

/Karl


Dateien:
 

Hallo Karl,

Sie können >= und <= anstelle von < und > für Ihre Handelsbedingungen verwenden:

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) >= m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) <= m_ma.Main(m_signal_bar);

Auf dem dritten hervorgehobenen Kreis auf Ihrem Bildschirmfoto hat der EA den Short-Handel zu spät aufgenommen. Der obige Code sorgt dafür, dass der Verkaufshandel 1 Takt früher einsetzt.

Wenn Sie möchten, dass der Handel am Kreuz selbst stattfindet (2 Balken zurück, die Kerze, in der sich der hervorgehobene Kreis befindet), dann können Sie dieselben Einstellungen verwenden, aber mit m_signal_bar = 0 (aktueller Balken). Dies würde sicherstellen, dass der Handel so nah wie möglich an der Kreuzung stattfindet, aber die Daten an diesem Balken werden oft neu gezeichnet. Die Indikatoren können sich gekreuzt haben, während sich der Balken bildete, und sie können dies bis zum Ende des Balkens beibehalten, oder auch nicht.

 
Enrico Lambino:

Hallo Karl,

Sie können >= und <= anstelle von < und > in Ihren Handelsbedingungen verwenden:

Bei dem dritten hervorgehobenen Kreis auf Ihrem Screenshot hat der EA den Short-Handel zu spät aufgenommen. Der obige Code sorgt dafür, dass der Verkaufshandel 1 Takt früher beginnt.

Wenn Sie möchten, dass der Handel am Kreuz selbst stattfindet (2 Balken zurück, die Kerze, in der sich der hervorgehobene Kreis befindet), dann können Sie dieselben Einstellungen verwenden, aber mit m_signal_bar = 0 (aktueller Balken). Dies würde sicherstellen, dass der Handel so nah wie möglich an der Kreuzung stattfindet, aber die Daten an diesem Balken werden oft neu gezeichnet. Die Indikatoren können sich gekreuzt haben, während sich der Balken bildete, und sie können dies bis zum Ende des Balkens beibehalten, oder auch nicht.


Hallo Enrico,

Vielen Dank für die schnelle Antwort, ich werde deine Empfehlungen ausprobieren.

/Karl

 
Karl Klang:


Hallo Enrico,

vielen Dank für die schnelle Antwort, ich werde Ihre Empfehlungen ausprobieren.

/Karl

Nochmals hallo Enrico,

Ich habe dieses Wochenende einige Tests gemacht. Ich habe die Handelsbedingungen auf >= und <= geändert, wie du gesagt hast, aber der Handel bewegt sich leider nicht 1 Bar früher (siehe Snip unten)


Ich habe auch versucht, signal_bar=0 zu setzen. Jetzt handelt er auf dem Cross selbst, aber ich bekomme eine Menge unerwünschter Trades, obwohl one_trade_per_candle=true und position_reverse=true im expert.Init Aufruf (siehe snip unten).

Die aktuelle Expert-Quelldatei ist angehängt.

 

Vielleicht ist die folgende Bedingung in der CExpertAdvisorBase::OnTick(void) falsch?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || IsNewBar(m_symbol_name,m_period))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || m_last_trade_time<Time(0))
   )

Sollte sie so lauten?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || m_last_trade_time<Time(0))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || IsNewBar(m_symbol_name,m_period))
   )


Dann erhalte ich folgendes:



 
Karl Klang:

Vielleicht ist die folgende Bedingung in der CExpertAdvisorBase::OnTick(void) falsch?

Sollte sie so lauten?


Dann erhalte ich folgendes:



Hallo Karl,

Das ist oft ein Problem mit Indikatoren wie TEMA. Die von solchen Indikatoren angezeigten Werte sind so flach, dass es manchmal ziemlich schwierig ist, einen Crossover zu bestätigen. Zum Beispiel, auf Ihrem ersten Screenshot (weißer Hintergrund), der erste und zweite Handel, wenn Sie genau hinsehen, vor zwei Bars vor diesen Geschäften, das Signal ist immer noch auf die entgegengesetzte Richtung. Dies macht den Balken vor 1 Kerze zur ersten Kerze, die eine Signalumkehr auslöste (was zu dem Handel in dem darauf folgenden Balken führte). Was den dritten Handel betrifft, so kann ich das nicht bestätigen, solange wir nicht die Indikatorwerte auf den Protokollen haben. Optisch erscheinen die Indikatoren kontinuierlich, aber in Wirklichkeit sind die Daten diskret.

Was CExpertAdvisorBase::OnTick(void) betrifft, stellen Sie sicher, dass, wenn Sie das Signal bar = 0 setzen, der Expert Advisor m_every_tick = true hat. Die Überprüfung auf eine neue Kerze ist etwas anderes als die Aufrechterhaltung eines einzelnen Handels pro Kerze.

 

Hallo Enrico,

ich habe einen Weg gefunden, die Calculate-Funktion jetzt mit einer Hysterese-Funktion zu behandeln, die zu funktionieren scheint, wenn sich der MA- und der TEMA-Indikator kreuzen.

Ich bin jedoch auf ein Problem mit dem Order Manager gestoßen. Es tritt auf, wenn ich den Strategietester für einige Schleifen während der Optimierung ausgeführt habe. In den ersten Schleifen funktioniert es gut, aber nach einigen Schleifen wird für jede Kerze eine Order platziert.

Hier funktioniert es gut:


Aber hier beginnt der Order Manager, mehrere Orders zu platzieren:


Als ich den folgenden Codeteil des COrderManagers debuggt habe, wird die Anweisung orders_total = OrdersTotal(); zu 1, wenn sie funktioniert, aber zu 0, wenn sie fehlschlägt, was dazu führt, dass die if-Bedingung m_max_order>orders_total immer zu true ausgewertet wird.

bool COrderManager::TradeOpen(const string symbol,ENUM_ORDER_TYPE type,double price,bool in_points=true)
  {
   bool ret=false;
   double lotsize=0.0;
   int trades_total =TradesTotal();
   int orders_total = OrdersTotal();
   m_symbol=m_symbol_man.Get(symbol);
   if(!IsPositionAllowed(type))
      return true;
   if(m_max_orders>orders_total && (m_max_trades>trades_total || m_max_trades<=0))

Ich hoffe, Sie können mir helfen, dieses Problem zu lösen.

Mit freundlichen Grüßen/
Karl