Meno codice, più azione... scrivere un EA - pagina 6

 
Maxim Kuznetsov:

Io alloco la memoria per loro, ovviamente. Ad una profondità non superiore a quella necessaria per i calcoli e il debug. Nel frammento dato è 30, che è più che sufficiente. Se da qualche parte sarà necessario calcolare per esempio la deviazione standard di profondità 50, allora la cache dovrebbe essere aumentata. Ed è solo per velocizzare i calcoli.

Ok. Ognuno ha la sua visione.
 
Vladimir Simakov:

Non c'è niente di sbagliato nella prospettiva

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Caratteristiche del linguaggio mql5, consigli e trucchi

fxsaber, 2018.02.15 11:48

Vi suggerisco di provare a scrivere uno script in MQL5 con questo tipo di logica di trading (stile MQL4 solo per una rapida visualizzazione del senso)

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

Non vi mostrerò le librerie. Il file ex5 è allegato.

CloseBy è stato fatto su due piedi, finora non ce n'era bisogno, ma grazie per il "debole", l'unica cosa che rimane è fare i cambiamenti nelle posizioni dopo CloseBy

In futuro, ci sarà una classe wrapper per COrder e CPostion

File:
Test.ex5  43 kb
 

Cercherò di spiegare a parole cosa si sta facendo :-)

Supponiamo di aver bisogno di un Expert Advisor. In primo luogo, abbiamo bisogno di quello più semplice che commercia per incrocio di frattali e trailing stop per frattali. Cioè, nel terminale, sarebbe così:

Ciò che è cerchiato in NERO è la linea 1 della tabella. Quei dati che l'Expert Advisor prende in considerazione nei suoi algoritmi.

Lo scopo dei casi d'uso che sono stati dati è quello di descrivere nel modo più compatto possibile ciò che si trova in quest'area, come viene contato e cosa lo completa con l'Expert Advisor. Quali calcoli si fanno sulla base di questi dati.

Secondo me, la cosa più semplice da fare è
1) elencare questi campi nominandoli, cioè elencarli nell'ENUM
2.) scrivere una semplice funzione che, in base al nome dell'ENUM e della barra, dia i loro valori all'Expert Advisor.

Per un programmatore ordinario, c'è una certa metodologia (passi chiaramente contrassegnati) di sviluppo di semplici Expert Advisors:

1. Definire l'ingresso

2. descrivere e completare i dati scrivendo formule; aggiungere colonne se necessario

3. Specifica quali dati della tabella risultante vengono utilizzati e dove.

Per memorizzare i dati c'è una classe DataFrame che memorizza i dati "per colonna" e fornisce accesso tramite indici, caching dei dati e calcoli su richiesta.

Su questo sottile (non c'è molto codice, solo ciò che è strettamente necessario per il caso d'uso), possiamo sviluppare vari Expert Advisors. Si conta la tabella, si ricevono i segnali e si aprono i trade.

Naturalmente, non è abbastanza :-) Allora, il progetto è stato appena lanciato... E non c'è una soluzione pronta, è un progetto. È un progetto che è appena nato e si sta sviluppando.

 
Vladimir Simakov:

Grazie per il "debole".

Quindi uno script, non un EA. Ma anche con un EA hai dimostrato perfettamente la differenza tra MT4 e MT5. Una delle varianti ha solo una linea. E il secondo, purtroppo, è fallito.

 
fxsaber:

Quindi uno script, non un EA. Ma anche con un EA hai dimostrato perfettamente la differenza tra MT4 e MT5. C'è solo una linea in una delle varianti.

Dai, CloseBy, nel caso non l'avessi notato, ho: pos1.CloseBy(pos2), tutto il resto sono ordini di apertura e operazioni di controllo. In mt4 devi anche aprire prima due posizioni e fornire un controllo per la loro apertura. Forse posterete anche il codice di lavoro sullo studio, giusto per fare un confronto.

 
Maxim Kuznetsov


:

Cercherò di spiegare a parole cosa si sta facendo :-)

Supponiamo di aver bisogno di un Expert Advisor. In primo luogo, abbiamo bisogno di quello più semplice che commercia per incrocio di frattali e trailing stop per frattali. Cioè, nel terminale, sarebbe così:

Ciò che è cerchiato in NERO è la linea 1 della tabella. Quei dati che l'Expert Advisor prende in considerazione nei suoi algoritmi.

Lo scopo dei casi d'uso che sono stati dati è quello di descrivere nel modo più compatto possibile ciò che si trova in quest'area, come viene contato e cosa lo completa con l'Expert Advisor. Quali calcoli si fanno sulla base di questi dati.

Secondo me, la cosa più semplice da fare è
1) elencare questi campi nominandoli, cioè elencarli nell'ENUM
2.) scrivere una semplice funzione che, in base al nome dell'ENUM e della barra, dia i loro valori all'Expert Advisor.

Per un programmatore ordinario, c'è una certa metodologia (passi chiaramente contrassegnati) di sviluppo di semplici Expert Advisors:

1. Definire l'ingresso

2. descrivere e completare i dati scrivendo formule; aggiungere colonne se necessario

3. Specifica quali dati della tabella risultante vengono utilizzati e dove.

Per memorizzare i dati c'è una classe DataFrame che memorizza i dati "per colonna" e fornisce accesso tramite indici, caching dei dati e calcoli su richiesta.

Su questo sottile (non c'è molto codice, solo ciò che è strettamente necessario per il caso d'uso), possiamo sviluppare vari Expert Advisors. Si conta la tabella, si ricevono i segnali e si aprono i trade.

Naturalmente, non è abbastanza :-) Allora, il progetto è stato appena lanciato... E non c'è una soluzione pronta, è un progetto. È un progetto che è appena nato e si sta sviluppando.

Per il pensiero generale, un esempio di una classe wrapper per Ichimoku, ma 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:

Per il pensiero generale, un esempio di una classe wrapper per Ichimoku, ma in mql4.

Per quale componente Ichimoku vuoi un wrapper? E soprattutto perché e di che tipo?
solo chiacchiere? si può, perché no...

PS/ Hai visto Excel? Nella vista DataFrame gli Ishimocks avranno lo stesso aspetto... Proprio come tutti gli altri... I commercianti lavorano con le tabelle in realtà. Un grafico è solo una rappresentazione parziale (vista) di una tabella riassuntiva. Quindi questi dati dovrebbero essere trattati come tabelle.
Dal punto di vista del trader, cos'è un oggetto del programma? Non è niente. Non ci sono queste cose nella sua vita pratica.

 
Vladimir Simakov:

Dai, CloseBy, nel caso non l'avessi notato, ho: pos1.CloseBy(pos2), tutto il resto aprendo ordini e controllando operazioni.

Non è così che funziona.

In mt4 devi anche aprire prima due posizioni e fornire un controllo per la loro apertura. Forse posterete anche il codice di lavoro sullo studio, giusto per fare un confronto.

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

Non funziona così.

L'ho scritto controllando l'apertura di questi stessi ordini.