Меньше кода, больше прока.. пишем советник - страница 6

 
Maxim Kuznetsov:

Память под них я конечно выделяю. На глубину не более чем нужна для расчётов и отладки. В приведённом фрагменте 30, что более чем достаточно. Если где-нибуть потребуется считать например стандартное отклонение глубиной 50, то кеш стоит увеличить. Да и то только ради ускорения рассчётов.

Ок. У каждого свое видение.
 
Vladimir Simakov:

С кругозором все в порядке

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Особенности языка mql5, тонкости и приёмы работы

fxsaber, 2018.02.15 11:48

предлагаю попробовать написать на MQL5 скрипт с такой торговой логикой (MQL4-стиль только для быстрого показа смысла)

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

Библиотеки не покажу. ex5 файл во вложении.

CloseBy на коленке сделан, необходимости пока в нем не было, но спасибо за "слабо", осталось только изменения в позиции оформить после CloseBy

В будущем будет один класс-обертка для COrder и СPosition

Файлы:
Test.ex5  43 kb
 

Попробую, уже по слогам, пояснить что делается :-)

Есть предположим , потребность в советнике. Для начала - в самом простом, который торгует по пересечению машек и тралит стоп по фракталам. То есть в терминале, это выглядело так :

То что обведено ЧЁРНЫМ квадратиком - это 1 строка таблицы. Те данные которые советник учитывает в своих алгоритмах.

Задача use-case которые были приведены - максимально компактно описать что лежит в этой области, как оно считается и чем советник это дополняет. Какие вычисления на основе этих данных производит.

На мой взгляд, самое простое что можно сделать -
1) перечислить эти поля присвоив им имена, то есть перечислить в ENUM
2) написать простую функцию которая по имени из ENUM и бару, отдаёт советнику их значения.

Для рядового программиста появляется некоторая методология (чётко обозначенные шаги) разработки простых советников:

1. Задать Input

2. Описать и дополнить Data, написав формулы; добавить столбцы по мере необходимости

3. Указать какие данные из полученной таблицы и где используются.

Чтобы хранить Data сделан класс DataFrame который хранит данные "по столбцам" обеспечивает доступ по индексам, кеширование данных и вычисления по требованию.

Уже на этой тонкой (кода там мало, только то что строго было необходимо для use-case) основе можно делать много разных советников. Таблица считает, сигналы получаются, сделки открываются.

Конечно этого мало :-) Так и проект только-только открыт.. и тут нет готового решения, это проект. Который только что родился и развивается.

 
Vladimir Simakov:

спасибо за "слабо"

Так скрипт, не советник. Но даже с советником Вы отлично продемонстрировали разницу между MT4 и MT5. В одном из вариантов только одна строка. А второй, к сожалению, не справился.

 
fxsaber:

Так скрипт, не советник. Но даже с советником Вы отлично продемонстрировали разницу между MT4 и MT5. В одном из вариантов только одна строка.

Да ладно, CloseBy, если вы не заметили, у меня: pos1.CloseBy(pos2), все остальное открытие ордеров и проверочные операции. В мт4 Вам тоже сначала две позиции надо открыть и обеспечить контроль их открытия. Может тоже работающий код в студию выложите, так, чисто для сравнения.

 
Maxim Kuznetsov


:

Попробую, уже по слогам, пояснить что делается :-)

Есть предположим , потребность в советнике. Для начала - в самом простом, который торгует по пересечению машек и тралит стоп по фракталам. То есть в терминале, это выглядело так :

То что обведено ЧЁРНЫМ квадратиком - это 1 строка таблицы. Те данные которые советник учитывает в своих алгоритмах.

Задача use-case которые были приведены - максимально компактно описать что лежит в этой области, как оно считается и чем советник это дополняет. Какие вычисления на основе этих данных производит.

На мой взгляд, самое простое что можно сделать -
1) перечислить эти поля присвоив им имена, то есть перечислить в ENUM
2) написать простую функцию которая по имени из ENUM и бару, отдаёт советнику их значения.

Для рядового программиста появляется некоторая методология (чётко обозначенные шаги) разработки простых советников:

1. Задать Input

2. Описать и дополнить Data, написав формулы; добавить столбцы по мере необходимости

3. Указать какие данные из полученной таблицы и где используются.

Чтобы хранить Data сделан класс DataFrame который хранит данные "по столбцам" обеспечивает доступ по индексам, кеширование данных и вычисления по требованию.

Уже на этой тонкой (кода там мало, только то что строго было необходимо для use-case) основе можно делать много разных советников. Таблица считает, сигналы получаются, сделки открываются.

Конечно этого мало :-) Так и проект только-только открыт.. и тут нет готового решения, это проект. Который только что родился и развивается.

Для общего размышления, пример класса-обертки для Ichimoku, правда на 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:

Для общего размышления, пример класса-обертки для Ichimoku, правда на mql4.

для которого компонента из Ишимоков, вы хотите обёртку ? И главное зачем и какую...
просто потрепаться ? можно, отчего-же нет..

PS/ Exсel видели ? В представлении DataFrame Ишимоки будут выглядить так-же. Как и все прочие.. Трейдеры работают с таблицами на самом деле. Графический чарт это просто частное представление (вид) сводной таблицы. Так и обращаться с этими данными надо как с таблицами.
С точки зрения трейдера - что такое программный объект ??? да ничто. В его практической жизни таких тварей нет.

 
Vladimir Simakov:

Да ладно, CloseBy, если вы не заметили, у меня: pos1.CloseBy(pos2), все остальное открытие ордеров и проверочные операции.

Так не работает.

В мт4 Вам тоже сначала две позиции надо открыть и обеспечить контроль их открытия. Может тоже работающий код в студию выложите, так, чисто для сравнения.

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

Так не работает.

Я же писал, что с контролем открытия этих самых ордеров.

Причина обращения: