Moins de code, plus d'action... l'écriture d'un EA - page 6

 
Maxim Kuznetsov:

Je leur alloue de la mémoire, bien sûr. A une profondeur ne dépassant pas celle nécessaire aux calculs et au débogage. Dans le fragment donné, il est de 30, ce qui est plus que suffisant. Si quelque part il sera nécessaire de calculer par exemple l'écart-type de la profondeur 50, alors le cache doit être augmenté. Et ce, uniquement pour accélérer les calculs.

Ok. Chacun a sa propre vision.
 
Vladimir Simakov:

Il n'y a pas de problème avec les perspectives

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Caractéristiques du langage mql5, conseils et astuces

fxsaber, 2018.02.15 11:48

Je vous suggère d'essayer d'écrire un script en MQL5 avec ce type de logique de trading (style MQL4 juste pour un affichage rapide)

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

Je ne vous montrerai pas les bibliothèques. Le fichier ex5 est joint.

CloseBy a été fait à partir de rien, jusqu'à présent il n'y avait pas besoin de le faire, mais merci pour le "faible", la seule chose qui reste à faire est de faire les changements dans les positions après CloseBy.

À l'avenir, il y aura une classe d'enveloppe pour COrder et CPostion.

Dossiers :
Test.ex5  43 kb
 

Je vais essayer d'expliquer ce qui se passe avec des mots :-)

Supposons que nous ayons besoin d'un conseiller expert. Tout d'abord, nous avons besoin de la plus simple qui négocie par le croisement de fractales et les stops suiveurs par fractales. C'est-à-dire que dans le terminal, cela ressemblerait à ceci :

Ce qui est entouré en NOIR est la ligne 1 du tableau. Ces données que le conseiller expert prend en compte dans ses algorithmes.

Le but des cas d'utilisation qui ont été donnés est de décrire de manière aussi compacte que possible ce qui se trouve dans cette zone, comment elle est comptée et ce qui la complète avec le conseiller expert. Quels calculs sont effectués sur la base de ces données.

À mon avis, la chose la plus simple à faire est de
1) répertorier ces champs en les nommant, c'est-à-dire les répertorier dans le champ ENUM
2.) écrire une fonction simple, qui par le nom de l'ENUM et de la barre donne leurs valeurs à l'Expert Advisor.

Pour un programmeur ordinaire, il existe une certaine méthodologie (étapes clairement marquées) de développement d'Expert Advisors simples :

1. Définir l'entrée

2. décrire et compléter les données en écrivant des formules ; ajouter des colonnes si nécessaire

3. Spécifiez quelles données du tableau résultant sont utilisées et où.

Pour stocker les données, il existe une classe DataFrame qui stocke les données "par colonne" et permet l'accès par index, la mise en cache des données et les calculs à la demande.

Sur cette fine (il n'y a pas beaucoup de code, seulement ce qui est strictement nécessaire pour le cas d'utilisation), nous pouvons développer divers Expert Advisors. La table compte, les signaux sont reçus et les transactions sont ouvertes.

Bien sûr, ce n'est pas suffisant :-) Donc, le projet vient d'être lancé... Et il n'y a pas de solution toute faite, c'est un projet. C'est un projet qui vient de naître et qui se développe.

 
Vladimir Simakov:

Merci pour le "faible".

Donc un script, pas un EA. Mais même avec un EA, vous avez parfaitement démontré la différence entre MT4 et MT5. L'une des variantes ne comporte qu'une seule ligne. Et la deuxième, malheureusement, a échoué.

 
fxsaber:

Donc un script, pas un EA. Mais même avec un EA, vous avez parfaitement démontré la différence entre MT4 et MT5. Il n'y a qu'une seule ligne dans l'une des variantes.

Allez, CloseBy, au cas où vous n'auriez pas remarqué, j'ai : pos1.CloseBy(pos2), tout le reste est des ordres d'ouverture et des opérations de vérification. Dans mt4 vous devez également ouvrir deux positions d'abord et fournir un contrôle pour leur ouverture. Peut-être que vous posterez également le code de travail sur le studio, juste pour comparer.

 
Maxim Kuznetsov


:

Je vais essayer d'expliquer ce qui se passe avec des mots :-)

Supposons que nous ayons besoin d'un conseiller expert. Tout d'abord, nous avons besoin de la plus simple qui trade par croisement de fractales et par trailing stops par fractales. C'est-à-dire que dans le terminal, cela ressemblerait à ceci :

Ce qui est entouré en NOIR est la ligne 1 du tableau. Ces données que le conseiller expert prend en compte dans ses algorithmes.

Le but des cas d'utilisation qui ont été donnés est de décrire de manière aussi compacte que possible ce qui se trouve dans cette zone, comment elle est comptée et ce qui la complète avec le conseiller expert. Quels calculs sont effectués sur la base de ces données.

À mon avis, la chose la plus simple à faire est de
1) répertorier ces champs en les nommant, c'est-à-dire les répertorier dans le champ ENUM
2.) écrire une fonction simple, qui par le nom de l'ENUM et de la barre donne leurs valeurs à l'Expert Advisor.

Pour un programmeur ordinaire, il existe une certaine méthodologie (étapes clairement marquées) de développement d'Expert Advisors simples :

1. Définir l'entrée

2. décrire et compléter les données en écrivant des formules ; ajouter des colonnes si nécessaire.

3. Spécifiez quelles données du tableau résultant sont utilisées et où.

Pour stocker les données, il existe une classe DataFrame qui stocke les données "par colonne" et permet l'accès par index, la mise en cache des données et les calculs à la demande.

Sur cette fine (il n'y a pas beaucoup de code, seulement ce qui est strictement nécessaire pour le cas d'utilisation), nous pouvons développer divers Expert Advisors. La table compte, les signaux sont reçus et les transactions sont ouvertes.

Bien sûr, ce n'est pas suffisant :-) Donc, le projet vient d'être lancé... Et il n'y a pas de solution toute faite, c'est un projet. C'est un projet qui vient de naître et qui se développe.

Pour une réflexion générale, un exemple de classe wrapper pour Ichimoku, mais en 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:

Pour une réflexion générale, un exemple de classe wrapper pour Ichimoku, mais en mql4.

Pour quel composant Ichimoku voulez-vous un wrapper ? Et surtout, pourquoi et de quel type ?
juste discuter ? vous pouvez, pourquoi pas...

PS/ Avez-vous vu Excel ? Dans la vue DataFrame, les Ishimocks auront la même apparence... Comme tous les autres... Les traders travaillent avec des tableaux en fait. Un graphique n'est qu'une représentation partielle (vue) d'un tableau récapitulatif. Ces données doivent donc être traitées comme des tableaux.
Du point de vue du trader, qu'est-ce qu'un objet de programme ? Ce n'est rien. Il n'y a pas de telles choses dans sa vie pratique.

 
Vladimir Simakov:

Allez, CloseBy, au cas où vous n'auriez pas remarqué, j'ai : pos1.CloseBy(pos2), tout le reste ouvrant des ordres et vérifiant les opérations.

Ce n'est pas comme ça que ça marche.

Dans mt4 vous devez également ouvrir deux positions d'abord et fournir un contrôle pour leur ouverture. Peut-être que vous posterez également le code de travail sur le studio, juste pour comparer.

#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:

Ça ne marche pas comme ça.

J'ai écrit cela en contrôlant l'ouverture de ces mêmes commandes.