Форум » Консультации по программированию » Помогите еще раз дорогой мастер?! » Ответить

Помогите еще раз дорогой мастер?!

Husanboy: Добрый день уважаемый Игорь! Я еще к вам по просьбу. Короче, есть индикатор корреляции и его коде использован формулу типа FastMA - SlowMA, но я хотел изменить его на FastMA / SlowMA. Сам попробовал но ни как не получилось(в принципе похоже элементарно легкий но у меня не получилось). Пожалуйста, покажите как заменит формулу?! Вот индикатор: http://file.qip.ru/arch/ZHX5cSTK/Correlations.html или http://qclk.ru/kF/Rm2b

Ответов - 61, стр: 1 2 3 4 5 All

Scriptong: Во-первых, в индикаторе не предусмотрена проверка на элементарные ошибки - деление на ноль. В итоге при запуске, когда не открыты соответствующие графики, индикатор завершается аварийно. Для предотвращения ошибки необходимо переписать код в блоке, следующем после if(ModeXPrice) так: double denom1 = iClose(Symbol1Name,0,1); double denom2 = iClose(Symbol2Name,0,1); double denom3 = iClose(Symbol3Name,0,1); if (denom1 == 0 || denom2 == 0 || denom3 == 0) return (0); kPrice1=1/denom1*iClose(Symbol1Name,0,1); kPrice2=1/denom2*iClose(Symbol1Name,0,1); kPrice3=1/denom3*iClose(Symbol1Name,0,1); Во-вторых, сами данные индикатор выдает очень неоднозначно, т. к. коэффициент "корреляции" между парами вычисляется на основании последней известной свечи каждого из символов. Получаем, что показания индикатора будут зависеть от момента его первого запуска. Так, запустив его в один момент времени, получим одну картину, в другой момент времени - другую. Причем в процессе работы индикатор изменять свои исторические показания не будет. Это очень странный алгоритм. Для изменения формулы необходимо знак "-" при МА заменить на знак "/". Только не забыть перед этим осуществить проверку деления на ноль следующим образом: double ma1 = iMA(Symbol1Name,Period(),MASlow,0,MAMethod,MAPrice,i); double ma2 = iMA(Symbol2Name,Period(),MASlow,0,MAMethod,MAPrice,i); double ma3 = iMA(Symbol3Name,Period(),MASlow,0,MAMethod,MAPrice,i); if (ma1 == 0 || ma2 == 0 || ma3 == 0) continue; Этот код нужно вставить сразу в начале цикла. Задуманное изменение формулы ни к чему хорошему не приведет. На экране будут отображены лишь горизонтальные линии, т. к. величина значений разных линий отличается на порядки.

Husanboy: Scriptong пишет: Спасибо большое, очень понятно и ясно!!!

Scriptong: Пожалуйста. Обращайтесь.


Husanboy: Scriptong пишет: Пожалуйста. Обращайтесь. Добрый вечер мой дорогой преподаватель! Еще к вам по просьбами обращаю. Пробовал написать советник работающие по мартингейлу, но не получилось корректировать порядочности открывание ордеры. Правила стратегии советника такого: Откроется 1 ордер на продажу с SL 10 и TP 10 пункта. Если сработал TP, тогда повторяется первый шаг. Если сработал SL, тогда откроем противоположный ордер(покупка) с SL 20 и TP 20 пунктам. Если сработал опять SL, теперь откроем тоже противоположный ордер(продажа) с SL 30 и TP 30 пунктам. Этот цикл продолжается до срабатывание TP и потом повторяется первый шаг. Здесь проблема только с открывание противоположный ордеры после стоп лосса и повторение первый шаг после тейкпрофита. Пожалуйста, помогите с кодом?! Заранее спасибо большое!!! Вот и сам советник: http://qclk.ru/k6/57gs или http://file.qip.ru/arch/ZxPS-Tfc/EA.html

Scriptong: Добрый вечер. В Вашем коде есть такие замечательные функции, как FindLastHistoryOrderParameter и ей подобные. Но тем не менее, в коде Вы повторяете их функционал. Зачем? Всего то нужно: 1. Определить величину профита последнего ордера в истории. Это лучше сделать через тикет: int lastTicket = FindLastHistoryOrderParameter(MAGIC_NUM, "ticket"); if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) return 0; 2. Если профит положительный, то открыть ордер с SL 10 и TP 10. if (OrderProfit > 0) { OrderSend(Symbol(), <тип ордера>, FixedLots, Bid, Slippage* PipValue, <10 пп. стопа>, <10 пп. профита>, NameEA + CurTime(),MAGIC_NUM, 0, Red); } 3. Если профит отрицательный, то посмотреть, какой размер профита/стопа был у последнего закрытого ордера. К этой величине добавить 10 и открыть новый ордер. else { double slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point; double tpSize = slSize; Sloss = Bid <или Ask> + <или -> slSize; Tprof = Bid <или Ask> + <или -> tpSize; OrderSend(...); } Вот и все.

Husanboy: Спасибо большое, но почему то не работает?! Там проблема не с ТП или СЛ, а открытие противоположный ордеры по очереди(если сработал СЛ продажу тогда открываем покупку). Сделал так: //----------------------------------------------------------------------------------------------------------------------------// int lastTicket = FindLastHistoryOrderParameter(MAGIC_NUM, "ticket"); if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) return 0; if (OrderProfit() > 0 && StartWithBuy ) { if(StopLoss == 0){Sloss = 0;} else{ Sloss = Ask - 10* PipValue * Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Bid + 10* PipValue * Point;} int Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying");OrderTime=Time[0]; } else if(OrderType()==OP_BUY) { double slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; double tpSize = slSize; Sloss = Bid + slSize; Tprof = Ask - tpSize; Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); } if (OrderProfit() > 0 && StartWithSell ) { if(StopLoss == 0){Sloss = 0;}else{ Sloss = Bid + 10 * PipValue* Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Ask - 10 * PipValue* Point;} Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Bid, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Red); prtAlert("Selling");OrderTime=Time[0]; } else if(OrderType()==OP_BUY) { slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; tpSize = slSize; Sloss = Ask - slSize; Tprof = Bid + tpSize; Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); }

Scriptong: Husanboy пишет: Там проблема не с ТП или СЛ, а открытие противоположный ордеры по очереди(если сработал СЛ продажу тогда открываем покупку). Вместе с проверкой прибыльности Вы зачем-то проверяете значение параметра StartWithBuy. Для какой цели? Ведь нужно проверять тип закрытого ордера, и открывать противоположный ему: if (OrderProfit > 0) { if (StartWithBuy) { // открыть Buy с профитом/стопом 10 } else { // открыть Sell с профитом/стопом 10 } } else { if (OrderType() == OP_BUY) { // открыть Sell с увеличенными профитом/стопом } else { // открыть Buy с увеличенными профитом/стопом } }

Husanboy: Scriptong пишет: Вместе с проверкой прибыльности Вы зачем-то проверяете значение параметра StartWithBuy. Для какой цели? Ведь нужно проверять тип закрытого ордера, и открывать противоположный ему: цитата: if (OrderProfit > 0) { if (StartWithBuy) { // открыть Buy с профитом/стопом 10 } else { // открыть Sell с профитом/стопом 10 } } else { if (OrderType() == OP_BUY) { // открыть Sell с увеличенными профитом/стопом } else { // открыть Buy с увеличенными профитом/стопом } } Извиняюсь?! Опять не получилось(не откроется ни какого ордера)! //----------------------------------------------------------------------------------------------------------------------------// int lastTicket = FindLastHistoryOrderParameter(MAGIC_NUM, "ticket"); if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) { if (OrderProfit() > 0 ) { if(StartWithBuy) { if(StopLoss == 0){Sloss = 0;} else{ Sloss = Ask - 10* PipValue * Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Bid + 10* PipValue * Point;} int Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying");OrderTime=Time[0]; } else { if(StopLoss == 0){Sloss = 0;}else{ Sloss = Bid + 10 * PipValue* Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Ask - 10 * PipValue* Point;} Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Bid, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Red); prtAlert("Selling");OrderTime=Time[0]; } } else { if (OrderType() == OP_BUY) { double slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; double tpSize = slSize; Sloss = Bid + slSize; Tprof = Ask - tpSize; Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); } else { slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; tpSize = slSize; Sloss = Ask - slSize; Tprof = Bid + tpSize; Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); } } } //===================================================================================================// Для легкости понимание удаляем из кода StartWithBuy. Теперь начнем с началу: - Сразу после запуск советника откроем одна ордер на покупку(Buy) с 10п ТП и СЛ; - Если сработал ТП тогда откроем ордер на покупка(Buy) тоже с 10п ТП и СЛ(то есть каждый раз после срабатывание ТП повторяется первый шаг); - Если сработал СЛ тогда откроем противоположный ордер то есть продажу(Sell) с 20п(удвоенным) ТП и СЛ; - Если опять сработал СЛ, теперь тоже откроем противоположный ордер(Buy) с удвоенным ТП и СЛ; - Если теперь сработал ТП тогда повторяется первый шаг(не зависимо на типу последного ордера откроем ордер на покупку с начальном ТП и СЛ); Пожалуйста, еще раз помогите с кодам?!

Scriptong: Husanboy пишет: Извиняюсь?! Опять не получилось(не откроется ни какого ордера)! Конечно, не откроется. Откроется только в том случае, если не получилось выбрать ордер. Именно такое условие Вы поставили в начало блока: if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) Читается так: если НЕ удалось выбрать ордер с тикетом lastTicket, то выполнить следующее. Там, где я в примерах использовал такую конструкцию, после условия следовал оператор: return (0); то есть выход из обработки тика. Таким образом, Вам нужно обрабатывать ситуацию, когда выбран ордер.

Husanboy: Scriptong пишет: Конечно, не откроется. Откроется только в том случае, если не получилось выбрать ордер. Именно такое условие Вы поставили в начало блока: цитата: if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) Читается так: если НЕ удалось выбрать ордер с тикетом lastTicket, то выполнить следующее. Там, где я в примерах использовал такую конструкцию, после условия следовал оператор: цитата: return (0); то есть выход из обработки тика. Таким образом, Вам нужно обрабатывать ситуацию, когда выбран ордер. Да сначала поставил это как вы написали(if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) return 0; ), но все равно не открылся ордер и потом удалял эту из кода и опять не работал. Вот сделал так, но все равно не работает: int lastTicket = FindLastHistoryOrderParameter(MAGIC_NUM, "ticket"); if (!OrderSelect(lastTicket, SELECT_BY_TICKET)) return (0); if(OrderProfit() > 0) { if(StartWithBuy) { if(StopLoss == 0){Sloss = 0;} else{ Sloss = Ask - 10* PipValue * Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Bid + 10* PipValue * Point;} int Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying");OrderTime=Time[0]; } else { if(StopLoss == 0){Sloss = 0;}else{ Sloss = Bid + 10 * PipValue* Point;} if(TakeProfit == 0){Tprof = 0;}else{ Tprof = Ask - 10 * PipValue* Point;} Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Bid, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Red); prtAlert("Selling");OrderTime=Time[0]; } } else if ( OrderType() == OP_BUY) { double slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; double tpSize = slSize; Sloss = Bid + slSize; Tprof = Ask - tpSize; Tiket= OrderSend(Symbol(), OP_SELL, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); } else { slSize = MathAbs(OrderStopLoss() - OrderOpenPrice()) + 10 * Point* PipValue; tpSize = slSize; Sloss = Ask - slSize; Tprof = Bid + tpSize; Tiket= OrderSend(Symbol(), OP_BUY, FixedLots, Ask, Slippage* PipValue, Sloss, Tprof, NameEA + CurTime(),MAGIC_NUM, 0, Green); prtAlert("Buying"); }

Scriptong: Husanboy пишет: Вот сделал так, но все равно не работает: Приведите весь код, пожалуйста - закачайте mq4 файл на dropmefiles.com или любой другой файловый сервер.

Husanboy: Scriptong пишет: dropmefiles.com Пожалуйста: http://dropmefiles.com/DPETz

Scriptong: Husanboy пишет: Пожалуйста: http://dropmefiles.com/DPETz Что-то перепутали. По ссылке расположен эксперт ЕА, но кода в нем, по сути то и нет. Только то, что автоматически сгенерировал мастер Meta Editor.

Husanboy: Scriptong пишет: Что-то перепутали. По ссылке расположен эксперт ЕА, но кода в нем, по сути то и нет. Только то, что автоматически сгенерировал мастер Meta Editor.

Husanboy: Все получилось! Сам поправил и это работает. Но теперь появилось другого просьба к вам - как прописать в советнике, чтобы закрытие сделок при работе на реальных счетах отображалось так же, как при визуальном тестировании (стрелками и пунктиром, соединяющим точки открытия и закрытия ордеров)?

Scriptong: Husanboy пишет: чтобы закрытие сделок при работе на реальных счетах отображалось так же, как при визуальном тестировании (стрелками и пунктиром, соединяющим точки открытия и закрытия ордеров)? У функций OrderSend, OrderClose, OrderModify и OrderCloseBy нужно явно указывать последний параметр - arrowColor. По умолчанию он передается как clrNone, т. е. без цвета, что не отображает стрелку. Например: OrderSend(Symbol(), OP_BUY, 0.1, Ask, 30, 0, 0, "MySystem", 0, 0, clrBlue);

Husanboy: Scriptong пишет: Например: цитата: OrderSend(Symbol(), OP_BUY, 0.1, Ask, 30, 0, 0, "MySystem", 0, 0, clrBlue); Понятно, но если я хотел вставить другого вида стрелку например этот советника для открытие arrow code 236 и 238, а для закрытие arrow code 251(я сам добавлял стрелки, но при закрытие появиться редко или не всегда): http://file.qip.ru/arch/Hsajf3xt/MQL4.html

max020780: помогите пожалуйста сделать так чтоб выводило на экран следующим образом серия из 1-го ордера = 1 серия из 2-х ордеров = 7 серия из 3-х ордеров = 4 серия из 4-х ордеров = 9 ........ ......... серия из N ордеров = 3 и чтоб размер массива увеличивался от размера count так как зарание количество серий неизвестно ushort seriess[]; ushort series_current = 0; input int magic=345461; int NumberOfPositions(string sy="" , int mn=-1) { int i, k=OrdersTotal(), kp=0; if (sy=="0") sy=Symbol(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol()==sy || sy=="") { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if(mn<0|| OrderMagicNumber()==magic) kp++; } } } } return(kp); } void OnTick() { int count = NumberOfPositions(Symbol(),-1); if(count == 0) series_current = 0; if(series_current != count) { series_current = (ushort)count; if(count == 1) seriess[0]++; if(count > 1) { seriess[count-1]++; seriess[count-2]--; } } int i; int k=12; string comm; string comm1; for(i = 0; i < k; i++){ comm = StringConcatenate( "Серия из " , i ); comm1= StringConcatenate( "ордеров = ",seriess[i+1], "\n\r"); Comment(comm+comm1); }

Scriptong: Добрый день. max020780 пишет: помогите пожалуйста сделать так чтоб выводило на экран следующим образом серия из 1-го ордера = 1 серия из 2-х ордеров = 7 серия из 3-х ордеров = 4 серия из 4-х ордеров = 9 Пока из приведенного кода неясно, каким образом идентифицируются серии ордеров. К примеру, может быть идентификация по символу (но в коде используется только один символ - текущий), по типам ордеров, по MagicNumber, по интервалу времени открытия и т. д. Таким образом, нужно сначала определиться с тем, что подразумевается под термином "серия". max020780 пишет: и чтоб размер массива увеличивался от размера count так как зарание количество серий неизвестно Для этого делается именно так, как Вы и сделали - объявляется динамический массив. Только этот массив у Вас не изменяет свой размер в дальнейшем, что приведет к фатальной ошибке - выход за пределы массива. Изменяются размеры массива следующим образом: int tickets[]; int ordersCnt = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderSymbol() != Symbol()) continue; ArrayResize(tickets, ordersCnt + 1, 100); tickets[ordersCnt] = OrderTicket(); ordersCnt++; } Этот код собирает тикеты ордеров, принадлежащих текущему символу, в массив tickets с подсчетом количества ордеров (ordersCnt). Также приведенный код не сможет вывести информацию по нескольким сериям, т. к. постоянно перезаписывается состояние Comment. Вместо: for(i = 0; i < k; i++) { comm = StringConcatenate( "Серия из " , i ); comm1= StringConcatenate( "ордеров = ",seriess[i+1], "\n\r"); Comment(comm+comm1); } нужно сделать так: string comm = ""; for(i = 0; i < k; i++) comm = comm + "Серия из " , IntegerToString(i) + "ордеров = " + IntegerToString(seriess[i + 1]) + "\n\r"); Comment(comm);

Husanboy: Добрый день уважаемый Игорь! Пожалуйста помогите с кодам: как сделать динамическое текст уровни индикатора как фибо расширение(во время смешение графика с помощью мишкой направо или налево текст линии(например 61.8...) не исчезает или не перемешается и выглядит как привязанный на Х координату). Здесь например: имя линии Support 1 привязана постоянное точку и во время смешение графика с помощью мишкой(то есть ручное смешение графика) он не изменяет свои позицию и остается на месту. А я хотел его динамическое движение. Пожалуйста помогите еще раз?! #property indicator_chart_window //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- ObjectDelete("S1"); ObjectDelete("S2"); ObjectDelete("S3"); ObjectDelete("R1"); ObjectDelete("R2"); ObjectDelete("R3"); ObjectDelete("PIVIOT"); ObjectDelete("Support 1"); ObjectDelete("Support 2"); ObjectDelete("Support 3"); ObjectDelete("Piviot level"); ObjectDelete("Resistance 1"); ObjectDelete("Resistance 2"); ObjectDelete("Resistance 3"); Comment(" "); //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //---- double rates[1][6],yesterday_close,yesterday_high,yesterday_low; ArrayCopyRates(rates, Symbol(), PERIOD_D1); if(DayOfWeek() == 1) { if(TimeDayOfWeek(iTime(Symbol(),PERIOD_D1,1)) == 5) { yesterday_close = rates[1][4]; yesterday_high = rates[1][3]; yesterday_low = rates[1][2]; } else { for(int d = 5;d>=0;d--) { if(TimeDayOfWeek(iTime(Symbol(),PERIOD_D1,d)) == 5) { yesterday_close = rates[d][4]; yesterday_high = rates[d][3]; yesterday_low = rates[d][2]; } } } } else { yesterday_close = rates[1][4]; yesterday_high = rates[1][3]; yesterday_low = rates[1][2]; } //---- Calculate Pivots Comment("\nYesterday quotations:\nH ",yesterday_high,"\nL ",yesterday_low, "\nC ",yesterday_close); double R = yesterday_high - yesterday_low;//range double p = (yesterday_high + yesterday_low + yesterday_close)/3;// Standard Pivot double r3 = p + (R * 1.000); double r2 = p + (R * 0.618); double r1 = p + (R * 0.382); double s1 = p - (R * 0.382); double s2 = p - (R * 0.618); double s3 = p - (R * 1.000); drawLine(r3,"R3", Lime,0); drawLabel("Resistance 3",r3,Lime); drawLine(r2,"R2", Green,0); drawLabel("Resistance 2",r2,Green); drawLine(r1,"R1", DarkGreen,0); drawLabel("Resistance 1",r1,DarkGreen); drawLine(p,"PIVIOT",Blue,1); drawLabel("Piviot level",p,Blue); drawLine(s1,"S1",Maroon,0); drawLabel("Support 1",s1,Maroon); drawLine(s2,"S2",Crimson,0); drawLabel("Support 2",s2,Crimson); drawLine(s3,"S3",Red,0); drawLabel("Support 3",s3,Red); //---- return(0); } //+------------------------------------------------------------------+ void drawLabel(string name,double lvl,color Color) { if(ObjectFind(name) != 0) { ObjectCreate(name, OBJ_TEXT, 0, Time[10], lvl); ObjectSetText(name, name, 8, "Arial", EMPTY); ObjectSet(name, OBJPROP_COLOR, Color); } else { ObjectMove(name, 0, Time[10], lvl); } } void drawLine(double lvl,string name, color Col,int type) { if(ObjectFind(name) != 0) { ObjectCreate(name, OBJ_HLINE, 0, Time[0], lvl,Time[0],lvl); if(type == 1) ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID); else ObjectSet(name, OBJPROP_STYLE, STYLE_DOT); ObjectSet(name, OBJPROP_COLOR, Col); ObjectSet(name,OBJPROP_WIDTH,1); } else { ObjectDelete(name); ObjectCreate(name, OBJ_HLINE, 0, Time[0], lvl,Time[0],lvl); if(type == 1) ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID); else ObjectSet(name, OBJPROP_STYLE, STYLE_DOT); ObjectSet(name, OBJPROP_COLOR, Col); ObjectSet(name,OBJPROP_WIDTH,1); } }

Scriptong: Husanboy пишет: Здесь например: имя линии Support 1 привязана постоянное точку и во время смешение графика с помощью мишкой(то есть ручное смешение графика) он не изменяет свои позицию и остается на месту. А я хотел его динамическое движение. Чтобы перемещалась линия в зависимости от текущего положения графика? Это достаточно много нужно изменять, да и непонятно, зачем такой функционал нужен. Еще два года назад такое в принципе невозможно было сделать. На мой взгляд, лучше использовать отображение уровней Pivot по дням в истории. Так сделано в индикаторе FiboPivot из статьи "Два пути".

Husanboy: Чтобы перемещалась линия в зависимости от текущего положения графика? Это достаточно много нужно изменять, да и непонятно, зачем такой функционал нужен. Еще два года назад такое в принципе невозможно было сделать. На мой взгляд, лучше использовать отображение уровней Pivot по дням в истории. Так сделано в индикаторе FiboPivot из статьи "Два пути". Спасибо большое!

Husanboy: Добрый день! К вам еще вопрос: как получить нужные данных от истории последних 6 ордеров(нам известно получить от все или последний )? Помогите с кодом?

Scriptong: Если под последними ордерами имеются в виду последние шесть ордеров по времени закрытия (а не по какому-то другому критерию), то сделать нужно следующим образом. 1. На глобальном уровне объявляется структура и именованная константа, указывающая количество искомых ордеров: struct OrderInfo { int ticket; datetime closeTime; OrderInfo() { ticket = -1; closeTime = 0; } }; #define MAX_ORDERS 6 2. Функция поиска ордеров с выдачей результата: // Инициализация массива, собирающего данные о последних шести ордерах OrderInfo orderInfo[MAX_ORDERS]; // Просмотр истории счета for (int i = OrdersHistoryTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderCloseTime() <= orderInfo[MAX_ORDERS - 1].closeTime) continue; InsertOrderData(orderInfo); } // Вывод данных об ордерах Print("=========== Информация о ", MAX_ORDERS, " последних закрытых ордерах ===================="); for (int i = MAX_ORDERS - 1; i >= 0; i--) { if (!OrderSelect(orderInfo[ i ].ticket, SELECT_BY_TICKET)) continue; OrderPrint(); } Print("=========== Конец информации о ", MAX_ORDERS, " последних закрытых ордерах ===================="); 3. Функция вставки в массив данных о новом ордере: void InsertOrderData(OrderInfo &orderInfo[]) { // Поиск индекса элемента массива, в который необходимо вставить данные об ордере int i = MAX_ORDERS - 2; for (; i >= 0; i--) if (OrderCloseTime() <= orderInfo[ i ].closeTime) break; // Вставка будет произведена по следующему, после найденного, индекса i++; // Сдвиг данных об ордерах на один элемент вниз с целью освобождения места для вставки for (int k = MAX_ORDERS - 1; k > i; k--) orderInfo[k] = orderInfo[k - 1]; // Вставка новых данных orderInfo[ i ].ticket = OrderTicket(); orderInfo[ i ].closeTime = OrderCloseTime(); } Жду дополнительных вопросов, т. к. вряд ли здесь все понятно. Ну а критерий поиска всегда можно изменить.

Husanboy: «Жду дополнительных вопросов, т. к. вряд ли здесь все понятно. Ну а критерий поиска всегда можно изменить.» Добрый вечер! Спасибо за отличное объяснение! Вопросу неправильно поставил и могу объяснит подробно: по пересечением индикатора АС входим сделку с обычным лотам и до появление противоположного сигналу открыли и закрыли несколько сделки(Зона А) и по противоположного сигналу закроем все открытых сделки, теперь входим по направлению сигналу но если общий профит все сделки от предыдущие зона А был отрицательный тогда умножаем лот или положительный тогда по обычным лотам. Как получаем эти данные(по зонами)? http://file.qip.ru/photo/3qnpFXd-/eurusdecn-h1-tallinex-limited2.html Спасибо большое за помощь!!!

Scriptong: Husanboy пишет: Вопросу неправильно поставил и могу объяснит подробно: по пересечением индикатора АС входим сделку с обычным лотам и до появление противоположного сигналу открыли и закрыли несколько сделки(Зона А) и по противоположного сигналу закроем все открытых сделки, теперь входим по направлению сигналу но если общий профит все сделки от предыдущие зона А был отрицательный тогда умножаем лот или положительный тогда по обычным лотам. Как получаем эти данные(по зонами)? Для этого нужно каким-то образом помечать ордера, которые соответствуют определенной серии ордеров. Я, например, использую для таких целей Magic Number. В нем кумулятивно записываются данные об идентификаторе ордеров эксперта, номере серии и номере ордера в серии: #define MAX_ORDERS_IN_SERIES 1000 // Максимальное количество ордеров одного направления, поддерживаемое экспертом #define SERIES_RANK 10 // Максимальное количество серий, поддерживаемое советником #define MAGICNUMBER_MUL (int)(MAX_ORDERS_IN_SERIES * SERIES_RANK) // Множитель ID ордеров эксперта //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Синтез значения Magic Number | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetMagicNumber(int id, int masterSign, int seriesIndex, int orderIndex) { return id * MAGICNUMBER_MUL + seriesIndex * MAX_ORDERS_IN_SERIES + orderIndex; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Анализ значения Magic Number | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetOrderIndexAndIDMasterSeries(int mn, int &id, int &seriesIndex) { id = mn / MAGICNUMBER_MUL; int residue = mn % MAGICNUMBER_MUL; seriesIndex = residue / MAX_ORDERS_IN_SERIES; return residue % MAX_ORDERS_IN_SERIES; } Когда ордера пронумерованы подобным образом, то дальнейшая их идентификация в истории счета или среди рабочих ордеров становится возможной. Так, если указанной Вами зоне А соответствуют сделки серии с индексом 1, то выделяете из истории счета все ордера с таким индексом серии, по всем ним складываете результат (OrderProfit() + OrderSwap() + OrderComission()). Также можно обойтись без номеров серии (но Magic Number в любом случае нужен, чтобы отличать "свои" ордера от "чужих"). Такое возможно, если известен интервал действия зоны А. Например, если зона А началась на свече 2014.11.14 17:00, а закончилась на свече 2014.11.17 07:00, то нужно выбрать из истории счета все ордера, которые открылись (OrderOpenTime()) и закрылись (OrderCloseTime()) в заданном интервале.

Husanboy: Добрый день! Спасибо за ответы! Вот приложил вес код. Попробовал разные варианты типа по вашему примеру, но все равно работает не правильно(умножение лота при убытки серии ордеров от предыдущие зону). Пожалуйста, помогите сделать этот код работоспособный?! #property version "1.00" #property strict input string Indicator_Parameters_______="_";//Indicator Parameters // Параметры индикатора Стрелки и Линии input string AC_________________________="----";//Indicator Accelerator Oscillator input double BuyLine = 0.0002;//AC Buy Line input double SellLine = -0.0002;//AC Sell Line input string Trade_Parameters___________="__";//Trade Parameters input int DistanceOrders = 10;//Distance for Open Price input string BuyOrders__________________="----";//BuyStop Settings input double TakeProfit1 = 10;//Take Profit 1 input double TakeProfit2 = 20;//Take Profit 2 input double TakeProfit3 = 0;//Take Profit 3 input double StopLossBuy = 0;//Stop Loss input string SellOrders_________________="------";//SellStop Settings input double TakeProfit11 = 10;//Take Profit 1 input double TakeProfit22 = 20;//Take Profit 2 input double TakeProfit33 = 0;//Take Profit 3 input double StopLossSell = 0;//Stop Loss input int MaxOpenOrders = 6;//Max Open Orders input string Lot_Parameters_____________="-----";//Lot Parameters input double FixedLots = 0.1;//Lot input bool Martingale = true;//Martingale input double MultiplierLot = 2;//Lot Multiplier input int Slippage = 3; input string NameEA = "EA"; input int MAGIC_NUM = 123;//MAGIC NUMBER //=================================================// double Lots;double SlossB,SlossS,lot ,Tprof1,Tprof2,Tprof3,Tprof11,Tprof22, Tprof33;bool Buy = false, Sell = false; int PipValue = 1;double ClosingArray[100]; double LastLot=0,div=1;int deposit=0; int kesishma;double Drawdown;int sp=0,P=0; datetime LastOrderHTime=0,LastOrderTime=0; double EntryPriceBuy,EntryPriceSell; double AllProfit=0;bool Buy1 = false, Sell1 = false;int LastOrderTicket; datetime LastOrderTimeBuy=0,LastOrderTimeSell=0; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { if (Digits == 3 || Digits == 5){ PipValue = 10; } return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() {return(0);} //+------------------------------------------------------------------+ //| Получение сигналов на покупку и продажу | //+------------------------------------------------------------------+ void Indicators() { Buy = (iAC(NULL,0,2) < BuyLine && iAC(NULL,0,1) > BuyLine); Sell = (iAC(NULL,0,2) > SellLine && iAC(NULL,0,1) < SellLine); Buy1 = (iAC(NULL,0,1) > BuyLine); Sell1 = (iAC(NULL,0,1) < SellLine); } //+-----------------------------------------------------------------// double FindLastOrderParameter(int mNumber, string ParamName) { int mOrderTicket = 0; double mOrderPrice = 0; double mOrderLot = 0; double mOrderProfit = 0; int PrevTicket = 0; int CurrTicket = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) if (OrderSymbol() == Symbol() && OrderMagicNumber() == mNumber) { CurrTicket = OrderTicket(); if(CurrTicket > PrevTicket) { PrevTicket = CurrTicket; mOrderPrice = OrderOpenPrice(); mOrderTicket = OrderTicket(); mOrderLot = OrderLots(); mOrderProfit = OrderProfit() + OrderSwap() + OrderCommission(); } } if(ParamName == "price") return(mOrderPrice); else if(ParamName == "ticket") return(mOrderTicket); else if(ParamName == "lot") return(mOrderLot); else if(ParamName == "profit") return(mOrderProfit); return(0); } //+-------------------------------------------------------------------------------------------------// datetime FindLastHistoryOrderParameter(int mNumber, string ParamName) { datetime mOrderTime = 0;int PrevTicket = 0; int CurrTicket = 0; for(int i=OrdersHistoryTotal()-1;i>=0;i--) { CurrTicket = OrderTicket(); if(CurrTicket > PrevTicket) { PrevTicket = CurrTicket; if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; mOrderTime = OrderOpenTime(); } } if(ParamName == "time") return(mOrderTime); return(0); } //+-----------------------------------------------------------------------------------------------------------------------+ //| Вывод предупреждения об отправке ордера | //+-----------------------------------------------------------------------------------------------------------------------+ void prtAlert(string str = "") { Print(str); Alert(str); } //+------------------------------------------------------------------+ //| Расчет размера ордера | //+------------------------------------------------------------------+ void LotsSize() { Lots = FixedLots; if(Lots<MarketInfo(Symbol(),MODE_MINLOT)) Lots=MarketInfo(Symbol(),MODE_MINLOT); if(Lots>MarketInfo(Symbol(),MODE_MAXLOT)) Lots=MarketInfo(Symbol(),MODE_MAXLOT); AllProfit = CheckTotalProfitHistory(); LastLot = CheckLastLotHistory(); if(Martingale && AllProfit < 0){ Lots=NormalizeDouble(LastLot * MultiplierLot, 2);} } //+------------------------------------------------------------------+ double CheckLastLotHistory() { double Llot=0; int df = OrdersHistoryTotal()-1; for(int i=OrdersHistoryTotal()-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC_NUM ) { Llot=OrderLots(); } }} return(Llot); } //+------------------------------------------------------------------+ //| History Total Profit | //+------------------------------------------------------------------+ double CheckTotalProfitHistory() { double Profit=0; for(int i=OrdersHistoryTotal()-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC_NUM) { if(buy != 0 && LastOrderTimeSell <= OrderOpenTime()){ Profit+=OrderProfit();} if(sell != 0 && LastOrderTimeBuy <= OrderOpenTime()){ Profit+=OrderProfit();} }}} return(Profit); } //+------------------------------------------------------------------+ void CloseOrders() { for( int i = 0; i < OrdersTotal(); i++) { bool Os = OrderSelect(i,SELECT_BY_POS); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC_NUM) { if( Sell && OrderComment()== NameEA+(string)1) { CloseAll(); } if( Buy && OrderComment()== NameEA) { CloseAll();}} } } //+------------------------------------------------------------------+ //| CloseAll | //+------------------------------------------------------------------+ int CloseAll() { int i=OrdersTotal()-1; for(i=OrdersTotal()-1;i>=0;i--) { int os = OrderSelect(i,SELECT_BY_POS); if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC_NUM) { if(OrderType()==OP_BUY) int oc = OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(MarketInfo(Symbol(),MODE_BID), (int)MarketInfo(Symbol(),MODE_DIGITS)),1000,Gold); if(OrderType()==OP_SELL) int oc = OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(MarketInfo(Symbol(),MODE_ASK), (int)MarketInfo(Symbol(),MODE_DIGITS)),1000,Gold); if(OrderType()!=OP_BUY && OrderType()!=OP_SELL) int od = OrderDelete(OrderTicket()); int x=0; for(x=0;x<100;x++) { if(ClosingArray[x]==0) { ClosingArray[x]=OrderTicket(); break; } } } } return(1);} //CloseAll --------------------------------------------------------END void OpenOrder() { int totalOrders = OrdersTotal(),numPos = 0,numPosb = 0 ,numPosss = 0 ,numPosbb = 0, numPoss = 0;totalOrders = OrdersTotal(); numPos = 0; for(int i = 0; i < totalOrders; i++) { int OrSel = OrderSelect(i, SELECT_BY_POS); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC_NUM) { numPos++; if(OrderType()== OP_BUYSTOP){ numPosb++;} if(OrderType()== OP_SELLSTOP){ numPoss++;} if(OrderType()== OP_BUY){ numPosbb++;} if(OrderType()== OP_SELL){ numPosss++;} } } if(numPos < 6) { if( Buy && LastOrderTimeBuy==0){ EntryPriceBuy = iOpen(NULL,0,0) + DistanceOrders * PipValue * Point;buy=1; EntryPriceSell = iOpen(NULL,0,0) - DistanceOrders * PipValue * Point;sell=0; LastOrderTime=iTime(NULL,0,0);lot=Lots;LastOrderTimeBuy=iTime(NULL,0,0);LastOrderTimeSell=0; } if( Sell && LastOrderTimeSell==0){ EntryPriceBuy = iOpen(NULL,0,0) + DistanceOrders * PipValue * Point;buy=0; EntryPriceSell = iOpen(NULL,0,0) - DistanceOrders * PipValue * Point;sell=2; LastOrderTime=iTime(NULL,0,0);lot=Lots;LastOrderTimeSell=iTime(NULL,0,0);LastOrderTimeBuy=0; } if( LastOrderTimeBuy!=0 && LastOrderTimeSell==0 ) { if( numPosb < 1 && numPosbb < 1){ if(StopLossBuy == 0){SlossB = EntryPriceSell;} else{ SlossB = EntryPriceBuy - StopLossBuy* PipValue * Point;} if(TakeProfit1 == 0){Tprof1 = 0;}else{ Tprof1 = EntryPriceBuy + TakeProfit1* PipValue * Point;} if(TakeProfit2 == 0){Tprof2 = 0;}else{ Tprof2 = EntryPriceBuy + TakeProfit2* PipValue * Point;} if(TakeProfit3 == 0){Tprof3 = 0;}else{ Tprof3 = EntryPriceBuy + TakeProfit3* PipValue * Point;} bool Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof1, NameEA+(string)1 ,MAGIC_NUM, 0, Green); Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof2, NameEA+(string)1 ,MAGIC_NUM, 0, Green); Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof3, NameEA+(string)1,MAGIC_NUM, 0, Green);} if( numPoss < 1 && numPosss < 1){ if(StopLossSell == 0){SlossS = EntryPriceBuy;} else{ SlossS = EntryPriceSell + StopLossSell * PipValue * Point;} if(TakeProfit11 == 0){Tprof11 = 0;}else{ Tprof11 = EntryPriceSell - TakeProfit11* PipValue * Point;} if(TakeProfit22 == 0){Tprof22 = 0;}else{ Tprof22 = EntryPriceSell - TakeProfit22* PipValue * Point;} if(TakeProfit33 == 0){Tprof33 = 0;}else{ Tprof33 = EntryPriceSell - TakeProfit33* PipValue * Point;} bool Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof11, NameEA+(string)1 ,MAGIC_NUM, 0, Red); Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof22, NameEA+(string)1 ,MAGIC_NUM, 0, Red); Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof33, NameEA+(string)1 ,MAGIC_NUM, 0, Red);} } if( LastOrderTimeBuy==0 && LastOrderTimeSell!=0 ) { if( numPosb < 1 && numPosbb < 1){ if(StopLossBuy == 0){SlossB = EntryPriceSell;} else{ SlossB = EntryPriceBuy - StopLossBuy* PipValue * Point;} if(TakeProfit1 == 0){Tprof1 = 0;}else{ Tprof1 = EntryPriceBuy + TakeProfit1* PipValue * Point;} if(TakeProfit2 == 0){Tprof2 = 0;}else{ Tprof2 = EntryPriceBuy + TakeProfit2* PipValue * Point;} if(TakeProfit3 == 0){Tprof3 = 0;}else{ Tprof3 = EntryPriceBuy + TakeProfit3* PipValue * Point;} bool Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof1, NameEA ,MAGIC_NUM, 0, Green); Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof2, NameEA ,MAGIC_NUM, 0, Green); Tiket= OrderSend(Symbol(), OP_BUYSTOP, lot, EntryPriceBuy, 3, SlossB, Tprof3, NameEA ,MAGIC_NUM, 0, Green);} if( numPoss < 1 && numPosss < 1){ if(StopLossSell == 0){SlossS = EntryPriceBuy;} else{ SlossS = EntryPriceSell + StopLossSell * PipValue * Point;} if(TakeProfit11 == 0){Tprof11 = 0;}else{ Tprof11 = EntryPriceSell - TakeProfit11* PipValue * Point;} if(TakeProfit22 == 0){Tprof22 = 0;}else{ Tprof22 = EntryPriceSell - TakeProfit22* PipValue * Point;} if(TakeProfit33 == 0){Tprof33 = 0;}else{ Tprof33 = EntryPriceSell - TakeProfit33* PipValue * Point;} bool Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof11, NameEA ,MAGIC_NUM, 0, Red); Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof22, NameEA ,MAGIC_NUM, 0, Red); Tiket= OrderSend(Symbol(), OP_SELLSTOP, lot, EntryPriceSell, 3, SlossS, Tprof33, NameEA ,MAGIC_NUM, 0, Red);} } } } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if(Bars < 3){ Print("Not enough bars for this strategy - ", NameEA); return(-1); } Indicators(); OpenOrder(); LotsSize();int totalOrders = OrdersTotal(); int numPos = 0,numPosb = 0,numPoss = 0;bool ban = false; bool band = false;bool bandit = false; /*DeleteOrders();*/CloseOrders(); for(int i = OrdersTotal() - 1; i >= 0; i--) if (OrderSelect (i, SELECT_BY_POS)) { // если на свече уже есть открытый ордер, ставим запрет if ( OrderOpenTime() >= Time[0] ) ban = true; } if ( ban ){ return(0);} for(int i=OrdersHistoryTotal()-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; // если на свече уже есть открытый ордер, ставим запрет if ( OrderOpenTime() >= Time[0] ) band = true; } if ( band ){ return(0);} for( int i = 0; i < totalOrders; i++) { int OrSel = OrderSelect(i, SELECT_BY_POS); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC_NUM) { numPos++; if (OrderProfit()<0){ Drawdown = OrderProfit()*100/AccountBalance(); } } } return(0); } //+---------------------------------------------------------------------------------//

Husanboy: Добрый день! Обновлен код(предыдущие поста). Пожалуйста, помогите?!

Scriptong: Добрый день. Пожалуйста, большие коды прикрепляйте в виде файла (например, разместите его на dropmefiles.com, а здесь оставьте ссылку). В том коде, что Вы привели, достаточно много очевидных ошибок (их я исправил). Но даже после исправления код не компилируется - отсутствует объявление переменных buy и sell. Исправить не могу, т. к. не понимаю, зачем эти переменные нужны сами по себе. Если же в коде опечатка, то ее нужно исправить только Вам. Догадаться, где именно эта опечатка, я не могу. Итак, вот файл кода, исправленный и приведенный мною в удобочитаемый вид. Определите в нем, где именно опечатка или где именно должны быть объявлены переменные. Ну и чтобы я смог помочь Вам, укажите четко, в чем именно заключается проблема: как должен работать эксперт и как он работает сейчас (в чем именно неправильность заключается).

Husanboy: Добрый вечер! Спасибо за ответь! Тогда начнем: каждый раз по пересечением АС на 0,0002(или -0,0002) линии открывается серии ордеров и это бывает начала торговый зону(например зона А). После обратным пересечение АС закрывается все(открытый и отложенный) ордеры и это конца торговый зону. Далее если общий прибил от предыдущие зону положительный тогда следующие серии ордеров для зону(В) открывается с обычным лотам, а если прибыл был отрицательный, тогда умножаем лот вдвое. Короче, использовать мартингейл по прибылью серии ордеров от предыдущие зону. Я уже сделал все необходимые, но умножение лота при убытки предыдущие зону работает не точно. По моему теперь немного понятно. Пожалуйста, помогите?!!! Спасибо заранее!!! Вот советник: http://dropmefiles.com/YxvHA

Scriptong: Доброго времени суток. Вы прислали свою старую версию. В итоге то, что я исправлял, придется заново исправлять. Так мы с Вами не сдвинемся с места Давайте уже оперировать одним и тем же кодом: после внесения правок в него мною правки вносите Вы. И так далее по очереди, пока не доведем код до кондиции. Итак, изначально ошибка в самом подходе к решению задачи. В коде нет разложения задачи на составляющие: каждая функция выполняет не одну конкретную задачу, а множество общих. В итоге идея размывается, а исправление ошибок с ростом кода экспоненциально затрудняется. К примеру, в коде существует 11 (!!!) мест, выполняющих последовательный перебор истории. Мало того, что они занимают много места в коде, так еще и приводят к нерациональной трате ресурсов. Все это легко заменяется на один цикл обращения к списку ордеров и один цикл обращения к истории счета. В этих циклах необходимо собрать все данные, необходимые для дальнейшей обработки. Чтобы комфортно работать с сетками ордеров, я уже рекомендовал Вам использовать разметку при помощи Magic Number. Без нее здесь никак не обойтись, т. к. иначе все ордера будут как близнецы-братья. Поэтому сразу берем на вооружение функции кодировки и декодировки Magic Number: #define MAX_ORDERS_IN_SERIES 1000 // Максимальное количество ордеров одного направления, поддерживаемое экспертом //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Синтез значения Magic Number | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetMagicNumber(int id, int masterSign, int seriesIndex, int orderIndex) { return id * MAX_ORDERS_IN_SERIES + orderIndex; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Анализ значения Magic Number | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetOrderIndexAndID(int mn, int &id) { id = mn / MAX_ORDERS_IN_SERIES ; return mn % MAX_ORDERS_IN_SERIES; } Далее. Так как в каждой серии у нас по шесть ордеров (три - Buy и три - Sell), то необходимо организовать два массива, в которые на каждом тике собирается информация о рабочих ордерах. Причем удобство этих массивов будет в том, что мы сразу же будем знать, какие ордера из сетки уже установлены, а какие - нет: #define ORDERS_IN_SERIES 3 int g_buyCnt, g_sellCnt; int g_buyTicket[ORDERS_IN_SERIES], g_sellTicket[ORDERS_IN_SERIES]; void FindExpertOrders() { int id, orderIndex; g_buyCnt = 0; g_sellCnt = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderSymbol() != Symbol()) continue; orderIndex = GetOrderIndexAndID(OrderMagicNumber(), id); if (id != i_magicNumber) continue; if (orderIndex < 0 || orderIndex >= ORDERS_IN_SERIES) continue; if (OrderType() % 2 == OP_BUY) { g_buyTicket[orderIndex] = OrderTicket(); g_buyCnt++; } else { g_sellTicket[orderIndex] = OrderTicket(); g_sellCnt++; } } } Функцию поиска своих ордеров необходимо вызвать сразу же при входе в OnTick. Код, который я привел - здесь. Осмыслите его и попытайтесь самостоятельно написать функцию просмотра истории по аналогии. А также подумайте над тем, где и как она должна использоваться. Потом продолжим.

Husanboy: Добрый день! Нету файл в вашем ссылку.

Scriptong: Husanboy пишет: Нету файл в вашем ссылку. Да, что-то там поломалось . Дублирую.

Husanboy: Scriptong пишет: Да, что-то там поломалось . Дублирую. Спасибо!

Husanboy: *PRIVAT*

Scriptong: Husanboy пишет: Снимите, пожалуйста, галку "показывать только модераторам". Иначе никто, кроме администратора, Ваше сообщение не увидит.

Husanboy: Добрый день! Отправил лс, пожалуйста проверите.

Scriptong: Husanboy пишет: Отправил лс, пожалуйста проверите. Ответ смотрите в личке.

max020780: Вечер добрый Игорь с наступающими вас праздниками помогите пожалуйста переделать простой тралл в пунктах так чтобы он траллил в валюте депозита тоесть в параметhs указывались в валюте депозита а то никак неполучается немогу сообразитьvoid SimpleTrailing(string sy="",int op=-1,int mn=-1, int tstop=0, bool IPT=false, int tstep=0)export { //timec=TimeCurrent(); double po,pp; int i,k=OrdersTotal(); string Autor; if(sy=="0") sy=Symbol(); if( tstop==0) tstop=MarketInfo(Symbol(),MODE_STOPLEVEL); for(i=0;i<k;i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) { po=MarketInfo(OrderSymbol(),MODE_POINT); if(mn<0 || OrderMagicNumber()==mn) { if(OrderType()==OP_BUY) { pp=MarketInfo(OrderSymbol(),MODE_BID); if((!IPT && OrderProfit()>0) || pp-OrderOpenPrice()>tstop*po) { if(OrderStopLoss()<pp-(tstop+tstep-1)*po) { ModifyOrder(-1,pp-tstop*po,-1); } } } if(OrderType()==OP_SELL) { pp=MarketInfo(OrderSymbol(),MODE_ASK); if((!IPT && OrderProfit()>0) || OrderOpenPrice()-pp>tstop*po) { if(OrderStopLoss()>pp+(tstop+tstep-1)*po || OrderStopLoss()==0) { ModifyOrder(-1,pp+tstop*po,-1,TimeCurrent()); } } } } } } } }

Scriptong: Если параметр, указывающий величину в валюте депозита, на которую следует отступать стопу от текущей цены: input double i_trailCurrencySize = 100.0; то для расчета количества пунктов, которые соответствуют этой величине, необходимо использовать такой код: double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); if (tickValue == 0.0 || tickSize == 0.0 || point == 0.0) return; double ticksAmount = i_trailCurrencySize / (tickValue * <объем ордера>); int points = (int)MathCeil(ticksAmount * tickSize / point); Этот код необходимо исполнять на каждом тике, т. к. на символах кроссов (там, где нет валюты депозита) стоимость пункта будет изменяться на каждом новом тике. Полученное значение points подставляйте в условия сравнения вместо величины трейлинга.

Husanboy: Добрый день мастер! Еще раз помогите с кодам пожалуйста?! С каким кодам мы получаем количество дневной прибыл или лосс по пунктам(daily pips profit or loss) в mql5(МТ5) языке? То есть pips profit\loss in history. Спасибо за ранее!!!

Scriptong: Добрый день. Подсчет общего количества пунктов, которые дали закрытые сделки, имеет смысл только в том случае, если за текущий день велась торговля только по одному символу. Если символов несколько, то будем складывать свиней с гусями. На MQL5 программирую мало. Поэтому нижеприведенный код вряд ли можно взять за образец решения поставленной задачи. Но по нему, как минимум, можно понять логику подсчета: // Получение даты/времени открытия текущего дня datetime time[1]; if (CopyTime(_Symbol, PERIOD_D1, 0, 1, time) < 0) return; // Загрузка истории за сегодняшний день if (!HistorySelect(time[0], TimeCurrent())) return; // Подсчет общего количества пунктов int total = HistoryDealsTotal(); // Общее количество сделок в истории сегодняшнего дня int totalPoints = 0; // Общее количество закрытых пунктов for (int i = 0; i < total; i++) { // Попытка выбора сделки из списка ulong ticket = HistoryDealGetTicket(i); if (ticket == 0) continue; // Определение типа сделки. Интересуют только Buy и Sell. Другие операции отбрасываются ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE); if (dealType != DEAL_TYPE_BUY && dealType != DEAL_TYPE_SELL) continue; // Прибыль/убыток, которую принесла сделка. Интересуют только операции закрытия double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT); if (profit == 0.0) continue; // Получение информации о свойствах символа, по которому открыта/закрыта сделка string symbol = HistoryDealGetString(ticket, DEAL_SYMBOL); double point = SymbolInfoDouble(symbol, SYMBOL_POINT); double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); if (point == 0.0 || tickSize == 0.0 || tickValue == 0.0) continue; // Получение объема сделки double volume = HistoryDealGetDouble(ticket, DEAL_VOLUME); if (volume == 0.0) continue; // Количество закрытых пунктов totalPoints += (int)MathRound((profit * tickSize) / (tickValue * volume) / point); } Alert("Total points = ", totalPoints); Так как история сделок в МТ5 представлена двумя строками (открытие и закрытие), а не одной, как в МТ4, то установить четкое соответствие между моментом начального открытия и полного закрытия позиции можно, основательно прошерстив списки не только сделок, но и ордеров. А это уже задача посложнее. В данном случае выбрал более простой путь: в списке находятся "закрывающие" сделки и по их прибыли вычисляется (примерно), сколько пунктов прибыли/убытка было закрыто.

Husanboy: Scriptong пишет: Добрый вечер! Да, вы абсолютно "Master MQL" и самый лучший из них!!! Это работает как я хотел и спросил. Спасибо еще раз и бесконечно!!!

Husanboy: И вот появилось еще другой вопросик: можно ли определить прибыльный позиции(или ордер) среди нескольких открытых ордеров? То есть хочу такое условие - закрыть прибыльный позицию среди нескольких открытых, но если его прибыл больше "x" от баланса("х"$). Помогите с кодам(для mql4)?! Спасибо еще раз!!!

Scriptong: Husanboy пишет: То есть хочу такое условие - закрыть прибыльный позицию среди нескольких открытых, но если его прибыл больше "x" от баланса("х"$) Наверное имелось в виду, что X указывается в процентах от баланса? Ведь если Х указывается в валюте, то значение баланса для такой операции не нужно. Код достаточно простой: input double i_targetProfitPercents = 10.0; // Целевая прибыль в процентах от баланса ... int ticket = GetTargetProfitOrder(); if (ticket < 0) return; // Закрытие ордера ticket // ... int GetTargetProfitOrder() { double targetProfit = AccountInfoDouble(ACCOUNT_BALANCE) * i_targetProfitPercents / 100.0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderType() != OP_BUY && OrderType() != OP_SELL) continue; double profit = OrderProfit() + OrderSwap() + OrderCommission(); if (profit >= targetProfit) return OrderTicket(); } return -1; } Алгоритм следующий: 1. Расчет величины целевой прибыли (targetProfit), исходя из текущего значения баланса депозита. 2. Поиск ордера Buy или Sell. 3. Определение, достаточна ли прибыль этого ордера для закрытия. 4. Если прибыль достаточна, то функция GetTargetProfitOrder возвращает тикет такого ордера. Зная тикет ордера, с ним можно делать все, что угодно.

Husanboy: Scriptong пишет: Наверное имелось в виду, что X указывается в процентах от баланса? Ведь если Х указывается в валюте, то значение баланса для такой операции не нужно. Добрый день! Все получилось и работает как я хотел. Спасибо большое еще раз!!!

Scriptong: Husanboy пишет: Все получилось и работает как я хотел. Спасибо большое еще раз!!! Пожалуйста. Обращайтесь.

Husanboy: Scriptong пишет: Пожалуйста. Обращайтесь. Добрый день! Сегодня хочу спросить о типу datetime. Если его выводим наружу с input ам, то он будет показан как календарь МТ4. Но его не возможно изменить. Как можно изменить его(для изменении время дней - часов, например для запрещение торговлю перед новостью)? Спасибо заранее!!!

Scriptong: Husanboy пишет: Сегодня хочу спросить о типу datetime. Если его выводим наружу с input ам, то он будет показан как календарь МТ4. Но его не возможно изменить. Как можно изменить его(для изменении время дней - часов, например для запрещение торговлю перед новостью)? Его можно изменить. К примеру, если параметр задан следующим образом: input datetime i_dateTime = D'2015.06.07 12:00'; то будет выглядеть в настроечных параметрах так: Чтобы изменить дату, то да - просто используем календарь. А вот для изменения времени необходимо установить курсор на поле времени и изменить его при помощи цифровых клавиш или при помощи стрелок вверх-вниз:

Husanboy: Scriptong пишет: Его можно изменить. К примеру, если параметр задан следующим образом: Добрый день! Спасибо за ответь! Об этом я тоже знал и пробовал, но не работал! Не изменяется!!! Или это программно не возможно? Помогите пожалуйста?!

Scriptong: Husanboy пишет: Об этом я тоже знал и пробовал, но не работал! Не изменяется!!! Что именно не работает? Опишите то, что Вы делаете, по шагам.

Husanboy: Scriptong пишет: Что именно не работает? Опишите то, что Вы делаете, по шагам. Scriptong пишет: Чтобы изменить дату, то да - просто используем календарь. А вот для изменения времени необходимо установить курсор на поле времени и изменить его при помощи цифровых клавиш или при помощи стрелок вверх-вниз: Сделал как вы написали изменил цифры и после нажатие кнопку "ок" все цифры вернется пережному дату.

Scriptong: Husanboy пишет: Сделал как вы написали изменил цифры и после нажатие кнопку "ок" все цифры вернется пережному дату. Перед нажатием "ОК" необходимо подтвердить произведенные изменения нажатием клавиши Enter.

Husanboy: Здравствуйте мастер! Помогите реализовать сигнал алерты этого индикатора. Сейчас он выдает алерт по каждому тику. Сам попробовал, но не получился. Спасибо за ранее!!! http://qclk.ru/ku/c44z

Scriptong: Husanboy пишет: Сейчас он выдает алерт по каждому тику. Сам попробовал, но не получился. Проблема в том, что Вы в качестве времени передаете функции Alerts время бара, вычисленное по индексу валютной пары (переменная i) в массиве iPars: iTime(NULL,TimeFrame,i) Причем бар берется с текущего графика, а нужно брать нулевой бар с графика того символа, которому соответствует индекс i. То есть на место, где указывается номер бара, Вы поставили индекс валютной пары, а на место, где указывается имя пары, поставили текущую пару (NULL). Но и этого еще не будет достаточно, т. к. для каждой валютной пары нужно организовать сохранение последнего времени возникновения сигнала. У Вас же переменная TimeNow одна на все пары. В итоге, если будет сигнал по одной паре, то по другой паре на этом же баре сигнала уже не будет.

Husanboy: Scriptong пишет: Причем бар берется с текущего графика, а нужно брать нулевой бар с графика того символа, которому соответствует индекс i. То есть на место, где указывается номер бара, Вы поставили индекс валютной пары, а на место, где указывается имя пары, поставили текущую пару (NULL). Но и этого еще не будет достаточно, т. к. для каждой валютной пары нужно организовать сохранение последнего времени возникновения сигнала. У Вас же переменная TimeNow одна на все пары. В итоге, если будет сигнал по одной паре, то по другой паре на этом же баре сигнала уже не будет. OK, Spasibo bolshoe!!! Uje poluchilos.

Scriptong: Husanboy пишет: OK, Spasibo bolshoe!!! Uje poluchilos. Пожалуйста.

giraffeol: Уважаемый Игорь! Знаю качество Вашей работы и профессиональный подход к решению задач еще по индикаторам с сайта Admiral Markets. Некоторые из Ваших индикаторов использую до сих пор. Так как я совершенно не умею писать индикаторы, рискнул обратиться к Вам за помощью. Помогите довести до "Ума" индикатор "KST_KnowSureThing". Вот на него ссылка https://db.tt/ioy8NnKW Основная проблема в том, что он не обновляется, т.е. появляется новый бар, а значений индикатора нет.... (скриншот https://db.tt/isSROn1u ) Еще хотелось бы по возможности добавить в этот индикатор несколько функций: 1. Индикатор отображался только на конкретном ТФ, например М30; 2. На максимумах и минимумах линии KST строилась на графике вертикальная линия заданного цвета, толщины и начертания (например черная); 3. На пересечениях линии KST и сигнальной линии также строилась вертикальная линия заданного цвета, толщины и начертания (при пересечении сверху вниз - красная, снизу в верх - зеленая); 4. Имелась возможность задать ТФ, на которых эти линии так же отображались ( например М15 и Н4). (скриншот https://db.tt/FXPOuAQq ). Заранее вам благодарен. С уважением, Олег.

Scriptong: giraffeol пишет: совершенно не умею писать индикаторы Добрый день, Олег. Напоминаю, что тема называется "Консультации по программированию". Очевидно, что невозможно проконсультировать человека в рамках той проблемы, суть которой он не понимает. Ваша просьба больше подходит для темы "Заказы на разработку", но такой темы на этом форуме нет и не будет. Ну а обновляющийся KST - здесь.

giraffeol: Игорь! Большое спасибо, что подправили файл индикатора. В каком разделе надо опубликовать торговую идею на основе этого индикатора для ее реализации в случае Вашей заинтересованности в этом? С уважением, Олег.

Scriptong: giraffeol пишет: В каком разделе надо опубликовать торговую идею на основе этого индикатора для ее реализации в случае Вашей заинтересованности в этом? По большому счету в любом разделе, кроме "Статьи Advance Tools", "Инструменты трейдера" и "Статьи MQLabs". Желательно, чтобы это была отдельная тема. В теме максимально подробно, насколько это возможно, излагается суть подхода. Выражения типа "нужно сделать советник/индикатор/скрипт" не приветствуются. Иначе получится, что прямо в теме я напишу отказ от реализации. Если идея мне понравится и будет время на ее реализацию, то со временем увидите результат в новостной ленте.



полная версия страницы