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

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

#4651

Спасибо за предложения /замечания

1) SetChart что-то очень жестокое - после применения скрипта на нескольких парах терминал пересобирать надо будет.
И/или профиль сохранять надо и потом восстанавливать. Народ напрочь запутается по любому, будет забывать и будет ругань.
намного проще делать фон под шрифтом при выводе инфы.
Гляньте как организован вывод в скрипте AccountInfo - выводится непрозрачное окошко с текстом поверх всего, глянули, закрыли и забыли, ничего не затирается/обнуляется.




Фон рисовать можно, но, если не путаю, бары не закрываются... Попробую, но точно не проще- если геометрию инфо-блоков можно вычислить, то при изменении размера шрифта будет не очень красиво... Но можно за красотой не гнаться..
Или поставлять в комплекте со скриптом шаблон...
Что касается AccountInfo, то там MessageBox, для его применения надо весь код вывода переделывать.. Честно говоря-лень.

Добавлено: 06-07-2017 19:34:47

Добрый вечер.
Очередная версия.
Изменения:
1.отказался от формата "индикатор" в пользу "скрипта". На живом рынке терминал тормозит на индикаторе сильно...
2. Набор данных и их компоновка по рекомендации

Предложения есть следующие:


3. Формируется файл csv. Лежит в папке Terminal\MQL4\Files\.
4. Если анализ интрадей не используется, то лишние блоки не выводятся.

Завершающим этапом (возможно завтра) будет формирование экранного отчета на основе MessageBox. Старик, как обычно, оказался прав.
п.с. Молчание скачавших индикатор означает, что в нем нет ошибки или никто их не искал?

AverageStatistic_1.3scr.mq45 скач.

Изменено 6 июля, 2017 пользователем usver73

#4652

как измерить в пунктах расстояние от , например Ma, до текущей цены?


и для исключения потери данных надо применять функцию NormalizeDouble():
punkt = MathAbs(NormalizeDouble( Ask - iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0 ) ) / Point,4);
#4653


как измерить в пунктах расстояние от , например Ma, до текущей цены?


и для исключения потери данных надо применять функцию NormalizeDouble():
punkt = MathAbs(NormalizeDouble( Ask - iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0 ) ) / Point,4);
Вы ни чего не напутали? проверьте ещё раз.
#4654

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

Elliott_Waves.mq46 скач.
bw_ve_2.gif

#4655

апсалютно


*абсолютно...
У меня вообще ничего не отображается, кроме названия индикатора...
#4656

Свежий урок:
http://tradelikeapro.ru/mql4-skleivaem-tikovyie-faylyi/

#4657

это потому что вы не умеете им пользоваться.....это скорее скрипт в оболочке индюка.....все построения делаются в ручную....на маркете есть подробное описание.....Вы рисуете любую трендовую линию по фракталам и называете ее "1*****" например: "1 волна", при первом тике, или чтоб не дожидаться тика, правой кнопкой мыши делаете обновление. Получаете картину что в первом сообщении

Изменено 7 июля, 2017 пользователем John222

#4658

Посмотрел видео урок Сергея aka xbms (написание советника на внешним индикаторе TMA) данный урок мне очень понравился. Я только изучаю MQL4 вот решил воплотить увиденное. Сколько не сторговался советник открывает кучу позиций, хотя по стратегии должен открывать одну позицию одну позицию от одного уровня и закрывать её у другого уровня. После компиляции ошибок нет.
Если можно помогите разобраться.
Вот сам код:

//+------------------------------------------------------------------+
//| Test advisor on TMA_Fair.mq4 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link
#property version "1.00"
#property strict

//------------------параметры советника -------------------------------
extern double lots = 0.01; //
extern int TakeProfit=60; //
extern int StopLoss=100; //
extern int Magic=111111111;
extern int Slippage=3;

//------- Внешние параметры индикатора -------------------------------
extern string TimeFrame = "current time frame";
extern int HalfLength = 56;
extern int Price = PRICE_CLOSE;
extern double ATRMultiplier = 2.0;
extern int ATRPeriod = 100;
extern bool Interpolate = true;
//------- Внешние параметры индикатора -------------------------------
double PRICE_HIGH,PRICE_LOW,SL,TP;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(Digits==3 || Digits==5)
{
TakeProfit *=10;
StopLoss *=10;
Slippage *=10;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
PRICE_HIGH= iCustom(NULL,0,"TMA_Fair",TimeFrame,HalfLength,Price,ATRMultiplier,ATRPeriod,Interpolate,1,0);
PRICE_LOW = iCustom(NULL,0,"TMA_Fair",TimeFrame,HalfLength,Price,ATRMultiplier,ATRPeriod,Interpolate,2,0);

if(Bid>=PRICE_HIGH && CountSell()==0)//
{
SL = NormalizeDouble(Bid+StopLoss*Point, Digits);
TP = NormalizeDouble(Bid-TakeProfit*Point, Digits);

{
ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,Slippage,0,0,"TMA_Fair робот",Magic,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
if(!OrderModify(ticket,OrderOpenPrice(),SL,TP,0)== true)
Print("Ошибка модификации ордера на продажу!");
}
}
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
if(Ask {
TP = NormalizeDouble(Ask+TakeProfit*Point, Digits);
SL = NormalizeDouble(Ask-StopLoss*Point, Digits);

ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,Slippage,0,0,"TMA_Fair робот",Magic,0,Blue);
if(ticket>0)
{

if(OrderSelect(ticket,SELECT_BY_TICKET))
if(!OrderModify(ticket,OrderOpenPrice(),SL,TP,0)== true)
Print("Ошибка модификации ордера на покупку!");
}
}
//+------------------------------------------------------------------+
if(Ask0)
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)== true)
{
if(OrderMagicNumber()==Magic && OrderType()==OP_SELL)
if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Black))
Print("Ошибка открытия ордера на продажу!");
}
}
}

//+------------------------------------------------------------------+

if(Bid>=PRICE_HIGH && CountBuy()>0)
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber()==Magic && OrderType()==OP_BUY)
if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Black))
Print("Ошибка открытия ордера на покупку !");
}
}
}
}
//+------------------------------------------------------------------+
int CountSell()//проверкна открытие ордеров на продажу
{
int count=0;

for(int trade=OrdersTotal()-1; trade>=0; trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_SELL)
{
if(OrderType()==OP_SELL)
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
int CountBuy()// проверкна открытие ордеров на покупку
{
int count=0;

for(int trade=OrdersTotal()-1; trade>=0; trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_BUY)
{
if(OrderType()==OP_BUY)
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+

Test_advisor_on_TMA_Fair.ex40 скач.

#4659

и для исключения потери данных надо применять функцию NormalizeDouble():
punkt = MathAbs(NormalizeDouble( Ask - iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0 ) ) / Point,4);
Вы ни чего не напутали? проверьте ещё раз.


Я не есть великий программист, но компилятор снял предупреждение.
#4660


и для исключения потери данных надо применять функцию NormalizeDouble():
punkt = MathAbs(NormalizeDouble( Ask - iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0 ) ) / Point,4);
Вы ни чего не напутали? проверьте ещё раз.

Я не есть великий программист, но компилятор снял предупреждение.
Я поясню: когда делят на Point, то хотят получить целое количество пунктов. Т.е. если punkt это переменная типа int:
int punkt = (int)( MathAbs( Ask - iMA( ... )) / Point ); // где (int) - приведение типа double -> int.

ПС: NormalizeDouble() не для исключения потери данных, а для необходимой потери точности для цен в рыночных операциях. ;)
#4661

Здравствуйте уважаемые! Есть такая функция:
double FindLastSellPrice()
{
int oldticket, ticket = 0;
double oldopenprice = 0;

for (int cnt = OrdersTotal()-1; cnt>=0; cnt--)
{
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
{
oldticket = OrderTicket();
if (oldticket > ticket)
{
ticket = oldticket;
oldopenprice = OrderOpenPrice();
}
}
}
}
return(oldopenprice);
}
вычисления цены последнего открытого ордера. По моему через нее можно вычислить цену и первого, или там пятого открытого ордера . Как в анекдоте, блин: - сколько будет 0.5 и 0.5? "Нутром чувствую, что литр, а математически выразить не могу." Подскажите пожалуйста, КАК???

#4662

Цена первого ордера:
oldticket = OrderTicket();
if (oldticket {
ticket = oldticket;
oldopenprice = OrderOpenPrice();
}
Для 5 или любого другого лучше делать массив, сортировать его по тикету или времени открытия и смотреть параметры 5 ордера (при наличии).
Только для чего это? Имейте ввиду, что у брокеров становится модно частичное открытие - это когда вместо 1 ордера реально открываются 2, 3 шт. Для сетки лучше вычислять цену безубытка, имхо.

#4663

Коллега usver73, забыл попросить вас добавить вывод одной строки с инфой:
1) хай за анализируемый период (цена)
2) лоу за анализируемый период (цена)
3) хай-лоу в 4-х значных пипсах.
В процессе считывания свечей отследите экстремумы за период - инфа может оказаться весьма полезной!

И, наверно, выложите уже последнюю версию скрипта в топике Сетки - пусть люди пощупают и проверят, там это быстрее происходить будет.

#4664

Здравствуйте. Если найдется свободное время, не откажите в помощи.
Нужно перевести стандартный volumes из indicator_separate_window в indicator_chart_window.
Просто вместо подвала, вертикальные линии на графике.
p.s. И если можно, то выведите в настройки ограничение истории...

Volumes.mq43 скач.

Изменено 9 июля, 2017 пользователем Strong-Tezis

#4665

« Ответ #3802 : Июль 08, 2017, 04:49:05 pm »


Большое спасибо, О||! Как неожиданно просто, но для меня не совсем, т. к. надо еще прописать алгоритм перепада цен между первым и последним открытыми ордерами, чтобы задавать общий профит (ор) в сеточнике не с потолка (30, 50), а в соответствии с этой величиной. Спасибо еще раз!!!
#4666
Старик, учту Ваши пожелания, но я уже задолбался с реализацией вывода в MessageBox. Проблема в том, что в нем нельзя управлять шрифтом, а для стройного вывода информации необходим моноширный шрифт...
Хочу попробовать все-таки индикатор, но с одним проходом и кнопочкой, удаляющей всю информацию..
Может ГУРУ MQL подскажут правильный подход?

Добавлено: 09-07-2017 16:47:34

MessageBox я так и не победил :(
В итоге остановился на реализации как индикатора. Чтобы не грузил систему, расчет делается один раз, затем только проверка нажатия кнопки выгрузки индикатора (надо проверять на демо-счете, т.к. функция удаления индикатора не работает в тестере).
Настройки чарта (графика) - минимальные- только график убирается вниз...
Из настроек убраны параметры, связанные с размерами панели. Собственно, осталось 4 параметра:

BeginDateCalc = D'2017.01.01';
EndDateCalc = D'2017.06.30 23:59:59';
"ИНТРАДЕЙ ПЕРИОДЫ";
IDbegin =0;//Интрадей начало периода
IDlenth =2;//Интрадей продолжительность периода.


Прошу проверить работу с временнЫми параметрами, мог ошибиться.

AverageStatistic_1.6ind.mq420 скач.
1.6_screen.png

Изменено 9 июля, 2017 пользователем usver73

#4667

А почему EXE-шник выложили?

#4668
Viktor M. повторюсь: для сетки важна "геометрия" - если мульт сетки будет высокий, то БУ сетки будет близок к цене и ТП от последнего ордера можно задать меньше и наоборот, т.е. ТП математически связан с мультом и шагом сетки.
Если один из ордеров сетки скользнёт при открытии? - то задание жёсткого ТП может привести к убыткам...
Так что советую копать в сторону вычисления БУ сетки.
#4669

Всё скинул исходник.

Test_advisor_on_TMA_Fair.mq45 скач.

#4670


Всё скинул исходник.


А еще надо было индюк, коль скоро он в советнике применяется... Нашел, но может быть "кривой", т. к. со второго раза угадал..
Теперь по советнику: у меня отрывает по одному ордеру, как и задумано.
Единственное, идет проверка на положение цены ВНЕ канала. Но если идет жесткий тренд, то после закрытия ордера по стопу, тут же открывается в том же направлении. ИМХО, это не логично...
И в функциях подсчета ордеров БАЙ и СЕЛЛ зачем-то дважды проверяете
OrderType()==OP_SELL  OrderType()==OP_BUY
#4671

Я по юзал по чатам и понял, что сам индикатор индикатор сне обязателен (но, я понял свой косяк). Люди которые хотят мне помочь, должны видеть основу. Индюк прилагаю.

"И в функциях подсчета ордеров БАЙ и СЕЛЛ зачем-то дважды проверяете"

Я думал, что так надо. Но, я только учусь, так что могу что то не увидеть в структуре кода. Буду очень благодарен, если положите "выкинуть" то, что не нужно.

"Но если идет жесткий тренд, то после закрытия ордера по стопу, тут же открывается в том же направлении. ИМХО, это не логично..."

Я согласен с Вами. Думаю, следующим этапом, дописать условия в данный код советника. В тоже время, если цена идет по жесткому тренду, то думаю без треллинга не обойтись. Но это уже надо данный советник полностью переделывать. Так что думаю, этот робот надо будет "подогнать" на определённые пары валют.

TMA_Fair.mq44 скач.

Изменено 9 июля, 2017 пользователем gosha342

#4672

Я по юзал по чатам и понял, что сам индикатор индикатор сне обязателен (но, я понял свой косяк). Люди которые хотят мне помочь, должны видеть основу. Индюк прилагаю.


Доброе утро. Индикатор не нужен, если его код вшит в советник. В Вашем случае предполагается, что он лежит в папке с индикаторами. Попробуйте его как-нибудь переименовать- советник будет строчить ошибки... Индюк я нашел..
Кстати, Ваш индюк как раз кривой... Я брал отсюда, по крайней мере компилируется без ошибок (за логику не скажу) /indikatory/7/indikator-trenda-tmafair-tma-bez-pererisovki/6599/?do=findComment&comment=268199
Еще у Вас каша со {} в строках 57-70
          if(Bid>=PRICE_HIGH && CountSell()==0)// 
{
SL = NormalizeDouble(Bid+StopLoss*Point, Digits);
TP = NormalizeDouble(Bid-TakeProfit*Point, Digits);

{
ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,Slippage,0,0,"TMA_Fair робот",Magic,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
if(!OrderModify(ticket,OrderOpenPrice(),SL,TP,0)== true)
Print("Ошибка модификации ордера на продажу!");
}
}
}

Поправил, во вложении

tma.png
Test_advisor_on_TMA_Fair_1.mq41 скач.

Изменено 10 июля, 2017 пользователем usver73

#4673

Добрый день.
Подскажите пожалуйста, если возможность, чтобы робот менял "мейжик" каждый новый день?И как это реализовать в коде?

#4674

Подскажите пожалуйста, если возможность, чтобы робот менял "мейжик" каждый новый день?И как это реализовать в коде?

Прибавляйте номер дня в году DayOfYear() к некому магику, и всё. Только зачем это?
#4675

Oll, здравствуйте! Все мои знания(если ЭТО можно так назвать) основаны на видеокурсе, который дает xbmc. Изложение материала очень хорошее, и доходчиво, но маловато. Такие понятия как мульт сетки и БУ сетки не попадались. Если не сложно, черкните алгоритм вычисления БУ сетки - может сумею вмонтировать в советник. Сравню со своими изысканиями - отпишусь.

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

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