Язык программирования 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/
Комментарии (8)
35 AM2 Автор Сообщений: 16418 - Андрей
12 sorusm Сообщений: 182 - sorusm
12 sorusm Сообщений: 182 - sorusm
Никак не могу понять, почему «больше или равно», если по логике должно быть «меньше или равно». Lots(symb)-это количество открытых позиций по конкретному символу?
Если меняю знак >= на <=, компилирую, на графике советник торгует, вроде бы нормально, а вот в тестере не появляется ни одной сделки. В чём может быть причина?
7 s22aa Сообщений: 25 - Александр
if(lot>MaxLots) lot=Lot;
меняем на
if(lot>MaxLots) lot=MaxLots;
Редактирован: 18 апреля 2022, 13:25
7 kvashnin007 Сообщений: 651 - Андрей
Хотя можно попробовать и предлагаемый мной вариант.
Правда, хитрости в усреднении большой не обнаружено.
Можно гораздо хитрее. Редактирован: 18 апреля 2022, 13:33
7 kvashnin007 Сообщений: 651 - Андрей
если параметр BuySell = 1, то вообще сделок не открывает ни на бай ни на селл.
Но не у всех в Альпари и на Робофорексе работает. Редактирован: 19 мая 2022, 13:43
20 alex30774 Сообщений: 768
5 Ali-k Сообщений: 19
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий