Weniger Code, mehr Action... einen EA schreiben - Seite 6

 
Maxim Kuznetsov:

Ich weise ihnen natürlich Speicherplatz zu. Nur so tief, wie es für Berechnungen und Fehlersuche erforderlich ist. In dem vorliegenden Fragment sind es 30, was mehr als genug ist. Wenn es irgendwo notwendig sein wird, z.B. die Standardabweichung der Tiefe 50 zu berechnen, dann sollte der Cache vergrößert werden. Und das nur, um die Berechnungen zu beschleunigen.

Gut. Jeder hat seine eigene Vision.
 
Vladimir Simakov:

An den Aussichten gibt es nichts auszusetzen

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Merkmale der Sprache mql5, Tipps und Tricks

fxsaber, 2018.02.15 11:48

Ich schlage vor, dass Sie versuchen, ein Skript in MQL5 mit dieser Art von Handelslogik zu schreiben (MQL4-Stil nur für die schnelle Sinnanzeige)

void OnStart()
{
  OrderCloseBy(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0), OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0));
}
 
fxsaber:
#include <Template\Objects\COrder.mqh>
#include <Template\Objects\CPosition.mqh>

COrder  *order1,*order2;
CPosition *pos1,*pos2;

//----------------------------------------------------------------------
int OnInit()
  {
   order1=new COrder(NULL,ORDER_TYPE_BUY,0.2,0.0,0.0,0.0);
   order2=new COrder(NULL,ORDER_TYPE_SELL,0.1,0.0,0.0,0.0);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete order1;
   delete order2;
   delete pos1;
   delete pos2;
  }
//+------------------------------------------------------------------+
void OnTick()
  {
   CheckOrder(order1,pos1);
   CheckOrder(order2,pos2);
   if (CheckPointer(pos1)&&CheckPointer(pos2)) pos1.CloseBy(pos2);
   if (CheckPointer(pos1)&&pos1.Control()>POSITION_MUST_CLOSE) delete pos1;
   if (CheckPointer(pos2)&&pos2.Control()>POSITION_MUST_CLOSE) delete pos2;
  }

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   if (CheckPointer(order1)) order1.TradeTransaction(trans,request,result);
   if (CheckPointer(order2)) order2.TradeTransaction(trans,request,result);
  }      
//-----------------------------------------------------------------
void CheckOrder(COrder* &order, CPosition* &position){
   if (!CheckPointer(order)) return;
   switch(order.Control()){
      case ORDER_FULL:        position=NewPosition(order);
                              Print(position.GetTicket()," Ok");
      case ORDER_REMOVE:
      case ORDER_ERROR:       delete order;}}
//-------------------------------------------------------------------
CPosition* NewPosition(COrder* &order)  {return CheckPointer(order)&&PositionSelectByTicket(order.GetTicket())?new CPosition():NULL;}

Ich werde Ihnen die Bibliotheken nicht zeigen. Die ex5-Datei ist beigefügt.

CloseBy wurde von Grund auf neu erstellt, bisher gab es keine Notwendigkeit dafür, aber danke für den "Schwachpunkt", das Einzige, was noch bleibt, ist, die Änderungen an den Positionen nach CloseBy vorzunehmen

In Zukunft wird es eine Wrapper-Klasse für COrder und CPostion geben

Dateien:
Test.ex5  43 kb
 

Ich werde versuchen, in Worten zu erklären, was gemacht wird :-)

Angenommen, wir brauchen einen Expert Advisor. Zunächst benötigen wir die einfachste Variante, bei der der Handel durch das Kreuzen von Fraktalen und Trailing-Stops durch Fraktale erfolgt. Das heißt, im Terminal würde es wie folgt aussehen:

Die in SCHWARZ eingekreiste Zeile ist die Zeile 1 der Tabelle. Die Daten, die der Expert Advisor in seinen Algorithmen berücksichtigt.

Der Zweck der gegebenen Anwendungsfälle ist es, so kompakt wie möglich zu beschreiben, was in diesem Bereich liegt, wie er gezählt wird und was ihn mit dem Expert Advisor ergänzt. Welche Berechnungen werden auf der Grundlage dieser Daten durchgeführt?

Meiner Meinung nach ist es am einfachsten, wenn Sie
1) diese Felder durch Benennung auflisten, d.h. sie in der ENUM auflisten
2.) eine einfache Funktion schreiben, die anhand des Namens aus dem ENUM und dem Balken deren Werte an den Expert Advisor weitergibt.

Für einen gewöhnlichen Programmierer gibt es eine bestimmte Methodik (klar gekennzeichnete Schritte) für die Entwicklung von einfachen Expert Advisors:

1. Definieren Sie die Eingabe

2. Daten durch das Schreiben von Formeln beschreiben und ergänzen; bei Bedarf Spalten hinzufügen

3. Geben Sie an, welche Daten aus der Ergebnistabelle verwendet werden und wo.

Um Daten zu speichern, gibt es die Klasse DataFrame, die Daten "spaltenweise" speichert und den Zugriff durch Indizes, Daten-Caching und Berechnungen bei Bedarf ermöglicht.

Auf dieser dünnen Basis (es gibt nicht viel Code, nur das, was für den Anwendungsfall unbedingt notwendig ist) können wir verschiedene Expert Advisors entwickeln. Die Tabelle wird gezählt, die Signale werden empfangen, und der Handel wird eröffnet.

Natürlich ist das nicht genug :-) Das Projekt wurde soeben gestartet... Und es gibt keine fertige Lösung, es ist ein Projekt. Es handelt sich um ein Projekt, das gerade erst geboren wurde und sich noch entwickelt.

 
Vladimir Simakov:

Danke für das "schwach".

Also ein Skript, kein EA. Aber auch mit einem EA haben Sie den Unterschied zwischen MT4 und MT5 perfekt demonstriert. Eine der Varianten hat nur eine Zeile. Der zweite Versuch ist leider gescheitert.

 
fxsaber:

Also ein Skript, kein EA. Aber auch mit einem EA haben Sie den Unterschied zwischen MT4 und MT5 perfekt demonstriert. In einer der Varianten gibt es nur eine Zeile.

Komm schon, CloseBy, falls du es noch nicht bemerkt hast, ich habe: pos1.CloseBy(pos2), alles andere sind Eröffnungsaufträge und Prüfvorgänge. In mt4 müssen Sie ebenfalls zuerst zwei Positionen eröffnen und deren Eröffnung überprüfen. Vielleicht können Sie auch den Arbeitscode im Studio veröffentlichen, nur um einen Vergleich zu ermöglichen.

 
Maxim Kuznetsov


:

Ich werde versuchen, in Worten zu erklären, was gemacht wird :-)

Angenommen, wir brauchen einen Expert Advisor. Zunächst benötigen wir die einfachste Variante, bei der der Handel durch das Kreuzen von Fraktalen und Trailing-Stops durch Fraktale erfolgt. Das heißt, im Terminal würde es wie folgt aussehen:

Die in SCHWARZ eingekreiste Zeile ist die Zeile 1 der Tabelle. Die Daten, die der Expert Advisor in seinen Algorithmen berücksichtigt.

Der Zweck der gegebenen Anwendungsfälle ist es, so kompakt wie möglich zu beschreiben, was in diesem Bereich liegt, wie er gezählt wird und was ihn mit dem Expert Advisor ergänzt. Welche Berechnungen werden auf der Grundlage dieser Daten durchgeführt?

Meiner Meinung nach ist es am einfachsten, wenn Sie
1) diese Felder auflisten, indem Sie sie benennen, d.h. sie im ENUM auflisten
2.) eine einfache Funktion schreiben, die anhand des Namens aus dem ENUM und dem Balken deren Werte an den Expert Advisor weitergibt.

Für einen gewöhnlichen Programmierer gibt es eine bestimmte Methodik (klar gekennzeichnete Schritte) für die Entwicklung von einfachen Expert Advisors:

1. Definieren Sie die Eingabe

2. Daten durch das Schreiben von Formeln beschreiben und ergänzen; bei Bedarf Spalten hinzufügen

3. Geben Sie an, welche Daten aus der Ergebnistabelle verwendet werden und wo.

Um Daten zu speichern, gibt es die Klasse DataFrame, die Daten "spaltenweise" speichert und den Zugriff über Indizes, Daten-Caching und Berechnungen bei Bedarf ermöglicht.

Auf dieser dünnen Basis (es gibt nicht viel Code, nur das, was für den Anwendungsfall unbedingt notwendig ist) können wir verschiedene Expert Advisors entwickeln. Die Tabelle wird gezählt, die Signale werden empfangen, und der Handel wird eröffnet.

Natürlich ist das nicht genug :-) Das Projekt wurde soeben gestartet... Und es gibt keine fertige Lösung, es ist ein Projekt. Es handelt sich um ein Projekt, das gerade erst geboren wurde und sich noch entwickelt.

Für allgemeine Denken, ein Beispiel für eine Wrapper-Klasse für Ichimoku, aber in mql4.

#ifndef _ICHIMOKU_
#define _ICHIMOKU_

#include <ProjectLibrary\Functions\MyLib.mqh>

class CIchimoku
  {
private:
   string            cSymbol;
   ENUM_TIMEFRAMES   cFrame;
   int               cTenkan;
   int               cKijun;
   int               cSenkou;
   ENUM_TIMEFRAMES   cTempFrame;
   int               cFrameShift;
public:
                     CIchimoku(string mSymbol,ENUM_TIMEFRAMES mFrame,int mTenkan,int mKijun,int mSenkou,int mDeltaFrame=0);
   double            Get(int mBuffer,int mShift=0);
   double            Tenkan(int mShift=0)       {return Get(MODE_TENKANSEN,mShift);}
   double            Kijun(int mShift=0)        {return Get(MODE_KIJUNSEN,mShift);}
   double            SpanA(int mShift=0)        {return Get(MODE_SENKOUSPANA,mShift);}
   double            SpanB(int mShift=0)        {return Get(MODE_SENKOUSPANB,mShift);}
   double            Chikou(int mShift=0)       {return Get(MODE_CHIKOUSPAN,mShift);}
   double            CloudMin(int mShift=0)     {return MathMin(SpanA(mShift),SpanB(mShift));}
   double            CloudMax(int mShift=0)     {return MathMax(SpanA(mShift),SpanB(mShift));}
private:
   ENUM_TIMEFRAMES   CheckFrame();
  };
//--------------------------------------------------------------------------------------------------
CIchimoku::CIchimoku(string mSymbol,ENUM_TIMEFRAMES mFrame,int mTenkan,int mKijun,int mSenkou,int mFrameShift=0):
   cTenkan(mTenkan),cKijun(mKijun),cSenkou(mSenkou),cFrameShift(mFrameShift){
   cSymbol=mSymbol==NULL?_Symbol:mSymbol;
   if (mFrameShift){
      cTempFrame=mFrame==PERIOD_CURRENT?(ENUM_TIMEFRAMES)Period():mFrame;
      cFrame=::GetShiftFrame(cTempFrame,mFrameShift);}
   else
      cFrame=mFrame;}
//--------------------------------------------------------------------------------------------------
ENUM_TIMEFRAMES CIchimoku::CheckFrame(void){
   if (!cFrameShift) return cFrame;//>>
   ENUM_TIMEFRAMES frame=(ENUM_TIMEFRAMES)Period();
   if (cTempFrame==frame) return cFrame;//>>
   else cTempFrame=frame;
   return ::GetShiftFrame(frame,cFrameShift);}
//--------------------------------------------------------------------------------------------------------------
double CIchimoku::Get(int mBuffer,int mShift=0){
   ResetLastError();
   double res=iIchimoku(cSymbol,CheckFrame(),cTenkan,cKijun,cSenkou,mBuffer,mShift);
   return !GetLastError()?res:0.0;}

#endif 
 
Vladimir Simakov:

Für allgemeine Denken, ein Beispiel für eine Wrapper-Klasse für Ichimoku, aber in mql4.

Für welche Ichimoku-Komponente benötigen Sie einen Wrapper? Und vor allem, warum und welche Art?
einfach nur plaudern? Sie können, warum nicht...

PS/ Haben Sie Excel gesehen? In der DataFrame-Ansicht werden die Ishimocks gleich aussehen... Genau wie alle anderen... Händler arbeiten eigentlich mit Tabellen. Ein Diagramm ist nur eine Teildarstellung (Ansicht) einer Übersichtstabelle. Daher sollten diese Daten wie Tabellen behandelt werden.
Was ist ein Programmobjekt aus der Sicht des Händlers? Es ist nichts. In seinem praktischen Leben gibt es so etwas nicht.

 
Vladimir Simakov:

Komm schon, CloseBy, falls du es noch nicht bemerkt hast, ich habe: pos1.CloseBy(pos2), alles andere eröffnet Aufträge und prüft Operationen.

So funktioniert das nicht.

In mt4 müssen Sie ebenfalls zuerst zwei Positionen eröffnen und deren Eröffnung überprüfen. Vielleicht können Sie auch den Arbeitscode im Studio veröffentlichen, nur um einen Vergleich zu ermöglichen.

#include <MT4Orders.mqh>

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  OrderCloseBy(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0), OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0));
}
 
fxsaber:

So funktioniert das nicht.

Ich habe das geschrieben, um die Eröffnung dieser Aufträge zu kontrollieren.