AM2
Андрей

 
Уровень 26

  Торгую в компаниях:


Группа "Программирование на MQL"

Рейтинг 270



Хитрый усреднитель на MQL5

Язык программирования MQL5 и сама платформа МТ5, как показывает опыт программирования в «Столе заказов MQL» не очень популярны среди основной массы трейдеров. Заказов на MQL5 единицы. Для того чтобы хоть немного популяризировать MQL5 у местной общественности, я попытался создать простейший усреднитель с минимальным количеством кода и уложился в 100 строк. Алгоритм усреднения, используемый в советнике, также заслуживает внимания.

Торговая стратегия:

Эксперт торгует в направлении заданном в настройках BuySell. Закрывает позицию при достижении профита Profit или убытка Loss в валюте депозита. Если после открытия позиции цена пошла не в нашу сторону, советник открывает усредняющий ордер постоянным объемом Lot, через указанное расстояние в пунктах Step. Когда эксперт набрал позиций объемом BigLot, начальный лот увеличивается на коэффициент Mnogitel. Таким образом открывая очередной усредняющий ордер с повышенным объемом, мы увеличиваем шансы позиции закрыться в прибыль. Все операции эксперт совершает на открытии свечи.


Рис.1. Сделки эксперта на графике. EURUSD, H1.


Рис.2. Результат торговли и оптимизации эксперта с 11.01.2013 по 12.09.2016. EURUSD, H1.

Настройки эксперта:


input int BuySell     =    1; // 1-Only Buy 2-Only Sell
input int Step        = 1000; // Step
input double Lot      = 0.1;  // Volume
input double BigLot   = 1;    // Big Lot
input double MaxLots  = 5;    // Maximum lot
input double Profit   = 60;   // Dollars Profit 
input double Loss     = 5100; // Dollars Loss
input double Mnogitel = 12;   // Lots Mnogitel 



Теперь разберем код эксперта:

Чтобы облегчить создание торговых функций будем пользоваться классом CTrade из стандартной библиотеки MT5:


#include <Trade\Trade.mqh>             
CTrade trade;


Далее нам понадобятся всего 2 дополнительные функции SymbProfit и Lots.

Функция SymbProfit вычисляет прибыль по открытой позиции:

//+------------------------------------------------------------------+
//|  Position Profit                                                 |
//+------------------------------------------------------------------+
double SymbProfit(string Symb)
  {
   double p=0;
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(PositionGetSymbol(i)==Symb)
        {
         p=+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
        }
     }
   return(p);
  }


Функция Lots считает объем открытой позиции:


//+------------------------------------------------------------------+
//|  Position Volume                                                 |
//+------------------------------------------------------------------+
double Lots(string Symb)
  {
   double lots=0;

   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(PositionGetSymbol(i)==Symb)
        {
         if(PositionGetInteger(POSITION_TYPE)<2)
           {
            lots=PositionGetDouble(POSITION_VOLUME);
           }
        }
     }
   return(lots);
  }


Цены аск и бид в MQL5 получаем отдельно:


   string symb=Symbol();
   double Ask=SymbolInfoDouble(symb,SYMBOL_ASK);
   double Bid=SymbolInfoDouble(symb,SYMBOL_BID);


Торговать будем на новом баре:


   if(bars!=Bars(symb,0))
     {
       ...
      bars=Bars(symb,0);
     }


И запишем условия для покупок и продаж:


      if(BuySell==1 && (PositionsTotal()<1 || (PositionsTotal()>0 && (pr-Ask)/_Point>=Step))) {trade.PositionOpen(symb,0,lot,Ask,0,0); pr=Bid;}//buy
      if(BuySell==2 && (PositionsTotal()<1 || (PositionsTotal()>0 && (Bid-pr)/_Point>=Step))) {trade.PositionOpen(symb,1,lot,Bid,0,0); pr=Bid;}//sell



За увеличение лота будет отвечать следующий код:


      if(Lots(symb)>=BigLot) lot=lot*Mnogitel;
      if(lot>MaxLots) lot=Lot;



Позицию мы будем закрывать следующим образом:


      if(SymbProfit(symb)>Profit || SymbProfit(symb)<-Loss) {trade.PositionClose(symb); lot=Lot;}


На экран советник выводит профит позиции, лот и последнюю цену открытия ордера, которую запоминает при открытии позиции:


      if(BuySell==1 && (PositionsTotal()<1 || (PositionsTotal()>0 && (pr-Ask)/_Point>=Step))) {... pr=Bid;}//buy
      if(BuySell==2 && (PositionsTotal()<1 || (PositionsTotal()>0 && (Bid-pr)/_Point>=Step))) {... pr=Bid;}//sell


Вывод информации на экран:


   Comment("\n Lots: ",Lots(symb),
           "\n Profit: ",SymbProfit(symb),
           "\n Price: ",pr);


После закрытия позиции лот становится первоначальным:


if(SymbProfit(symb)>Profit || SymbProfit(symb)<-Loss) {... lot=Lot;}


Вот и весь советник:


//+------------------------------------------------------------------+
//|                                                   HelloSmart.mq5 |
//|                                              Copyright 2016, AM2 | 
//|                                     https://www.forexsystems.biz | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2016, AM2" 
#property link "https://www.forexsystems.biz" 
#property version "1.00" 

#include <Trade\Trade.mqh>             
CTrade trade;

input int BuySell     =    1; // 1-Only Buy 2-Only Sell
input int Step        = 1000; // Step
input double Lot      = 0.1;  // Volume
input double BigLot   = 1;    // Big Lot
input double MaxLots  = 5;    // Maximum lot
input double Profit   = 60;   // Dollars Profit 
input double Loss     = 5100; // Dollars Loss
input double Mnogitel = 12;   // Lots Mnogitel 

int bars=0;
double lot=Lot,pr=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|  Position Profit                                                 |
//+------------------------------------------------------------------+
double SymbProfit(string Symb)
  {
   double p=0;
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(PositionGetSymbol(i)==Symb)
        {
         p=+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
        }
     }
   return(p);
  }
//+------------------------------------------------------------------+
//|  Position Volume                                                 |
//+------------------------------------------------------------------+
double Lots(string Symb)
  {
   double lots=0;

   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(PositionGetSymbol(i)==Symb)
        {
         if(PositionGetInteger(POSITION_TYPE)<2)
           {
            lots=PositionGetDouble(POSITION_VOLUME);
           }
        }
     }
   return(lots);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   string symb=Symbol();
   double Ask=SymbolInfoDouble(symb,SYMBOL_ASK);
   double Bid=SymbolInfoDouble(symb,SYMBOL_BID);

   if(bars!=Bars(symb,0))
     {
      if(BuySell==1 && (PositionsTotal()<1 || (PositionsTotal()>0 && (pr-Ask)/_Point>=Step))) {trade.PositionOpen(symb,0,lot,Ask,0,0); pr=Bid;}//buy
      if(BuySell==2 && (PositionsTotal()<1 || (PositionsTotal()>0 && (Bid-pr)/_Point>=Step))) {trade.PositionOpen(symb,1,lot,Bid,0,0); pr=Bid;}//sell

      if(Lots(symb)>=BigLot) lot=lot*Mnogitel;
      if(lot>MaxLots) lot=Lot;

      if(SymbProfit(symb)>Profit || SymbProfit(symb)<-Loss) {trade.PositionClose(symb); lot=Lot;}
      bars=Bars(symb,0);
     }

   Comment("\n Lots: ",Lots(symb),
           "\n Profit: ",SymbProfit(symb),
           "\n Price: ",pr);
  }
//+------------------------------------------------------------------+



Как вы только что могли убедиться в программировании на MQL5 нет ничего сложного и даже такие вещи как усреднители пишутся довольно таки быстро. Свойства позиции мы могли получить с помощью класса CPositionInfo таким образом можно еще сократить размер кода.

Скачать советник вы можете по ссылке: www.opentraders.ru/downloads/1315/
  • +5
  • Просмотров: 2398
  • 13 сентября 2016, 10:55
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Программирование на MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
Следующая запись в группе  
Работаем с группой ордеров
08 сентября 2016
15 сентября 2016

Комментарии (2)

+
0
С CPositionInfo:


//+------------------------------------------------------------------+
//|                                                   HelloSmart.mq5 |
//|                                              Copyright 2016, AM2 | 
//|                                     https://www.forexsystems.biz | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2016, AM2" 
#property link "https://www.forexsystems.biz" 
#property version "1.00" 

#include <Trade\Trade.mqh> 
#include <Trade\PositionInfo.mqh>   

CTrade trade;
CPositionInfo pos;

input int BuySell     = 2;    // 1-Only Buy 2-Only Sell
input int Step        = 1000; // Step
input double Lot      = 0.1;  // Volume
input double BigLot   = 1;    // Big Lot
input double MaxLots  = 5;    // Maximum lot
input double Profit   = 60;   // Dollars Profit 
input double Loss     = 5100; // Dollars Loss
input double Mnogitel = 3;    // Lots Mnogitel 

int bars=0;
double lot=Lot,pr=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|  Position Profit                                                 |
//+------------------------------------------------------------------+
double SymbProfit(string Symb)
  {
   double p=0;
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(pos.Select(Symb))
        {
         p+=pos.Profit();
        }
     }
   return(p);
  }
//+------------------------------------------------------------------+
//|  Position Volume                                                 |
//+------------------------------------------------------------------+
double Lots(string Symb)
  {
   double lots=0;

   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(pos.Select(Symb))
        {
         lots+=pos.Volume();
        }
     }
   return(lots);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(string symb)
  {
   for(int i=PositionsTotal()-1;i>=0;i--)
     {
      if(pos.Select(symb))
        {
         trade.PositionClose(symb);
        }
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   string symb=Symbol();
   double Ask=SymbolInfoDouble(symb,SYMBOL_ASK);
   double Bid=SymbolInfoDouble(symb,SYMBOL_BID);

   if(bars!=Bars(symb,0))
     {
      if(BuySell==1 && (PositionsTotal()<1 || (PositionsTotal()>0 && (pr-Ask)/_Point>=Step))) {trade.PositionOpen(symb,0,lot,Ask,0,0); pr=Bid;}//buy
      if(BuySell==2 && (PositionsTotal()<1 || (PositionsTotal()>0 && (Bid-pr)/_Point>=Step))) {trade.PositionOpen(symb,1,lot,Bid,0,0); pr=Bid;}//sell

      if(Lots(symb)>=BigLot) lot=lot*Mnogitel;
      if(lot>MaxLots) lot=Lot;

      if(SymbProfit(symb)>Profit || SymbProfit(symb)<-Loss) {CloseAll(symb); lot=Lot;}
      bars=Bars(symb,0);
     }

   Comment("\n Lots: ",Lots(symb),
           "\n Profit: ",SymbProfit(symb),
           "\n Price: ",pr);
  }
//+------------------------------------------------------------------+

avatar

  26  AM2 Автор Сообщений: 6925 - Андрей

  • 13 сентября 2016, 15:33
+
0
А уровни стоп лосс и тейк профит виртуальные или выставляются?
avatar

  5  sorusm Сообщений: 80

  • 24 ноября 2017, 09:52

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий
Начать торговлю с Альпари

 
Как начать: открываем первую торговую сделку за 7 шагов →