Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Evilmaker
Мой вариант:
int i=1;
bool b1 = maFast(1) - maSlow(1) > 0, b2 = b1;
while(b1 == b2)
{
i++;
b2 = maFast(i) - maSlow(i) > 0;
}
i - номер бара предшествующего пересечению, т.е. если считать от "0" бара, то пересечение состоялось i-1 бар назад
ПС: maFast() - это сокращенная запись функции iMA()
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

Речь идет о том, что не будет значимых нововведений. А только баги периодически будут править. А вот все новое мол - в МТ5. Когда они вживую сказали то же самое на конференции в Москве, я уточнил: "То

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано

Благодарю, ребят! Попробую оба варианта. Кстати, такую запись я не встречал в хелпе по mql: maFast. Может, это в пятой версии?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Кстати, такую запись я не встречал в хелпе по mql: maFast. Может, это в пятой версии?

Я же написал: это просто сокращённая запись вызова функции iMA. Ну поленился я писать полностью вызов, зато теперь приходится объяснять... ~x(
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Всем добрый вечер! Кто может написать сову по моей стратегии?

Создавай тему, выкладывай стратегию + хотя-бы ручные тесты. Здесь есть около 10 программистов, если заинтересуешь - сделают.
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
TradeHistory_v4.2

Здравствуйте, коллеги. Индикатор публикуется на бета-тестирование. Буду рад замечаниям и предложениям от программистов.

То, что тут было уже не актуально. Среда программирования MQL - отстой и недостойна, чтобы под нее писать супероптимальный код.

Есть у меня индикатор TradeHistory (мой). Он показывает последние N закрытых сделок по паре из истории. Основное его назначение - оценка прибылей и убытков и принятие решения об применении мартина. Сегодня добавил отображение галочек, показывающих убыток и факт его последующего перекрытия, т.к. глазами оценивать ситуацию бывает сложно. При достижении перекрывающего профита расчет следующих убытков начинается без учета предыдущего профита. Идея такая - бороться с убытками, а профит пусть растворяется в тумане в депозите.

Новые параметры:
CompensationAll - если включен, то выводит данные о компенсациях не только для последней серии перекрытых убытков, а для всех сделок. По умолчанию отключен чтобы не мельтешил.
OverInMoney - если включен, то вместо галочек будут отображаться деньги. В этом режиме нужно увеличить GUI_RightOffset+40, а то залезет за правый край окна.
FilterMagic - если включен, то фильтрует ордера по магику. Магик 0 - ручная торговля. Если выключен, то все ордера по паре в одной таблице.

Вот прибыль компенсировала предыдущий убыток. Чисто, красиво, малыми лотами.


Вот два некомпенсированных убытка и пример плохой торговли. Надо подумать.


Евробакс. Режим CompensationAll + OverInMoney - FilterMagic. Красиво)



Мякотка

Мои подозрения, что я выводил ордера в порядке их открытия, а не в порядке закрытия, оправдались. Поэтому если в конце серии закрыт давний ордер с большой прибылью, то индикатор не показывал, что суммарный убыток серии последних сделок перекрыт этим старым ордером, т.к. такой ордер не был наверху серии. А одна из главных задач индикатора - определение необходимости применения мартина по результатам закрытия сделок.

Поскольку выборка ордеров по порядку закрытия средствами MQL не предусмотрена, то в версии TradeHistory_v4.1 организована предварительная обратная сортировка по дате/времени закрытия первых ордеров в количестве HistHistOrdersCount*5. Этот запас, думаю, позволит с уверенностью перекрыть ситуации, когда закрывается старый ордер, который долго держали. Вроде не тормозит.

Вишенка и новая версия 4.2
Внимание! В коде присутствует сортировка по условию while. Если я где-то ошибся, то Ваш терминал зависнет. У меня работает на 9 парах, но мало ли.

[SPOILER]
Чудесная встроенная в MQL функция сортировки массива ArraySort не умеет сортировать массив по нескольким столбцам. Из этого следует, что если ордера были закрыты в одно время, то внутри этого времени сортировка ордеров в обратном порядке приведет к тому, что старые ордера будут сверху (ну так оно работает). А если используется усреднение (на еврофунте сейчас я стопы не использую например), то перекрытие убытков профитом индикатор опять покажет некорректно.

Почитал форумы. Пришлось писать собственную функцию дополнительной сортировки. А сортировка нужна такая, чтобы сделки, закрытые в одну дату/время выводились в порядке уменьшения профита - сверху профиты, ниже убытки. Так произойдет корректная фиксация перекрытия убытка профитами последующих сделок.


Буду благодарен за предложения от программистов по оптимизации логики кода.
Оптимизацию синтаксиса проводить не буду. Не забудьте, что я дельфин, поэтому мой стиль отличается от сишного. А на скорость пули не влияет.

TradeHistory_v4.mq4
TradeHistory_v4.1.mq4
TradeHistory_v4.2.mq4

Изменено пользователем st2050
  • Лайк 4
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Приветствую Господа трейдеры. Я новичок. Пытаюсь освоить язык программирования. Уже запутался. Задача - открытие одного ордера на каждом закрытии бара М15 в ту же сторону
...........
open = NormalizeDouble(iOpen(Symbol(),PERIOD_M15,1),Digits);
close = NormalizeDouble(iClose(Symbol(),PERIOD_M15,1),Digits);

if (close > open && CountTrades() == 0)
{ ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, SL, TP, "", magic, Blue);
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
{ SL = NormalizeDouble(Ask - StopLoss * Point, Digits);
TP = NormalizeDouble(Ask + TakeProfit * Point, Digits);
bool res=OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
if(!res)
{ Print ("Ошибка модификации ордера. Код ошибки=",GetLastError());
}
else
Print("Цена ордера успешно модифицирована.");
}
}
........
При условии " CountTrades() == 0" открывает один ордер, но пока открытый ордер не закроется, другой не открывает. Без этого условия, ордера строчит на каждом тике . Помогите пжста , как правильно прописать проверку баров? :-/ Извините за возможно некорректно сформулированный вопрос, но думаю логика понятна. Всем профита!

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Вам нужно немного уточнить логику - вы хотите, чтобы на каждом баре открывался ордер, не важно при этом, сколько уже их открыто? Тогда вам проверка CountTrades() не нужна, вам нужен алгоритм выполнения кода на каждом баре. Можно примерно так:

int BBars=0;
void OnTick()
{
if(BBars!=Bars)
{BBars=Bars;
// код выполняемый на каждом баре текущего ТФ....
}
}
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

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

bool isNewBar()
{
static datetime new_Bar;
if (new_Bar == Time[1]) return(false); //Если бар не закрыт - выход
new_Bar = Time[1];
return(true);
}

вызов: if ( isNewBar() ) { //Ваш код.... }

  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Доброго дня. Программирую недавно. Есть несколько вопросов , которые сам сделать не могу.
Один из таких:

#property description "Советник выставляет всем ордерам стоплосс"
//--------------------------------------------------------------------*/
extern int Stoploss = 100; //стоплосс
//--------------------------------------------------------------------
int init()
{
DrawLABEL("Stoploss",StringConcatenate("Stoploss ",Stoploss),5,15,Gray);
return(0);
}
//-------------------------------------------------------------------
int deinit()
{
ObjectDelete("Stoploss");
return(0);
}
//--------------------------------------------------------------------
int start()
{
if (!IsTradeAllowed()) return(0);
int STOPLEVEL=MarketInfo(Symbol(),MODE_STOPLEVEL);
double OSL,OOP,SL;
int tip;
for (int i=0; i {
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if (OrderSymbol()==Symbol())
{
tip = OrderType();
OSL = NormalizeDouble(OrderStopLoss(),Digits);
OOP = NormalizeDouble(OrderOpenPrice(),Digits);
SL=OSL;
if (tip==OP_BUY)
{
if (OSL==0 && Stoploss>=STOPLEVEL && Stoploss!=0)
{
SL = NormalizeDouble(OOP - Stoploss * Point,Digits);
}
if (SL != OSL)
{
if (!OrderModify(OrderTicket(),OOP,SL,0,0,White)) Print("Error OrderModify ",GetLastError());
}
}
if (tip==OP_SELL)
{
if (OSL==0 && Stoploss>=STOPLEVEL && Stoploss!=0)
{
SL = NormalizeDouble(OOP + Stoploss * Point,Digits);
}
if (SL != OSL)
{
if (!OrderModify(OrderTicket(),OOP,SL,0,0,White)) Print("Error OrderModify ",GetLastError());
}
}
}
}
}
return(0);
}
//--------------------------------------------------------------------
void DrawLABEL(string name, string Name, int X, int Y, color clr)
{
if (ObjectFind(name)==-1)
{
ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
ObjectSet(name, OBJPROP_CORNER, 1);
ObjectSet(name, OBJPROP_XDISTANCE, X);
ObjectSet(name, OBJPROP_YDISTANCE, Y);
}
ObjectSetText(name,Name,12,"Arial",clr);
}
//--------------------------------------------------------------------

Как сделать так чтобы стоплосс устанавливался на все ордера, кроме первого бай и первого сел ?
Большая просьба о помощи.

Изменено пользователем ni349
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Как сделать так чтобы стоплосс устанавливался на все ордера, кроме первого бай и первого сел ?

Что Вы называете первым? по времени открытия/магику или цене... В МТ ордера сортируются по времени открытия/магику, т.е. для этого варианта достаточно сделать счётчик или флаг типа:
bool bb=false, bs=false;
(после проверки типа ордера на бай)
if (!bb) { bb = true; continue; }

с bs тоже самое для селл. Таким образом первый бай и селл из списка ордеров не будут модифицированы. Можно, конечно и с сортировкой заморочиться, но я думаю и так сойдет...
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Парни, вот еще одна задачка:
Требуется находить на графике простую комбинацию из 2-х - 4-х подряд идущих свечей одинакового направления размером не меньше заданного (см. рисунок во вложении).
Т.е. имеем вводные:
BarsCount = задаваемое количество подряд идущих свечей одного направления
BarsPipsMin = минимальный размер свечи в пунктах.

Если находим BarsCount свечей подряд бай, каждая из которых не меньше BarsPipsMin - возвращаем к примеру 1, если то-же селл - возвращаем -1.

Кагбэ я это написал, обычный перебор в цикле со сравнением цен и размеров свечей, задача несложная, НО... получилось довольно громоздко и самое главное - медленно для тестера. Есть какие мысли, как это сделать компактно и быстро?

1.jpg

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Парни, вот еще одна задачка:
Требуется находить на графике простую комбинацию из 2-х - 4-х подряд идущих свечей одинакового направления размером не меньше заданного (см. рисунок во вложении).
Т.е. имеем вводные:
BarsCount = задаваемое количество подряд идущих свечей одного направления
BarsPipsMin = минимальный размер свечи в пунктах.

Если находим BarsCount свечей подряд бай, каждая из которых не меньше BarsPipsMin - возвращаем к примеру 1, если то-же селл - возвращаем -1.

Кагбэ я это написал, обычный перебор в цикле со сравнением цен и размеров свечей, задача несложная, НО... получилось довольно громоздко и самое главное - медленно для тестера. Есть какие мысли, как это сделать компактно и быстро?


Вы можете выложить свой кусок кода? ибо возможно его можно оптимизировать.
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ок, вот код:
Входные:
BarCount - количество свечей для проверки
BarPipsMin - минимальный размер свечи в пунктах

         int barBuy = 0;
int barSell = 0;

for (int i = 1; i {
if (Close > Open)
{
if(Close - Open >= BarPipsMin * Point)
barBuy ++;
}
else if (Close )
{
if(Open - Close >= BarPipsMin * Point)
barSell ++;
}
}
if (barBuy == BarCount)
return(1);
else if (barSell == BarCount)
return(-1);
else
return(0);


Поскольку детект идет по закрытым свечам, думаю можно еще по аналогии с недавно приведенным примером от Oll добавить вызов этой функции на новом баре а не на каждом тике.

Кстати, кто знает, как получить время тестирования эксперта в тестере? Для последующей оптимизации кода (ну кроме как сидеть с секундомером :) )
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Ок, вот код:
Входные:
BarCount - количество свечей для проверки
BarPipsMin - минимальный размер свечи в пунктах

         int barBuy = 0;
int barSell = 0;

for (int i = 1; i {
if (Close > Open)
{
if(Close - Open >= BarPipsMin * Point)
barBuy ++;
}
else if (Close )
{
if(Open - Close >= BarPipsMin * Point)
barSell ++;
}
}
if (barBuy == BarCount)
return(1);
else if (barSell == BarCount)
return(-1);
else
return(0);


Поскольку детект идет по закрытым свечам, думаю можно еще по аналогии с недавно приведенным примером от Oll добавить вызов этой функции на новом баре а не на каждом тике.

Кстати, кто знает, как получить время тестирования эксперта в тестере? Для последующей оптимизации кода (ну кроме как сидеть с секундомером :) )

чтобы меньше шагов выполнялось можно вставить строчку в цикле после проверок
if(buyBar!=0&&barSell!=0)break;
и действительно проверка на открытии свечи значительно уменьшит время также.
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Спойлер


Ок, вот код:
Входные:
BarCount - количество свечей для проверки
BarPipsMin - минимальный размер свечи в пунктах

         int barBuy = 0;
int barSell = 0;

for (int i = 1; i {
if (Close > Open)
{
if(Close - Open >= BarPipsMin * Point)
barBuy ++;
}
else if (Close )
{
if(Open - Close >= BarPipsMin * Point)
barSell ++;
}
}
if (barBuy == BarCount)
return(1);
else if (barSell == BarCount)
return(-1);
else
return(0);


Поскольку детект идет по закрытым свечам, думаю можно еще по аналогии с недавно приведенным примером от Oll добавить вызов этой функции на новом баре а не на каждом тике.

Кстати, кто знает, как получить время тестирования эксперта в тестере? Для последующей оптимизации кода (ну кроме как сидеть с секундомером :) )

По идее можно кэшировать результат по свечкам, чтобы в последствие проверять только последнею которая закроется, а не заново пересчитывать. Для проверки BarCount свечей на каждой новой свече это сэкономит BarCount - 1 итерации ( При 3 свечах для проверки это сэкономит 2/3 итераций)
Да конечно, если еще и проверять только на открытие новой свечи, а не на каждом тике как говорилось выше, то скорость прохода в тестере должна подняться многократно.

Когда тестер заканчивает работу он пишет общее время выполнения. Изменено пользователем Qj
  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Qj и arbuz771, спасибо за подсказки!
Блин, он-же в журнале пишет общее время теста в конце, вот я затупил:)

Исправлю с вашими замечаниями, но в принципе базовая функция нормальная?
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
JR не нормальная. Цикл вообще не нужен. Просто счётчик баров с фильтром размера. Логика:
Если размер бара больше Х - счетчикБаровБай++ иначе =0
Если размер бара меньше -Х - счётчикБаровСелл++ иначе =0
Если счетчикБаровБай больше N - код
Если счётчикБаровСелл больше N - код

ПС: Естественно запускать счётчики на открытии бара.
ППС: после исполнения кода можно обнулить счётчик или нет - тебе решать. Изменено пользователем 0ll
  • Лайк 3
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Oll, но в твоем примере не сработает отследить что нужные бары идут подряд (а это именно то, что нужно) или я чего-то не понял? Изменено пользователем JR
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Коллеги прошу помощи с советником не могу понять почему не отрабатывает половина функции. Функция заключается в том что если цена пошла в минус на N пунктов то сделка закрывается и открывается в противоположенном направлении с удвоенным лотом и укороченным TP (так сказать что бы перекрыть убыток по закрытой сделке). Не выполняется именно раздел if (OrderType() == OP_SELL) в то время как раздел на OP_BUY отрабатывает отлично. Ни ошибок ни предупреждений программа не выдает.

void Castle()
{
for (int i=0; i {
if (OrderSelect(i,SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL) //--- НЕ ПОНИМАЮ ПОЧЕМУ НЕ ВЫПОЛНЯЕТСЯ
{
if (OrderProfit()*(-1) > Zamok)
{
DeleteOrders();
TP = NormalizeDouble(Ask + (TakeProfit/2) * Point, Digits());
if (!OrderSend(Symbol(), OP_BUY, Lots*2, MarketInfo(OrderSymbol(),MODE_ASK), Slippage, SL, TP, comment, 888, 0, DimGray))
Print("Замок не сформирован ", GetLastError());
}
}
if (OrderType() == OP_BUY) //-- ВЫПОЛНЯЕТСЯ НА УРА
{
if (OrderProfit()*(-1) > Zamok)
{
DeleteOrders();
TP = NormalizeDouble(Bid - (TakeProfit/2) * Point, Digits());
if (!OrderSend(Symbol(), OP_SELL, Lots*2, MarketInfo(OrderSymbol(),MODE_BID), Slippage, SL, TP, comment, 888, 0, DimGray))
Print("Замок не сформирован ", GetLastError());
}
}

}
}
}
}

Изменено пользователем _Ugin_
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Всем привет! Не могу понять почему ордера не открываются) В этом деле новичок, нужна помощь.

Мордекай.mq4

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

В новых билдах появилась интересная примочка, сейчас при компиляции, выдаёт видимо время разовой прогонки кода. Я ещё не проверял уменьшение времени при оптимизации, но видимо задумано для этого. Правда не совсем понятно, имеется ввиду прогонка основного тела советника или с учётом выхода на функции, так же если имеется множество условий с выходом на функции, не активные в данный момент, то картина опять же не будет чёткой.

Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...