Ar4i Опубликовано 6 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 декабря, 2023 Здравствуйте! Помогите пожалуйста, найти ошибку по уроку где показывают как писать мартенгейл. Компелируеться без ошибок и предупреждению. Сам пересмотрел урок уже дважды и в голове все плывет. Какие бы параметры не выставлял, выдает плюс- минус одно и тоже. Как на скриншоте, совсем ни как на уроке. Может у кого то, есть свой код с урока //+------------------------------------------------------------------+ //| 4.1.mq4 | //| советники на мартингейле. j | //| https://www | //+------------------------------------------------------------------+ #property copyright "j" #property link "https://www" #property version "1.00" #property strict extern double Lots = 0.01; extern int TakeProfit = 50; extern int Step = 60; extern double multipler = 2; extern int Magic = 123; extern int maPeriod = 14; extern int ma_shift = 0; extern int ma_method = 1; extern int ma_price = 0; int ticket; double tp, price, lastlot; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if( Digits == 3 || Digits == 5) TakeProfit *=10; Step *=10; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double ima_1 = iMA(Symbol(), NULL, maPeriod, ma_shift, ma_method, ma_price, 0); if(CountTrades()==0) { if(Ask > ima_1) { tp=NormalizeDouble(Ask + TakeProfit *Point, Digits); ticket=OrderSend(Symbol(), OP_BUY, Lots, Ask, 10, 0, tp, "", Magic, 0, Blue); } else { tp=NormalizeDouble(Bid - TakeProfit *Point, Digits); ticket=OrderSend(Symbol(), OP_SELL, Lots, Bid, 10, 0, tp, "", Magic, 0, Red); } } else { int order_type = FindLastOrderType(); if(order_type==OP_BUY) { price = FindLastOrderPrice(OP_BUY); if(Ask <= price-Step *_Point) { lastlot=FindLastLots(OP_BUY); lastlot= NormalizeDouble(lastlot *multipler, 2); ticket = OrderSend(Symbol(), OP_BUY, lastlot, Ask, 10, 0, 0, "", Magic, 0, Blue); //TakeProfit пока 0, так как его еще надо будет модифицировать с учетом всех открытых ордеров if(ticket < 1) Print("Ошибка открития ордера на покупку"); ModifyOrders(OP_BUY); } } if(order_type==OP_SELL) { price = FindLastOrderPrice(OP_SELL); if(Bid >= price + Step *Point) { lastlot=FindLastLots(OP_SELL); lastlot= NormalizeDouble(lastlot * multipler, 2); ticket = OrderSend(Symbol(), OP_SELL, lastlot, Bid, 10, 0, 0, "", Magic, 0, Red); if(ticket < 1) Print("Ошибка открытие ордера на продажу"); ModifyOrders(OP_SELL); } } } } // OnTick() //-------------------------------------------------------------1) считаем ордера в рынке int CountTrades() { int count = 0; for(int i= OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) if(OrderType() == OP_BUY || OrderType() == OP_SELL ) count++; } } return(count); } //---------------------------------------------------------------2) Находим тип последнего ордера, BUY или SELL int FindLastOrderType() { for(int i= OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic) return(OrderType()); } } return(-1); } //----------------------------------------------------------3) Находим цену последнего ордера double FindLastOrderPrice(int otype) { int oldticket; double oldopenprice = 0; ticket = 0; for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype) { oldticket = OrderTicket(); if(oldticket > ticket) { ticket = oldticket; oldopenprice = OrderOpenPrice(); }}}} return(oldopenprice); } //--------------------------------------------------4) Находим сколько пунктов прошел последний закрытый ордер double FindLastOrderProfit(int otype) { int oldticket; double oldorderProfit = 0; int bticket = 0; for(int cnt=OrdersTotal(); cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY)) { if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype) { oldticket = OrderTicket(); if(oldticket > bticket) { bticket = oldticket; oldorderProfit = OrderProfit(); }}}} return(oldorderProfit); } //--------------------------------------------------5) Наход объем лота последнего открытого ордера double FindLastLots(int otype) { int oldticket; double oldlots = 0; ticket = 0; for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic && OrderType() == otype) { oldticket = OrderTicket(); if(oldticket > ticket) { ticket = oldticket; oldlots = OrderLots(); }}}} return(oldlots); } //----------------------------------------------6) Модифиция TakeProfit void ModifyOrders(int otipe) { double avg_price, order_lots=0; price = 0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { price += OrderOpenPrice() *OrderLots(); order_lots += OrderLots(); } } } avg_price = NormalizeDouble(price / order_lots, Digits); if(otipe == OP_BUY) tp = NormalizeDouble(avg_price + TakeProfit, Digits); if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit, Digits); for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0)) Print("ордера успешно модифицированы"); else Print("ошибка модификации ордеров"); } } } }//void ModifyOrders //--------------------------------------------------------------- Изменено 6 декабря, 2023 пользователем Ar4i Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 В 06.12.2023 в 17:03, Ar4i сказал: Здравствуйте! Помогите пожалуйста, найти ошибку по уроку где показывают как писать мартенгейл. Компелируеться без ошибок и предупреждению. Сам пересмотрел урок уже дважды и в голове все плывет. Какие бы параметры не выставлял, выдает плюс- минус одно и тоже. Как на скриншоте, совсем ни как на уроке. Может у кого то, есть свой код с урока //+------------------------------------------------------------------+ //| 4.1.mq4 | //| советники на мартингейле. j | //| https://www | //+------------------------------------------------------------------+ #property copyright "j" #property link "https://www" #property version "1.00" #property strict extern double Lots = 0.01; extern int TakeProfit = 50; extern int Step = 60; extern double multipler = 2; extern int Magic = 123; extern int maPeriod = 14; extern int ma_shift = 0; extern int ma_method = 1; extern int ma_price = 0; int ticket; double tp, price, lastlot; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if( Digits == 3 || Digits == 5) TakeProfit *=10; Step *=10; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double ima_1 = iMA(Symbol(), NULL, maPeriod, ma_shift, ma_method, ma_price, 0); if(CountTrades()==0) { if(Ask > ima_1) { tp=NormalizeDouble(Ask + TakeProfit *Point, Digits); ticket=OrderSend(Symbol(), OP_BUY, Lots, Ask, 10, 0, tp, "", Magic, 0, Blue); } else { tp=NormalizeDouble(Bid - TakeProfit *Point, Digits); ticket=OrderSend(Symbol(), OP_SELL, Lots, Bid, 10, 0, tp, "", Magic, 0, Red); } } else { int order_type = FindLastOrderType(); if(order_type==OP_BUY) { price = FindLastOrderPrice(OP_BUY); if(Ask <= price-Step *_Point) { lastlot=FindLastLots(OP_BUY); lastlot= NormalizeDouble(lastlot *multipler, 2); ticket = OrderSend(Symbol(), OP_BUY, lastlot, Ask, 10, 0, 0, "", Magic, 0, Blue); //TakeProfit пока 0, так как его еще надо будет модифицировать с учетом всех открытых ордеров if(ticket < 1) Print("Ошибка открития ордера на покупку"); ModifyOrders(OP_BUY); } } if(order_type==OP_SELL) { price = FindLastOrderPrice(OP_SELL); if(Bid >= price + Step *Point) { lastlot=FindLastLots(OP_SELL); lastlot= NormalizeDouble(lastlot * multipler, 2); ticket = OrderSend(Symbol(), OP_SELL, lastlot, Bid, 10, 0, 0, "", Magic, 0, Red); if(ticket < 1) Print("Ошибка открытие ордера на продажу"); ModifyOrders(OP_SELL); } } } } // OnTick() //-------------------------------------------------------------1) считаем ордера в рынке int CountTrades() { int count = 0; for(int i= OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) if(OrderType() == OP_BUY || OrderType() == OP_SELL ) count++; } } return(count); } //---------------------------------------------------------------2) Находим тип последнего ордера, BUY или SELL int FindLastOrderType() { for(int i= OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic) return(OrderType()); } } return(-1); } //----------------------------------------------------------3) Находим цену последнего ордера double FindLastOrderPrice(int otype) { int oldticket; double oldopenprice = 0; ticket = 0; for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype) { oldticket = OrderTicket(); if(oldticket > ticket) { ticket = oldticket; oldopenprice = OrderOpenPrice(); }}}} return(oldopenprice); } //--------------------------------------------------4) Находим сколько пунктов прошел последний закрытый ордер double FindLastOrderProfit(int otype) { int oldticket; double oldorderProfit = 0; int bticket = 0; for(int cnt=OrdersTotal(); cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY)) { if(OrderSymbol()== Symbol() && OrderMagicNumber() == Magic && OrderType()== otype) { oldticket = OrderTicket(); if(oldticket > bticket) { bticket = oldticket; oldorderProfit = OrderProfit(); }}}} return(oldorderProfit); } //--------------------------------------------------5) Наход объем лота последнего открытого ордера double FindLastLots(int otype) { int oldticket; double oldlots = 0; ticket = 0; for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== OrderSymbol() && OrderMagicNumber() == Magic && OrderType() == otype) { oldticket = OrderTicket(); if(oldticket > ticket) { ticket = oldticket; oldlots = OrderLots(); }}}} return(oldlots); } //----------------------------------------------6) Модифиция TakeProfit void ModifyOrders(int otipe) { double avg_price, order_lots=0; price = 0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { price += OrderOpenPrice() *OrderLots(); order_lots += OrderLots(); } } } avg_price = NormalizeDouble(price / order_lots, Digits); if(otipe == OP_BUY) tp = NormalizeDouble(avg_price + TakeProfit, Digits); if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit, Digits); for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0)) Print("ордера успешно модифицированы"); else Print("ошибка модификации ордеров"); } } } }//void ModifyOrders //--------------------------------------------------------------- В тестере есть журнал, в него имеет смысл заглядывать. В вашем случае не работает модификация ордеров: То есть сетку вы строить продолжаете, но закрывается у вас только первый ордер по тейку. А остальные остаются висеть и счет дохнет, когда их набирается слишком много. Ошибка в функции ModifyOrders: вы забыли умножить TakeProfit (который в пунктах) на величину пункта. Замените текст функции вот та это и будет вам счастье: //----------------------------------------------6) Модифиция TakeProfit void ModifyOrders(int otipe) { double avg_price, order_lots=0; price = 0; for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()== Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { price += OrderOpenPrice() *OrderLots(); order_lots += OrderLots(); } } } avg_price = NormalizeDouble(price / order_lots, Digits); if(otipe == OP_BUY) tp = NormalizeDouble(avg_price + TakeProfit * Point(), Digits); if(otipe == OP_SELL) tp = NormalizeDouble(avg_price - TakeProfit * Point(), Digits); for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==otipe) { if(OrderModify( OrderTicket(), OrderOpenPrice(), 0, tp, 0)) Print("ордера успешно модифицированы"); else Print("ошибка модификации ордеров"); } } } }//void ModifyOrders //--------------------------------------------------------------- А еще мне кажется, что вот такое условие на первый вход будет куда более логичным для простого мартина: Спойлер 3 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Ar4i Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 1 час назад, Rigal сказал: Ошибка в функции ModifyOrders: вы забыли умножить TakeProfit (который в пунктах) на величину пункта. Да, в журнале видел что твориться. Но не знал что с этим делать. Спасибо большое за решение. Так найти такую мелкую ошибку это "мощно" конечно! 1 час назад, Rigal сказал: А еще мне кажется, что вот такое условие на первый вход будет куда более логичным для простого мартина: У меня никак не получалось применить изначальный вариант 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 Ваша версия также не позволит использовать нецелые множители с минимальным лотом: если множитель, например, 1.4 - умножаться не будет совсем. А если 1.5 и больше - первое умножение будет на двойку. Второе уже на 1.5 - но в итоге получится тройка, что не соответствует вашим ожиданиям (1.5 в квадрате - это 2.25). Поправить это довольно просто. Вот, например, код, где я перфекционизма ради выкинул все ненужные поиски и немного модифицировал входы, закинул вторую машку. Нет больше понятия "шаг" (он адаптивный), а "тейк" превратился в "минимальный тейк первого ордера", уж извините. MartinLessonX.mq4 Все нужные нам параметры уже открытой позиции мы собираем в одном цикле. Код не для совсем новичка. Советник закрывает не только в прибыль. Зато легко подбираются настройки, которые пройдут всю историю котировок. Например, я прогнал евродоллар на часе с 2010 случайными настройками: Спойлер Дерзайте 1 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Ar4i Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 Да это интересно что вы сделали. Надо еще посидеть и сам код/механизм понять. Еще к уроку по мартенгейлу было одно из домашних заданий. Добавить внешний параметр MaxOrders и доработать советник таким образом, чтобы он не открывал ордеров больше, чем указано в этой переменной. Это я так понимаю надо писать отдельную функцию, для которой нужен будет либо Стоп-лосс по аналогии с ModifyOrders(где была ошибка). Или считать убыточные ордера. Как думаете что лучше. Мне кажется Стоп-лосс на "вырост" интересней Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 33 минуты назад, Ar4i сказал: Да это интересно что вы сделали. Надо еще посидеть и сам код/механизм понять. Еще к уроку по мартенгейлу было одно из домашних заданий. Добавить внешний параметр MaxOrders и доработать советник таким образом, чтобы он не открывал ордеров больше, чем указано в этой переменной. Это я так понимаю надо писать отдельную функцию, для которой нужен будет либо Стоп-лосс по аналогии с ModifyOrders(где была ошибка). Или считать убыточные ордера. Как думаете что лучше. Мне кажется Стоп-лосс на "вырост" интересней Зачем? У вас уже есть функция, которая считает, сколько ордеров открыто - вы ее в самом начале вызываете, сразу после машки. Если ордеров больше, или равно заданному ограничению - можно просто выходить из OnTick сразу. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Ar4i Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 Вы наверное имеете в виду if(CountTrades()==0) изменить ее допустим на if(CountTrades()<3)..? В идеале я иду к тому что бы например сделать так, что бы каждая сделка открывалась по условию, а закрывалась по стопу или профиту. При этом что был параметр количества минусовых сделок подряд. После числа которых мартингейл начинался бы заново Изменено 7 декабря, 2023 пользователем Ar4i Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 7 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 7 декабря, 2023 56 минут назад, Ar4i сказал: Вы наверное имеете в виду if(CountTrades()==0) изменить ее допустим на if(CountTrades()<3)..? Я имею в виду int countTrades = CountTrades(); if(countTrades >= MaxOrders) return; if(countTrades == 0)... ну и далее по тексту. 58 минут назад, Ar4i сказал: В идеале я иду к тому что бы например сделать так, что бы каждая сделка открывалась по условию, а закрывалась по стопу или профиту. При этом что был параметр количества минусовых сделок подряд. После числа которых мартингейл начинался бы заново Это сильно другая задача. Тоже решаемая, конечно. Много занятностей. Например, сколько сделок у вас будет октрыто одновременно зависит от взаимного отношения величины шага, тейка и стопа. И нужно продумать и выписать, как вы будете обрабатывать набор открытых позиций и те, что закрылись, в профит, или в убыток. Как я уже сказал: дерзайте. Дорогу осилит идущий. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Ar4i Опубликовано 8 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 8 декабря, 2023 А если так? Я вижу что мне нужна одна функция Lot() которую я вставлю прямо в OrderSend. А в этой функции уже будет расчет мартенгейла. То есть если подряд ряд проигрышей(MaxOrders) лот увеличивается. Иначе, если плюс - то лот базовый Изменено 8 декабря, 2023 пользователем Ar4i Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 11 декабря, 2023 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 11 декабря, 2023 В 08.12.2023 в 12:09, Ar4i сказал: А если так? Я вижу что мне нужна одна функция Lot() которую я вставлю прямо в OrderSend. А в этой функции уже будет расчет мартенгейла. То есть если подряд ряд проигрышей(MaxOrders) лот увеличивается. Иначе, если плюс - то лот базовый Вы, возможно, не прочитали. Или пока не поняли. Но вы пробуйте, тестируйте в визуале - станет понятнее. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
diodio Опубликовано 10 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 10 января Всем доброго времени суток! У меня вопрос, 1 терминал, несколько пар, на каждой паре стоит один и тот же советник с разными магиками, мне нужно чтоб у всех этих советников была одна общая переменная которая отвечает за эквити, просадку, счет то один на всех, и там где есть просадка на одной паре но советник не может выставить локировку, другая пара по тому же советнику выставляет локировку и перекрывает в случае профита просадку у той пары где есть просадка. Как это сделать? Пробовал выставить одинаковый магик на всех советниках, но не заметил того что я хотел. Тут конечно нужно сделать еще одну общую переменную которая будет собирать этот локированный профит. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 10 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 10 января 6 часов назад, diodio сказал: Пробовал выставить одинаковый магик на всех советниках, но не заметил того что я хотел А что вы хотели заметить? Есть смысл приводить фрагменты кода. Иначе сложно сориентироваться, чего вы ждете. Ссылка на сообщение Поделиться на другие сайты More sharing options...
neurolynx Опубликовано 12 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 12 января Подскажите, плиз, как перевести своп из валюты в пункты. Допустим, на фунте у меня стоит тейк на бай на 1.27618. При этом накопился своп, например, -245. Это на центовом счете. И я бы хотела пересчитать тейк, увеличив его на сумму свопа. Вот как перевести сумму свопа в нужные пункты? )) На этом конкретном примере. Заранее извиняюсь за дилетантство. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 12 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 12 января 11 часов назад, neurolynx сказал: Подскажите, плиз, как перевести своп из валюты в пункты. Допустим, на фунте у меня стоит тейк на бай на 1.27618. При этом накопился своп, например, -245. Это на центовом счете. И я бы хотела пересчитать тейк, увеличив его на сумму свопа. Вот как перевести сумму свопа в нужные пункты? )) На этом конкретном примере. Заранее извиняюсь за дилетантство. У пункта есть цена: double tickvalue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE); Такую прибыль сделка объемом один лот приносит на пробег длиной TickSize (как правило Point(), но лучше опереться на настоящую величину SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE); Соответственно, вам нужно подвинуть тейк на double delta = -OrderSwap() / SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) / OrderLots() * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE); double new_tp = NormalizeDouble(OrderTakeProfit() + delta, Digits); 1 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
neurolynx Опубликовано 12 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 12 января 8 часов назад, Rigal сказал: double delta = -OrderSwap() / SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) / OrderLots() * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE); double new_tp = NormalizeDouble(OrderTakeProfit() + delta, Digits); Спасибо огромное, я чем больше читала об этом вопросе, тем больше запутывалась. Теперь стало понятно. Ну... и раз уж вы отвечаете... Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line. Вы не могли бы помочь с этим кусочком кода? Я нашла в интернете несколько вариантов (еще не пробовала), но они все очень громоздкие, там много лишнего, сделанного на всякий случай. Изменено 13 января пользователем neurolynx Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 13 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 13 января 13 часов назад, neurolynx сказал: Спасибо огромное, я чем больше читала об этом вопросе, тем больше запутывалась. Теперь стало понятно. Ну... и раз уж вы отвечаете... Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line. Вы не могли бы помочь с этим кусочком кода? Я нашла в интернете несколько вариантов (еще не пробовала), но они все очень громоздкие, там много лишнего, сделанного на всякий случай. В этой задаче двумя строчками не обойдешься. Я поэтому накидал пример советника, который: При инициализации создает три объекта линий: покупки, продажи, полная совокупность. Есть стандартная библиотека в метатрейдере, ChartObjects/ChartObjectsLines.mqh - сильно упрощает работу с линиями. В той же папочке куча оберток для других графических объектов, можно покопаться. К сожалению, документировано оно неидеально При де-инициализации он их удалит с графика Реализован один метод, который посчитает безубыток покупок, продаж и общий. Если нет покупок - линия спрячется (убираем ее на уровень цены 0.0) То же самое для продаж Общий безубыток рисуется только если есть и покупки и продажи и их вес отличается (если он равен - это хедж и у нас нет точки, где вся позиция выйдет в безубыток: куда бы ни пошла цена - нам становится только хуже от копящихся свопов). В противном случае тоже прячем в ноль Метод принимает магик в качестве аргумента, по умолчанию -1. Если передать магик - посчитает только для позиций с этим магиком. Я там немного накомментировал по тексту. Например, формулы для расчета безубытка явно пометил. Все считается с учетом свопов и комиссий. Занятное оказалось упражнение. Я все это уже года три назад реализовал в библиотеки и забыл довольно прочно ChartLineSandbox.mq4 Изменено 13 января пользователем Rigal 1 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
neurolynx Опубликовано 14 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 14 января 12 часов назад, Rigal сказал: В этой задаче двумя строчками не обойдешься. Спасибо большое, буду со старанием вникать. Хотя выражения типа "double profit[2] = {0.0, 0.0}" для меня за гранью пока что. Квадратные скобочки - это я вообще в первый раз встречаю в коде )) Гугл говорит, что это для индексации массивов. Ух! Я программирование изучала с полного нуля сугубо по урокам этого форума, думала, что этого хватит )) Спасибо вам огромное еще раз! Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 14 января 13 часов назад, neurolynx сказал: Спасибо большое, буду со старанием вникать. Хотя выражения типа "double profit[2] = {0.0, 0.0}" для меня за гранью пока что. Квадратные скобочки - это я вообще в первый раз встречаю в коде )) Гугл говорит, что это для индексации массивов. Ух! Я программирование изучала с полного нуля сугубо по урокам этого форума, думала, что этого хватит )) Спасибо вам огромное еще раз! Если опереться вот прямо на тот вопрос, что вы исходно задали, вот на этот: В 12.01.2024 в 23:48, neurolynx сказал: Мне бы хотелось сделать визуальную линию безубытка, как у вас в Ступидо - золотую двойную )) Безубыток у меня посчитан и назван, допустим для наглядности, golden line То код будет выглядеть гораздо проще: #include <ChartObjects/ChartObjectsLines.mqh> CChartObjectHLine breakEvenTotalLine; int OnInit() { /* что там у вас уже в OnInit */ breakEvenTotalLine.Create(0, "BreakevenTotalLine", 0, 0.0); breakEvenTotalLine.Width(2); breakEvenTotalLine.Color(clrGold); breakEvenTotalLine.Description("Total breakeven"); } void OnDeinit(const int reason){ /* что там у вас уже в OnDeinit */ breakEvenTotalLine.Delete(); } void OnTick() { /* что там у вас уже в OnTick */ breakEvenTotalLine.Price(0, goldenLine); //вот тут мы передвигаем линию в посчитанную позицию goldenLine } Что касается массивов в моем коде: я просто считаю нужные мне величины для покупок и продаж за один цикл перебора по ордерам. В этом здорово помогает тот факт, что константа типа ордера покупок (OP_BUY) равна нулю, а продаж - единице. То есть мы можем просто завести переменную в виде массива из двух элементов и обращаться к "покупковой" и "продажной" части просто по типу ордера. Скажем, мне нужно посчитать плавающую прибыль по покупкам и продажам раздельно, а также общую. Это можно завести две разных переменных, profitBuy и profitSell, а внутри цикла делать if(OrderType() == OP_BUY) profitBuy += OrderProfit(); else profitSell += OrderProfit(); Или сделать, как я: завели массив profit из двух элементов. Нулевой - покупки, первый - продажи. И тогда profit[OrderType()] += OrderProfit(); Компактнее и меньше шансов на ошибку, особенно в более сложных конструкциях. если уложить эту технику в голове, то дальше из нее вырастает множество красивых конструкций-сверток. Например, объявим массив "знака": int sgn[2] = {1, -1}; Теперь, чтобы выставить тейк у открытого ордера на расстояние tp от цены открытия, можно написать: OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), NormalizeDouble(OrderOpenPrice() + sgn[OrderType()] * tp, Digits)); И мы получим тейк для покупок на tp выше цены открытия, а для продаж - ниже или, например, проверить пересечение машки ценой... Скажем, мы хотим для продаж поймать момент, когда цена пересекает машку снизу вверх, а для покупок - сверху вниз (ну просто для примера). Предположим, закрытие последнего бара у нас в переменной close, а машка в переменной ma. И вот мы выбираем некий ордер и в типичном подходе мы напишем: if(OrderType() == OP_BUY) { if(close < ma) Print("MA Crossed"); } else { if(close > ma) Print("MA Crossed"); } Используя трюк с sgn[OrderType()] это можно свернуть вот в такую простенькую проверку if(sgn[OrderType()] * (ma - close) > 0) Print("MA Crossed"); Для покупок выполнится только если ma > close, для продаж - только если close > ma 1 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
neurolynx Опубликовано 14 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 14 января 8 часов назад, Rigal сказал: Если опереться вот прямо на тот вопрос, что вы исходно задали, вот на этот То код будет выглядеть гораздо проще Большущее спасибо за упрощение )) Вникать было долго, а безубыток хочется видеть "прям счас". Кроме шуток, вы не думали написать руководство по mql? Для чайников, желательно )) 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 15 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 15 января 13 часов назад, neurolynx сказал: Кроме шуток, вы не думали написать руководство по mql? Для чайников, желательно ) Нет, спасибо. Много времени, и чукча больше читатель. Я сдуюсь на первой главе. Ну и программирование на mql от программирования на, например, С++, отличается довольно небогатым API метатрейдера. Все остальное уже написано для чайников для множества языков программирования. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
estebaanm98 Опубликовано 29 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 29 января В 15/4/2021 в 12:21, Lexa000 сказал: Locomotora v1.01 (7).mq4 56,99\u043a\u0411 · 11 descargas Necesito colocar una cabina en la locomotora, pero estoy confundido. ¿Alguien puede decirme cómo hacer esto más fácilmente? ¿Debo crear una regla separada o cómo debo escribir variables? EA - Budak Ubat v1.51.mq4 44.16\u043a\u0411 · 18 descargas Do you have v1.62 mql4? Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 29 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 29 января 2 часа назад, estebaanm98 сказал: У вас есть v1.62 mql4? Locomotive v1.01 (02).mq4 Эти проще Советник a1.01.mq4 Ссылка на сообщение Поделиться на другие сайты More sharing options...
estebaanm98 Опубликовано 29 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 29 января 20 минут назад, Lexa000 сказал: Locomotora v1.01 (02).mq4 45.1\u043a\u0411 · 0 descargas estos son mas faciles Asesor a1.01.mq4 69.59\u043a\u0411 · 0 descargas Easier in what sense? Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 30 января Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 30 января 22 часа назад, estebaanm98 сказал: Easier in what sense? MarketInsider_v1.2.ex4 Для этого индикатора нужна регистрация на сайте продавца, без регистрации советник торговать не будет Ссылка на сообщение Поделиться на другие сайты More sharing options...
mishastar Опубликовано 9 мая Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 9 мая Доброго дня! Может кто научить как реализовать возможность управление советником с одного терминала - советником второго терминала??? Или кто то встречал подобную реализацию или подскажите где копать. Суть такая. На одном терминале первый советник строит сетку ордеров. Когда советник открывает например шестую сделку, то он должен отправить команду другому советнику стоящему на другом счете, другом терминале, о том что можно открывать первую сделку по той же паре. Классический копировальщик тут как то не подошел.. Любая информация во благо!!! Ссылка на сообщение Поделиться на другие сайты More sharing options...
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти