Menos código, más acción... escribir un EA - página 6

 
Maxim Kuznetsov:

Les asigno memoria, por supuesto. A una profundidad no mayor que la necesaria para los cálculos y la depuración. En el fragmento dado es 30, que es más que suficiente. Si en algún lugar será necesario calcular, por ejemplo, la desviación estándar de la profundidad 50, entonces la memoria caché debe ser aumentada. Y es sólo para acelerar los cálculos.

Bien. Cada uno tiene su propia visión.
 
Vladimir Simakov:

No hay nada malo en la perspectiva

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Características del lenguaje mql5, consejos y trucos

fxsaber, 2018.02.15 11:48

Le sugiero que intente escribir un script en MQL5 con este tipo de lógica de comercio (estilo MQL4 sólo para mostrar el sentido rápido)

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

No voy a mostrar las bibliotecas. Se adjunta el archivo ex5.

CloseBy se hizo sobre la marcha, hasta ahora no había necesidad en él, pero gracias por el "débil", lo único que queda es hacer los cambios en las posiciones después de CloseBy

En el futuro, habrá una clase envolvente para COrder y CPostion

Archivos adjuntos:
Test.ex5  43 kb
 

Intentaré explicar lo que se hace con palabras :-)

Supongamos que necesitamos un Asesor Experto. En primer lugar, necesitamos el más simple que opera por cruce de fractales y trailing stops por fractales. Es decir, en el terminal, se vería así :

Lo que está marcado en NEGRO es la línea 1 de la tabla. Son los datos que el Asesor Experto tiene en cuenta en sus algoritmos.

El propósito de los casos de uso que se han dado es describir de la manera más compacta posible lo que hay en esta área, cómo se cuenta y qué se complementa con el Asesor Experto. Qué cálculos se hacen a partir de estos datos.

En mi opinión, lo más fácil es
1) enumerar estos campos nombrándolos, es decir, enumerarlos en el ENUM
2.) escribir una función simple, que por el nombre de la ENUM y la barra da sus valores al Asesor Experto.

Para un programador ordinario, hay una cierta metodología (pasos claramente marcados) de desarrollo de Asesores Expertos simples:

1. Definir la entrada

2. describir y aumentar los datos escribiendo fórmulas; añadir columnas según sea necesario

3. Especifica qué datos de la tabla resultante se utilizan y dónde.

Para almacenar los datos existe una clase DataFrame que almacena los datos "por columna" proporciona acceso por índices, caché de datos y cálculos bajo demanda.

Sobre este fino (no hay mucho código, sólo lo estrictamente necesario para el caso de uso), podemos desarrollar varios Asesores Expertos. La mesa cuenta, las señales se reciben y las operaciones se abren.

Por supuesto, no es suficiente :-) Así que, el proyecto acaba de abrirse... Y no hay una solución ya hecha, es un proyecto. Es un proyecto que acaba de nacer y se está desarrollando.

 
Vladimir Simakov:

Gracias por lo de "débil".

Así que un script, no un EA. Pero incluso con un EA has demostrado perfectamente la diferencia entre MT4 y MT5. Una de las variantes sólo tiene una línea. Y la segunda, por desgracia, fracasó.

 
fxsaber:

Así que un script, no un EA. Pero incluso con un EA has demostrado perfectamente la diferencia entre MT4 y MT5. Sólo hay una línea en una de las variantes.

Vamos, CloseBy, por si no te has dado cuenta, tengo: pos1.CloseBy(pos2), todo lo demás son órdenes de apertura y operaciones de verificación. En mt4 también es necesario abrir dos posiciones primero y proporcionar un control para su apertura. Tal vez también publique el código de trabajo en el estudio, sólo para comparar.

 
Maxim Kuznetsov


:

Intentaré explicar lo que se hace con palabras :-)

Supongamos que necesitamos un Asesor Experto. En primer lugar, necesitamos el más simple que opera por cruce de fractales y trailing stops por fractales. Es decir, en el terminal, se vería así :

Lo que está marcado con un círculo NEGRO es la línea 1 de la tabla. Son los datos que el Asesor Experto tiene en cuenta en sus algoritmos.

El propósito de los casos de uso que se han dado es describir de la manera más compacta posible lo que hay en esta área, cómo se cuenta y qué se complementa con el Asesor Experto. Qué cálculos se hacen a partir de estos datos.

En mi opinión, lo más fácil es
1) enumerar estos campos nombrándolos, es decir, enumerarlos en el ENUM
2.) escribir una función simple, que por el nombre de la ENUM y la barra da sus valores al Asesor Experto.

Para un programador ordinario, hay una cierta metodología (pasos claramente marcados) de desarrollo de Asesores Expertos simples:

1. Definir la entrada

2. describir y aumentar los datos escribiendo fórmulas; añadir columnas según sea necesario

3. Especifica qué datos de la tabla resultante se utilizan y dónde.

Para almacenar los datos existe una clase DataFrame que almacena los datos "por columna" proporciona acceso por índices, caché de datos y cálculos bajo demanda.

Sobre este fino (no hay mucho código, sólo lo estrictamente necesario para el caso de uso), podemos desarrollar varios Asesores Expertos. La mesa cuenta, las señales se reciben y las operaciones se abren.

Por supuesto, no es suficiente :-) Así que, el proyecto acaba de ser lanzado... Y no hay una solución ya hecha, es un proyecto. Es un proyecto que acaba de nacer y se está desarrollando.

Para pensar en general, un ejemplo de una clase envolvente para Ichimoku, pero 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:

Para el pensamiento general, un ejemplo de una clase envolvente para Ichimoku, pero en mql4.

¿Para qué componente de Ichimoku quiere una envoltura? Y lo más importante, ¿por qué y de qué tipo?
¿sólo charlar? se puede, por qué no...

PD/ ¿Has visto a Excel? En la vista del DataFrame los Ishimocks tendrán el mismo aspecto... Al igual que todos los demás... Los comerciantes trabajan con tablas en realidad. Un gráfico es sólo una representación parcial (vista) de un cuadro resumen. Así que estos datos deben ser tratados como tablas.
Desde el punto de vista del comerciante, ¿qué es un objeto de programa? No es nada. No hay tales cosas en su vida práctica.

 
Vladimir Simakov:

Vamos, CloseBy, por si no te has dado cuenta, tengo: pos1.CloseBy(pos2), todo lo demás abriendo órdenes y comprobando operaciones.

No es así como funciona.

En mt4 también es necesario abrir dos posiciones primero y proporcionar un control para su apertura. Tal vez también publique el código de trabajo en el estudio, sólo para comparar.

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

No funciona así.

Lo escribí controlando la apertura de estas mismas órdenes.

Razón de la queja: