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

От xbms, 13 апреля, 2013 в Уголок Программиста

#3226

Уважаемый xbms!
Первым делом хочу поблагодарить Вас за обучение программированию.

Написал советник по Вашим урокам, который открывает ордера на продажу если свеча открылась выше верхней линии Боллинджера и закрылась ниже, а на покупку, в обратном порядке. Стоп лосс определяется из минимальной цены из N последних баров (на покупку), максимальной цены из N последних баров (на продажу). Тейк профит на касании ценой противоположной линии Боллинджера. Открытие и закрытие ордеров сова производит правильно. А вот расчет мин и макс цен для стоп лосса не правильный. Я для этого вывел расчет цен на экран. Обнаружил, что определяется мин и макс цен во всем графике с момента начала работы советника а не на ближайших свечах к цене. В связи с этим, если стоп лосс ордера на продажу будет меньше цены выставления ордера, то соответственно это будет ошибкой и из за этого сова не устанавливает стоп лосс.
Компиляция совы ошибок не выдает, а в журнале тестера появляется много ошибок типа -
2016.02.29 11:04:08.725 TestGenerator: unmatched data error (high value 1.13209 at 2015.09.14 16:00 is not reached from the least timeframe, high price 1.13208 mismatches)
2016.02.29 11:04:08.724 TestGenerator: unmatched data error (volume limit 13655 at 2015.09.04 16:00 exceeded)
2016.02.29 11:07:32.763 2015.01.21 18:00 CrossInd EURUSD,H1: Ошибка модификации ордера на продажу
2016.02.29 11:07:32.763 2015.01.21 18:00 CrossInd EURUSD,H1: OrderModify error 130

И что интересно ошибки модификации ордера идут только на продажу.
Прошу помочь разобраться с этой проблемой.
Заранее благодарю.

CrossInd.ex46 скач.
CrossInd.mq410 скач.

Изменено 4 марта, 2016 пользователем alex161271

#3227

Всем привет. Подскажите пожалуйста как записать в мкл4 пересечение линией графика цены. Спасибо.

#3228


Всем привет. Подскажите пожалуйста как записать в мкл4 пересечение линией графика цены. Спасибо.

Примерно так:
if ( Line2bar > Price2bar && Line1bar
#3229
double MAPrice1 = iMA(_Symbol, PERIOD_CURRENT, 14, 0, MODE_EMA, PRICE_CLOSE, 1);
double MAPrice2 = iMA(_Symbol, PERIOD_CURRENT, 14, 0, MODE_EMA, PRICE_CLOSE, 2);

if (High[2] Low[1] High[1] > MAPrice1) // High первой свечи выше МА, т.е. цена пробила МА
{
Print("Пробитие МА ценой снизу вверх");
// Необходимые действия
}


Проверяется условие, что вторая свеча целиком ниже МА. Затем что Лоу первой свечи ниже МА, а Хай выше МА. Т.е. произошло пересечение бара и МА.
В качестве МА взята ЕМА14.

Для пробития сверху вниз в первой строке условного оператора замени Хай на Лоу и знак "меньше" на "больше".
#3230

Сижу, строчу и тут как гром среди ясного неба понимаю, что советник же каждый раз перезапускается и вычисления все происходят с нуля, а мне нужно сделать одну переменную долговременного хранения. Какие есть варианты реализации? Работать с файлами как-то совсем не охота, да и время теряется больше чем хотелось бы.

#3231


Сижу, строчу и тут как гром среди ясного неба понимаю, что советник же каждый раз перезапускается и вычисления все происходят с нуля, а мне нужно сделать одну переменную долговременного хранения. Какие есть варианты реализации? Работать с файлами как-то совсем не охота, да и время теряется больше чем хотелось бы.


объяви ее перед всеми блоками, ну например после строчки #property strict
и дальше работай в OnTick с этой переменной не обнуляя ее в начале онтика.
#3232



Сижу, строчу и тут как гром среди ясного неба понимаю, что советник же каждый раз перезапускается и вычисления все происходят с нуля, а мне нужно сделать одну переменную долговременного хранения. Какие есть варианты реализации? Работать с файлами как-то совсем не охота, да и время теряется больше чем хотелось бы.


объяви ее перед всеми блоками, ну например после строчки #property strict
и дальше работай в OnTick с этой переменной не обнуляя ее в начале онтика.

Пробовал, всегда выдает 1
Спойлер

#property strict
int a=1;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
a=a++;
Alert(a);

}
//+------------------------------------------------------------------+



Добавлено: 29-02-2016 21:32:43

Все мой косяк) Зачем-то a= сделал, только не пойму почему это сразу все ломает, ведь все равно a++ выполняется и только потом "a" равняется итоговому выражению. Ну да и ладно)
Выходит extern это тоже может быть долговременная память

Изменено 1 марта, 2016 пользователем SVS696

#3233

У меня возникла необходимость передавать данные из одного индикатора в другой.
Собственно с передачей данных проблем нет, можно передавать через глобальные переменные или другим способом,
а вот с синхронизацией все туманно.

Может кто знает:
1. В каком порядке производится расчет нескольких индикаторов, прикрепленных к одному графику?
2. В какой момент и в каком порядке изменяется размер индикаторных буферов?

В чем суть проблемы: есть один индикатор (ведущий), который выполняет расчет (на каждой свече или каждом тике, в данном случае это неважно). Есть пара ведомых индикаторов, которые должны принять данные расчета и отобразить. Как обеспечить, чтобы индикаторы считались в нужном порядке, т.е. сначала ведущий, потом ведомые?

Изменено 1 марта, 2016 пользователем ie67

#3234

Выведи принтами время с миллисекундами - и напиши нам результат. ;)

#3235


Выведи принтами время с миллисекундами - и напиши нам результат. ;)



Время здесь не поможет. При изменении объема кода в любом из индикаторов картина будет меняться.
Вопрос именно в порядке вызова индикаторов. Индикаторы выполняются в одном (интерфейсном) потоке.
При поступлении тика терминал должен вызвать OnCalculate() последовательно для каждого индикатора.
Основной вопрос - в каком порядке? По именам, по номерам подокон или еще как-то?

Изменено 1 марта, 2016 пользователем ie67

#3236

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

#3237



Выведи принтами время с миллисекундами - и напиши нам результат. ;)


Время здесь не поможет. При изменении объема кода в любом из индикаторов картина будет меняться.
Мы в курсе потоков МТ... после изменения объёма кода и следовательно перекомпиляции, индюк должен переинициализироваться и поэтому, возможно, изменится положение его точки входа в стеке МТ - это и покажут миллисекунды в логе.
#3238

Добрый день, интересует вопрос как прописать в индикаторе статистику сигналов (винрейт), желательно за определенное время.
Помогите примером.
Если ранее данный вопрос обсуждался в ветке - ткните носом, не успел еще ее всю прочесть.

#3239


Добрый день, интересует вопрос как прописать в индикаторе статистику сигналов (винрейт)
Если ранее данный вопрос обсуждался в ветке - ткните носом, не успел еще ее всю прочесть.

в этой ветке такого не помню. объясните толком чего хотите, т.к. из того что понял Вам советник по индюку нужен.
#3240

0ll, не, пример данной статистики/счетчика/тестера картинкой в приложении, не знаю как он правильно называется. Подсчет сигналов по стрелкам и их винрейт.
Вот и вопрос, как сие реализовано, с помощью чего?
Опыта в mql еще нет, только только въезжаю.

EURUSDabM15.png

#3241
brujo что за индюк? я знаю как это реализовано, но желательно на индюке посмотреть...
#3242

0ll, в этом то и проблема, что открытого кода нет, так бы тоже сам смотрел да копался потихоньку.
На скрине предоставлен Strong_Reversal, продают его, в гугле легко ищется, ссылки постить не буду.
Но только на статистику смотреть не надо, не все в нем так сладко, как кажется впервой.

#3243
brujo ну я так и думал, что для бинарных. Он считает стату по следующей свече после стрелки. если была реверсная свеча +1, если нет -1.
#3244

Всем привет!
Есть вопрос.

Про instant execution.

У меня сова проверяет условия раз в 5минут.

Правильно я понимаю, если я открою счет в Альфе ф, а там для мт4 только instant execution.

То при проверке условия, если будет сильная волатильность, сова будет открывать сделку, а цена уйдет чутка => ордер не будет исполнен и придется 5мин сове снова тупить?
Так?

т.е. "instant" исполнение в топку в любом случае?

#3245
Найк если ордер не открывается, то возникает ошибка и МТ сообщает её номер. От Вас зависит как сова будет реагировать на это (те же реквоты). Так, что ордер будет открыт в не зависимости от названия кухни. :d
#3246

Не совсем понял логики данного предупреждения. Как его решить?

return value of 'OrderSelect' should be checked Drifter_1.00.mq4 114 21

#3247


Не совсем понял логики данного предупреждения. Как его решить?

return value of 'OrderSelect' should be checked Drifter_1.00.mq4 114 21


OrderSelect возвращает результат о том что все окей или нет, вы это не проверяете.
#3248

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

Вот часть существующего кода, правильно ли я понимаю,
что на выходе, в переменной runningpoints - будет сумма всех пунктов всех ордеров,
(а не пунктов от БУ сетки ?)

Спойлер



int runningpoints=0;
int numopen=0;
double runningprofit=0;
bool CloseTrades=false;
bool CloseManual=false;
bool closeonsell=false;
bool closeonbuy=false;

for(int a=OrdersTotal()-1;a>=0;a--)
{
if(!OrderSelect(a,SELECT_BY_POS,MODE_TRADES))
continue;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==mn)
{
if(OrderType()==OP_BUY)
{
runningpoints+=(Bid-OrderOpenPrice())/Point;
runningprofit+=OrderProfit()+OrderCommission()+OrderSwap();
closeonsell=true;
numopen+=1;
}
if(OrderType()==OP_SELL)
{
runningpoints+=(OrderOpenPrice()-Bid)/Point;
runningprofit+=OrderProfit()+OrderCommission()+OrderSwap();
closeonbuy=true;
numopen+=1;
}
}




А мне нужно получить переменную, в которой будет расстояние от цены БУ сетки (положительное, если мы в плюсе,
отрицательное, если в минусе).
Можно ли это сделать с минимальным изменением кода выше ?

Нашел два скрипта, которые расчитывают и выводят в алерте цену БУ и растояние в пунктах.
Прикрепил эти скрипты и коды под спойлерами.

Скрипт 1
Спойлер


//+------------------------------------------------------------------+
//| Bezubytok.mq4 |
//| Copyright © 2007, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#include
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int Spr= MarketInfo(Symbol(),MODE_SPREAD);
//------------ Безубыток ---------------------------------------------------
double B2_B=0,B2_S=0,B2_LB=0,B2_LS=0,BSw=0,SSw=0;
for(int b2=0;b2 {
if(OrderSelect(b2,SELECT_BY_POS,MODE_TRADES)==false) continue;
if(OrderSymbol()==Symbol())
{
if (OrderType()==OP_BUY)
{
B2_B=((B2_B*B2_LB)+(OrderOpenPrice()*OrderLots()))/(B2_LB+OrderLots());
B2_LB=B2_LB+OrderLots();
BSw=BSw+OrderSwap();
}
if (OrderType()==OP_SELL)
{
B2_S=((B2_S*B2_LS)+(OrderOpenPrice()*OrderLots()))/(B2_LS+OrderLots());
B2_LS=B2_LS+OrderLots();
SSw=SSw+OrderSwap();
}
}}
double M2B=0,M2S=0 ,M5;
if (B2_LB>B2_LS) // Идём вверх
{
for(int J2=0;J2 {
M2B=J2*B2_LB*10;
M2S=((B2_B-B2_S+Spr*Point)/Point+J2)*(B2_LS*(-10));
if (M2B+M2S+BSw+SSw>=0)
{
M5=NormalizeDouble(B2_B+J2*Point,Digits);
break;
}}}
if (B2_LS>B2_LB) // Идём вниз
{
for(int J3=0;J3 {
M2S=J3*B2_LS*10;
M2B=((B2_B-B2_S+Spr*Point)/Point+J3)*(B2_LB*(-10));
if (M2S+M2B+BSw+SSw>=0)
{
M5=NormalizeDouble(B2_S-J3*Point,Digits);
break;
}}}
string Message;
if (B2_LS==B2_LB && B2_LB!=0 ) Message="Залокированные позиции" ;
else
Message="Уровень без убытка "+"\n"+" "+DoubleToStr(M5,Digits)+"\n"+
" Надо пройти "+DoubleToStr((M5-Bid)/Point,0);
MessageBox(Message,Symbol(),MB_OK);
//----
return(0);
}
//+------------------------------------------------------------------+




Скрипт 2
Спойлер


//+------------------------------------------------------------------+
//| Zero_Level.mq4 |
//| Copyright © 2007, Xupypr |
//+------------------------------------------------------------------+
// Скрипт вычисляющий уровни без убытка, на покупку, на продажу с учетом накопленных свопов.
#property copyright "Copyright © 2007, Xupypr"
#include
void start()
{
double BuyLots=0;
double SellLots=0;
double BuyProfit=0;
double SellProfit=0;
int Total=OrdersTotal();
for (int i=Total-1;i>=0;i--)
{
if (OrderSelect(i,SELECT_BY_POS))
{
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_BUY)
{
BuyLots=BuyLots+OrderLots();
BuyProfit=BuyProfit+OrderProfit()+OrderCommission()+OrderSwap();
}
if (OrderType()==OP_SELL)
{
SellLots=SellLots+OrderLots();
SellProfit=SellProfit+OrderProfit()+OrderCommission()+OrderSwap();
}
}
}
double Price=0;
double TickValue=MarketInfo(Symbol(),MODE_TICKVALUE);
if (BuyLots>0) double BuyLevel=NormalizeDouble(Bid-(BuyProfit/(TickValue*BuyLots)*Point),Digits); else BuyLevel=0;
if (SellLots>0) double SellLevel=NormalizeDouble(Ask+(SellProfit/(TickValue*SellLots)*Point),Digits); else SellLevel=0;
if ((BuyLots-SellLots)>0) Price=NormalizeDouble(Bid-((BuyProfit+SellProfit)/(TickValue*(BuyLots-SellLots))*Point),Digits);
if ((SellLots-BuyLots)>0) Price=NormalizeDouble(Ask+((BuyProfit+SellProfit)/(TickValue*(SellLots-BuyLots))*Point),Digits);
string Title="Уровень без убытка для "+Symbol();
string ZeroLevel=" не существует";
if (Price>0) ZeroLevel=" = "+DoubleToStr(Price,Digits);
string Buy=" не существует";
if (BuyLevel>0) Buy=" = "+DoubleToStr(BuyLevel,Digits);
string Sell=" не существует";
if (SellLevel>0) Sell=" = "+DoubleToStr(SellLevel,Digits);
string Message="Уровень без убытка"+ZeroLevel+"\t\nУровень на покупку"+Buy+"\t\nУровень на продажу"+Sell;
MessageBox(Message,Title,MB_OK|MB_ICONINFORMATION);
}




Но уж очень там все запутано для меня. И не хочется использовать один из этих кодов в готовом виде,
потому что там свой цикл, который похоже дублирует цикл, существующий уже в советнике.
Если поставить два, то будут большие тормоза в тестировании...

Может кто-то сможет сделать на основе существующего кода расчет такой переменной с расстоянием до БУ сетки ?




bezubytok.mq48 скач.
zero_level_1.mq48 скач.

#3249

Подскажите, как красиво округлить время до минут? Т.е. у меня 16:25:06, хочу 16:25:00

Я сейчас делаю так:


string RoundTime = TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES);
IntervalTime = StringToTime(RoundTime);

Т.е. перевожу время в стринг без секунд, потом обратно во время, но это какое то извращение.
Знаю, что еще через MqlDateTime можно убрать секунды, то тогда код получится километровый из-за структуры дополнительной.

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

Перейти к списку тем
Форум · 2.0.20260627.0025