AM2
Андрей

 
Уровень 35

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


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

Рейтинг 283



Хитрый усреднитель на 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
  • Просмотров: 14657
  • 13 сентября 2016, 10:55
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

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

Брокер для ваших роботов, 15 лет на рынке

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

+
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

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

  • 13 сентября 2016, 15:33
0
Доброго дня! А сделки открытые вручную подхватывать и усреднять будет?
avatar

  12  sorusm Сообщений: 182 - sorusm

  • 29 мая 2018, 09:14
0
А уровни стоп лосс и тейк профит виртуальные или выставляются?
avatar

  12  sorusm Сообщений: 182 - sorusm

  • 24 ноября 2017, 09:52
0
«За увеличение лота будет отвечать следующий код:if(Lots(symb)>=BigLot) lot=lot*Mnogitel; ...»
Никак не могу понять, почему «больше или равно», если по логике должно быть «меньше или равно». Lots(symb)-это количество открытых позиций по конкретному символу?
Если меняю знак >= на <=, компилирую, на графике советник торгует, вроде бы нормально, а вот в тестере не появляется ни одной сделки. В чём может быть причина?
avatar

  7  s22aa Сообщений: 25 - Александр

  • 5 марта 2018, 21:26
+
0
Опечатка:

if(lot>MaxLots) lot=Lot;
меняем на
if(lot>MaxLots) lot=MaxLots;


Редактирован: 18 апреля 2022, 13:25
avatar

  8  kvashnin007 Сообщений: 734 - Андрей

  • 18 апреля 2022, 13:24
0
Извините не заметил большую букву в Lot.
Хотя можно попробовать и предлагаемый мной вариант.

Правда, хитрости в усреднении большой не обнаружено.
Можно гораздо хитрее.
Редактирован: 18 апреля 2022, 13:33
avatar

  8  kvashnin007 Сообщений: 734 - Андрей

  • 18 апреля 2022, 13:29
0
Если параметр BuySell = 2, то торгует только в селл;

если параметр BuySell = 1, то вообще сделок не открывает ни на бай ни на селл.

Но не у всех в Альпари и на Робофорексе работает.
Редактирован: 19 мая 2022, 13:43
avatar

  20  alex30774 Сообщений: 782

  • 19 мая 2022, 13:14
+1
Здравствуйте. А можно доработать данный усреднитель и сделать, чтобы он подхватывал и усреднял сделки по магику другого советника или открытые вручную по выбору?
avatar

  5  Ali-k Сообщений: 19

  • 2 июня 2022, 17:28

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