drobayura Опубликовано 28 декабря, 2022 Поделиться Доработка советников: общая тема Опубликовано 28 декабря, 2022 26 минут назад, drobayura сказал: Да это и есть цена входа high в BUY и low в SELL. ... "пропускает сигналы" - не открывает ордер на реальном счете. ..."отрабатывает четко" а на демо счете открывает ордера по high и low ценам свечи. Если что то не так просто покажите как надо чтоб ордера открывались на high и low свечи. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 28 декабря, 2022 Поделиться Доработка советников: общая тема Опубликовано 28 декабря, 2022 3 часа назад, drobayura сказал: Если что то не так просто покажите как надо чтоб ордера открывались на high и low свечи. Ну открыть ордер можно по текущей цене открытия. Бид, или аск. чтобы открываться на хай и лоу свечи, вам всего лишь надо открывать покупки, когда аск равен лоу (никогда) и продажи, когда бид равен хай. если вы найдете способ открываться на лоу и хай это будет настоящий грааль Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 Здравствуйте! Может кто нибудь помочь сделать этот тралл общим? double OOP,SL; int b=0,s=0,tip,TicketB=0,TicketS=0; for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==Symbol()) { tip = OrderType(); OOP = NormalizeDouble(OrderOpenPrice(),Digits); if(tip==OP_BUY) { b++; TicketB=OrderTicket(); if(Stoploss!=0 && Bid<=OOP - Stoploss * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),slippage,clrNONE)) continue;} if(Takeprofit!=0 && Bid>=OOP + Takeprofit * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),slippage,clrNONE)) continue;} if(TrailingStop>0) { SL=NormalizeDouble(Bid-TrailingStop*Point,Digits); if(SL>=OOP+TrailingStart*Point && (TrallB==0 || TrallB+TrailingStep*Point<SL)) TrallB=SL; } } if(tip==OP_SELL) { s++; if(Stoploss!=0 && Ask>=OOP + Stoploss * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),slippage,clrNONE)) continue;} if(Takeprofit!=0 && Ask<=OOP - Takeprofit * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),slippage,clrNONE)) continue;} TicketS=OrderTicket(); if(TrailingStop>0) { SL=NormalizeDouble(Ask+TrailingStop*Point,Digits); if(SL<=OOP-TrailingStart*Point && (TrallS==0 || TrallS-TrailingStep*Point>SL)) TrallS=SL; } } } } } Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 8 часов назад, Lexa000 сказал: Здравствуйте! Может кто нибудь помочь сделать этот тралл общим? double OOP,SL; int b=0,s=0,tip,TicketB=0,TicketS=0; for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==Symbol()) { tip = OrderType(); OOP = NormalizeDouble(OrderOpenPrice(),Digits); if(tip==OP_BUY) { b++; TicketB=OrderTicket(); if(Stoploss!=0 && Bid<=OOP - Stoploss * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),slippage,clrNONE)) continue;} if(Takeprofit!=0 && Bid>=OOP + Takeprofit * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),slippage,clrNONE)) continue;} if(TrailingStop>0) { SL=NormalizeDouble(Bid-TrailingStop*Point,Digits); if(SL>=OOP+TrailingStart*Point && (TrallB==0 || TrallB+TrailingStep*Point<SL)) TrallB=SL; } } if(tip==OP_SELL) { s++; if(Stoploss!=0 && Ask>=OOP + Stoploss * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),slippage,clrNONE)) continue;} if(Takeprofit!=0 && Ask<=OOP - Takeprofit * Point) {if(OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),slippage,clrNONE)) continue;} TicketS=OrderTicket(); if(TrailingStop>0) { SL=NormalizeDouble(Ask+TrailingStop*Point,Digits); if(SL<=OOP-TrailingStart*Point && (TrallS==0 || TrallS-TrailingStep*Point>SL)) TrallS=SL; } } } } } Ну вы, вроде, уже сделали его общим, когда выложили его код сюда в топик. Если вы имели в виду что-то другое, то, возможно, имеет смысл описать подробнее, чего именно вам хотелось бы добиться Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 1 час назад, Rigal сказал: Ну вы, вроде, уже сделали его общим, когда выложили его код сюда в топик. Если вы имели в виду что-то другое, то, возможно, имеет смысл описать подробнее, чего именно вам хотелось бы добиться Мне нужно чтобы он траллил все открытые ордера по направлению в продажи общим профитом, то же самое в другом направлении. Например: открытую сеть в продажи закрывал всю общим профитом Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 4 минуты назад, Lexa000 сказал: Мне нужно чтобы он траллил все открытые ордера по направлению в продажи общим профитом, то же самое в другом направлении. Например: открытую сеть в продажи закрывал всю общим профитом Ну тогда есть смысл пояснить, что там за параметры в коде, как вам хотелось бы их учитывать - они все объявлены за пределами процитированного куска и не совсем понятно, что кто из них значит. Трал там явно в пунктах, причем пятизначных для пятизначного брокера, четырехзначных - для четырехзначного. Я так понимаю, TrailingStop - это величина отката, на котором закрываем. TrailingStart - это профит в пунктах, после которого начинаем тралить, TrailingStep - шаг фиксации "максимума". А дальше там есть вопросы по тейкам и стопам, например: они, вероятно, индивидуальные у всех ордеров, вы с ними как хотите поступать? Ну и в целом, код так себе: перезапуск советника с этим кодом приведет к поломке логики трала. Поэтому проще описать, чего вы хотите. Написать это проще с нуля. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 24 минуты назад, Rigal сказал: Ну тогда есть смысл пояснить, что там за параметры в коде, как вам хотелось бы их учитывать - они все объявлены за пределами процитированного куска и не совсем понятно, что кто из них значит. Трал там явно в пунктах, причем пятизначных для пятизначного брокера, четырехзначных - для четырехзначного. Я так понимаю, TrailingStop - это величина отката, на котором закрываем. TrailingStart - это профит в пунктах, после которого начинаем тралить, TrailingStep - шаг фиксации "максимума". А дальше там есть вопросы по тейкам и стопам, например: они, вероятно, индивидуальные у всех ордеров, вы с ними как хотите поступать? Ну и в целом, код так себе: перезапуск советника с этим кодом приведет к поломке логики трала. Поэтому проще описать, чего вы хотите. Написать это проще с нуля. Вот его параметры extern string txt1="Виртуальный Трейлинг"; //. extern bool virtualTral = true;//Виртуал Трейлинг input double VTrailingStop = 10.0; // Длина трала input double VTrailingStart = 5.0; // Минимальная прибыль для старта input double VTrailingStep = 1.0; // Шаг трала так же в поинт умножен Хотел, чтобы он отдельно работал от стоплоса и профита, как обычный классический тралл. У меня есть трал, но у него все видно, и постоянные уведомления модификации, и не хочется чтобы конфликтовал. Например: когда просадка, то нужно удалять тейки и стопы чтобы не мешали Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 Я хотел примерно так сделать, это первая часть на покупку double SetPoint=g_Point; int P=0; if(virtualTral && VTrailingStart>0 && TrailingStep<VTrailingStart) { double rtb=rata_price(0),tr=0; for(int i=0; i<OrdersTotal(); i++) { P=OrderSelect(iTrade,SELECT_BY_POS,MODE_TRADES); if(OrderType()==OP_BUY && OrderSymbol()==Symbol()) { tr=rtb; } else { tr=OrderOpenPrice(); } if(Bid-tr>VTrailingStart*SetPoint) { if(Bid-((VTrailingStart-TrailingStep)*SetPoint) > OrderStopLoss()) { P=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-((VTrailingStart-TrailingStep)*SetPoint),OrderTakeProfit(),0,Green); } Изменено 5 января, 2023 пользователем Lexa000 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 8 минут назад, Lexa000 сказал: Я хотел примерно так сделать, это первая часть на покупку double SetPoint=g_Point; int P=0; if(virtualTral && VTrailingStart>0 && TrailingStep<VTrailingStart) { double rtb=rata_price(0),tr=0; for(int i=0; i<OrdersTotal(); i++) { P=OrderSelect(iTrade,SELECT_BY_POS,MODE_TRADES); if(OrderType()==OP_BUY && OrderSymbol()==Symbol()) { tr=rtb; } else { tr=OrderOpenPrice(); } if(Bid-tr>VTrailingStart*SetPoint) { if(Bid-((VTrailingStart-TrailingStep)*SetPoint) > OrderStopLoss()) { P=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-((VTrailingStart-TrailingStep)*SetPoint),OrderTakeProfit(),0,Green); } Ну примерно так и надо, если функция rata_price возвращает уровень безубытка всей позиции. Только непонятно, зачем вот этот кусок { tr=rtb; } else { tr=OrderOpenPrice(); } Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 5 минут назад, Rigal сказал: Ну примерно так и надо, если функция rata_price возвращает уровень безубытка всей позиции. Только непонятно, зачем вот этот кусок { tr=rtb; } else { tr=OrderOpenPrice(); } Этот кусок относится к коду rata_price, а rata_price относится к модификации ордеров Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 5 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 5 января, 2023 Какая-то каша из невнятных формулировок и обрывков кода, если честно. Я не буду вам мешать. Если не справитесь - напишите здесь, чего вы хотите. Желательно без упоминания, чего еще у вас есть, и как оно работает, сфокусируйтесь на конкретной задаче. Я потрачу 15 минут, накидаю. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Lexa000 Опубликовано 6 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 6 января, 2023 5 часов назад, Rigal сказал: Какая-то каша из невнятных формулировок и обрывков кода, если честно. Я не буду вам мешать. Если не справитесь - напишите здесь, чего вы хотите. Желательно без упоминания, чего еще у вас есть, и как оно работает, сфокусируйтесь на конкретной задаче. Я потрачу 15 минут, накидаю. Тот виртуальный трал написан для одного ордера отдельно от других сопровождаемый и закрывающийся в профит, а мне нужно чтоб сопровождал все ордера открытые в одном направлении и закрывал по общему стопу в профите, если открытые ордера в плюсе, то они перекрываются стопом и сопровождаются для увеличения профита и закрываются при откате цены назад Изменено 6 января, 2023 пользователем Lexa000 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 6 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 6 января, 2023 7 часов назад, Lexa000 сказал: Тот виртуальный трал написан для одного ордера отдельно от других сопровождаемый и закрывающийся в профит, а мне нужно чтоб сопровождал все ордера открытые в одном направлении и закрывал по общему стопу в профите, если открытые ордера в плюсе, то они перекрываются стопом и сопровождаются для увеличения профита и закрываются при откате цены назад //+------------------------------------------------------------------+ //| Trailer.mq4 | //| Copyright 2022, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict input double VTrailingStartPips = 10.0; //Start trailing, pips input double VTrailingStopPips = 10.0; //Traling stop, pips input double VTrailingStepPips = 1.0; //Trailing step, pips double trailingStartDouble, trailingStopDouble, trailingStepDouble; double maxProfitDistance[] = {0.0, 0.0}; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { string baseCurrency = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_BASE); string quoteCurrency = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_PROFIT); int pointsInPip = (Digits == 3 || Digits == 5) ? 10 : 1; if(baseCurrency == "XAU" || quoteCurrency == "XAU") pointsInPip = Digits == 2 ? 10 : 1; double pip = pointsInPip * Point(); trailingStartDouble = VTrailingStartPips * pip; trailingStopDouble = VTrailingStopPips * pip; trailingStepDouble = VTrailingStepPips * pip; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { double lots[] = {0.0, 0.0}; double profit[] = {0.0, 0.0}; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol()) { lots[OrderType()] += OrderLots(); profit[OrderType()] += OrderProfit() + OrderSwap() + OrderCommission(); } } for(int type = OP_BUY; type <= OP_SELL; type++) { if(lots[type] > DBL_EPSILON) { //we have open orders of this type double profitDistance = profit[type] / lots[type] / SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE) * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE); if(maxProfitDistance[type] > 0.0 && maxProfitDistance[type] - profitDistance >= trailingStopDouble) { CloseAll(type); } else if(profitDistance >= trailingStartDouble) { double stepRoundedProfitDistance = trailingStartDouble + MathFloor((profitDistance - trailingStartDouble) / trailingStepDouble) * trailingStepDouble; maxProfitDistance[type] = MathMax(maxProfitDistance[type], stepRoundedProfitDistance); } } else { maxProfitDistance[type] = 0.0; } } } //+------------------------------------------------------------------+ void CloseAll(int _type) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderType() == _type) { RefreshRates(); if(!OrderClose(OrderTicket(), OrderLots(), (_type == OP_BUY ? Bid : Ask), 0, clrPurple)) Print("Failed to close ticket #", OrderTicket(), ": ", GetLastError()); } } } Пипсы в настройках гарантированно старые, аналог четырехзначных. Все остальное тривиально Изменено 6 января, 2023 пользователем Rigal 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
ademen Опубликовано 13 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 13 января, 2023 Есть диапазон такого типа, в настройках задается к-во колен и процент риска. Советник выставляет на красной линии sell limit или sell stop, на голубой buy stop или buy limit При активации sell stop, и потом buy limit - на красной линии снова выставится ордер на продажу, потом при активации его на голубой - ордер на покупку и так указанное к-во колен (бай и селл считаются вместе). Когда у нас выставлено максимальное к-во колен (например 4 из 4) - на противоположной границе канала должны быть закрыты все ордера, убыток должен получиться такой, который указан в настройках (то-есть нужно так рассчитать лот, что бы прийдя к границе, у нас был указанный убыток). Мой код выглядит так: Спойлер double getStartLot(double channel_w) { double loss = AccountBalance() * inp_max_lossPres / 100; Print("Max loss in balance is " + (string)loss); double prev_t = 0; double profit_t = 0; double profit_b; double profit_s; double l = 0; double totalSumLot_0 = 0; double totalSumLot_1 = 0; for(double j = 0; j < 1000; j++) { profit_t = 0; profit_b = 0; profit_s = 0; l = l+ 0.01; for(int i = 0; i < inp_max_levels; i++) { //прибавим к виртуальном бай и селл условное к-во лотов поочередно if(i % 2 == 0) totalSumLot_0 += (l * MathPow(inp_mult_grid, i)); else totalSumLot_1 += (l * MathPow(inp_mult_grid, i)); } double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); profit_b = totalSumLot_0 * tickValue * channel_w; profit_s = totalSumLot_1 * tickValue * channel_w; profit_t = MathAbs(profit_b - profit_s); //если профит больше или равно нужным потерям - остановимся на этом лоте if(profit_t >= loss) { Print("lot: " + (string)l + " loss: " + (string)prev_t); Print("profit_b: " + profit_b); Print("profit_s: " + profit_s); Print("totalSumLot_0: " + totalSumLot_0); Print("totalSumLot_1: " + totalSumLot_1); return (l); } } return (-1); } Но, срабатывает не точно возле нужной границы Возможно есть мнения как решить мой кейс? Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 13 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 13 января, 2023 1 час назад, ademen сказал: Есть диапазон такого типа, в настройках задается к-во колен и процент риска. Советник выставляет на красной линии sell limit или sell stop, на голубой buy stop или buy limit При активации sell stop, и потом buy limit - на красной линии снова выставится ордер на продажу, потом при активации его на голубой - ордер на покупку и так указанное к-во колен (бай и селл считаются вместе). Я немного потерялся. На красной линии нельзя выставить sell limit или sell stop - выбор зависит от того, где цена. Я читаю условие, как канал, внутри которого находится цена - и мне непонятно, как правильно прочитать: цена огораживается лимитками, или стопами? Но абстрагируясь от точной логики: одна из причин, по которой убыток может не попадать в расчеты - своп и комиссия? 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
ademen Опубликовано 13 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 13 января, 2023 4 минуты назад, Rigal сказал: Я немного потерялся. На красной линии нельзя выставить sell limit или sell stop - выбор зависит от того, где цена. Я читаю условие, как канал, внутри которого находится цена - и мне непонятно, как правильно прочитать: цена огораживается лимитками, или стопами? В зависимости от того, где цена - мы выставляем той или иной вид ордера. Цена снизу огораживается снизу - лимитками, а сверху - стопами Примерно так должно отработать, если у нас выставлено макс колен = 4 и убыток 10% (баланс 1 000 долл) 18 минут назад, Rigal сказал: Но абстрагируясь от точной логики: одна из причин, по которой убыток может не попадать в расчеты - своп и комиссия? В тестере я открывал в пределах одного дня и счет без комиссий, поэтому проблема скорее всего именно в алгоритме. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 13 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 13 января, 2023 3 часа назад, ademen сказал: В зависимости от того, где цена - мы выставляем той или иной вид ордера. Цена снизу огораживается снизу - лимитками, а сверху - стопами Примерно так должно отработать, если у нас выставлено макс колен = 4 и убыток 10% (баланс 1 000 долл) В тестере я открывал в пределах одного дня и счет без комиссий, поэтому проблема скорее всего именно в алгоритме. внизу нельзя огородить sell limit, лимитка на продажу может быть выставлена только выше текущей цены. Соответственно, снизу - только на покупку. Получается, это не в разных направлениях ордера... сверху - покупка на пробой, снизу - сразу следующее колено в покупку лимиткой. И такую же конструкцию можно вкрячить для продаж, сразу две отложки вокруг цены. Но тогда я не особенно понимаю, какая там дальше логика? 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
ademen Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 8 часов назад, Rigal сказал: внизу нельзя огородить sell limit, лимитка на продажу может быть выставлена только выше текущей цены. Да, верно, должно быть sell stop на третьем ордере 8 часов назад, Rigal сказал: Но тогда я не особенно понимаю, какая там дальше логика? Логики нет, статистику собираю. Вроде алгоритм должен быть не сложный: смоделировать движения цены в канале и посчитать лот, убыток, но на практике у меня не получается, как ни пробовал. Игорь, может есть идея как сделать? Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 6 часов назад, ademen сказал: Да, верно, должно быть sell stop на третьем ордере Логики нет, статистику собираю. Вроде алгоритм должен быть не сложный: смоделировать движения цены в канале и посчитать лот, убыток, но на практике у меня не получается, как ни пробовал. Игорь, может есть идея как сделать? я не про ту логику. Я пытаюсь понять, что хочется сделать - и пока не понял, честно. Давай попробуем в общих терминах, я попытаюсь описать, что я пока понял, поправляй: - канал, где синяя линия выше текущей цены, а красная - ниже Вариант один: - мы выставляем на красной селл стоп и бай лимит. На синей, соответственно, бай стоп и селл лимит - срабатывают ордера не одновременно: сначала срабатывает стоп, потом лимит (потому, что они активируются разными сторонами цены) - После того, как пара сработала, у нас общая прибыль по этой паре в пунктах всегда равна текущему спреду (поскольку открыты они по одной и той же цене, а закрывать их надо по разным сторонам текущей цены, с разницей на спред) - ну и комиссия и капающий своп - После того, как пара сработала, цена может остаться за границей сине-красного канала, или вернуться в него - дальше понимание обрывается Вариант два: - когда у нас ноль ордеров, мы выставляем два: на синей мы выставляем бай стоп, на красной - селл стоп (судя по вот этому рисунку) 20 часов назад, ademen сказал: - после срабатывания ордера любой стороны, мы открываем новый на противоположной (убеждаемся, что он открыт) - до превышения заданного числа колен - требуется посчитать лотность так, чтобы это число колен означало убыток определенной величины Если речь о втором варианте, то задача не решается в общем виде, потому, что убыток будет в любой момент зависеть от траектории цены: для четного количества сделок в рынке убыток будет равен общему лоту помножить на (ширину канала + спред), помножить на цену тика, поделить на величину тика, плюс комиссия и свопы. То есть, когда в рынке четное количество ордеров, убыток будет расти только за счет свопов и расширения спреда. При нечетном количестве сделок в рынке, убыток тот же для ближайшго четного набора вниз, плюс плавающий убыток, или прибыль непарной позиции - которая ничем не ограничена. Она, конечно, будет ограничена по убытку очередным парным ордером, если он разрешен. Теперь немного о том, как можно упростить модель Пару ордеров можно заменить одним ордером со стопом - потому, что пара ордеров образует лок, который НИКОГДА не выйдет в профит, зато будет копить свопы до закрытия (и отрицательное плечо свопа у любого брокера ВСЕГДА больше положительного, то есть кумулятивный своп этой пары - отрицателен). Поправляй, если я где-то что-то не так понял, или разжуй яснее, я все это наощупь комментирую Изменено 14 января, 2023 пользователем Rigal 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 Если я правильно понимаю идею, хочется дождаться выхода из этого канала и закрыть прибыль на удаление от канала. Эта идея не реализуется накоплением пар ордеров одинаковой величины. Нужно или использовать вдвое больший лот на втором ордере и дальше (1-2-2-2-...), чтобы каждый следующий выход имел совокупный вес в сторону пробоя равный исходному лоту Либо, куда более осмысленно, закрывать предыдущий ордер стопом при открытии нового - тогда лот тот же можно использовать. Это легко визуализировать, если вспомнить, что стоп открытой позиции - это как раз стоп ордер в противоположном направлении. Изменено 14 января, 2023 пользователем Rigal 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 Написал это все, перечитал еще раз исходное сообщение и, мне кажется, понял, что хочется посчитать: лот ордера, при котором заданное количество ордеров на одной стороне канала, закрытое на другой стороне канала, принесет заданный убыток. Эта задача решается так: PnL = L * ChannelWidth * TickValue / TickSize Соответственно, L = PnL * TickSize / ChannelWidth / TickValue Где L = это совокупный лот позиции. Для ордеров равной лотности L = lots * N, где N - заданное количество колен Глядя в код, я вижу, что там используется экспонента, то есть лотность колен может расти. Соответственно, для множителя колена k: L = lots * (k^0 + k^1 + k^2 + ... + k^N-1) Отсюда lots = L / (k^0 + k^1 + k^2 + ... + k^N-1) Если используется более сложный подход к вариации лотности, его по-прежнему можно свернуть в некую последовательность, которая будет выстраиваться для заданного числа колен, вынести стартовый лот за скобку и решить уравнение. глядя на код выше, опять же, попытаюсь накидать, как может выглядеть такое вычисление в коде: input int StepLimit = 4; //Лимит количества колен input double LotMultiplier = 1.6; //Множитель лота double lotCumulativeMultiplier = 0.0; //посчитаем кумулятивный множитель для колен один раз на инициализации, просто ради оптимизации double minLot, maxLot, lotStep; //константы, вытащим их один раз int lotPrecision = 2; int OnInit() { .... lotCumulativeMultiplier = 1.0; //первое колено множится на один for(int i = 1; i < StepLimit; i++) //пропускаем нулевую степень, она добавлена предыдущей строчкой lotCumulativeMultiplier += MathPow(LotMultiplier, i); minLot = SymbolInfo(Symbol(), MODE_MINLOT); maxLot = SymbolInfo(Symbol(), MODE_MAXLOT); lotStep = SymbolInfo(Symbol(), MODE_LOTSTEP); //пишу по памяти, константы MODE_ перепроверить! if(lotStep >= 0.1) lotPrecision = 1; if(lotsStep >= 1.0) lotPrecision = 0; .... } double getStartLot(double channel_w) { //я предполагаю, что ширина канала выше - в абсолютных единицах. Не в поинтах и не в пипсах double loss = AccountBalance() * inp_max_lossPres / 100; // сохранил, пересчет из процентов в деньги double totalLots = loss * SymbolInfo(Symbol(), MODE_TICKSIZE) / channel_w / SymbolInfo(Symbol(), MODE_TICKVALUE); // проверить константы, пишу прямо на сайте, могу перепутать MODE_TICKSIZE и проч double startLots = totalLots / lotCumulativeMultiplier; //теперь превратим это в приемлемое значение лота. Распишу в несколько строк, хотя можно свернуть в одну startLots = MathFloor(startLots / lotStep) * lotStep; startLots = MathMax(startLots, minLot); startLots = MathMin(startLots, maxLot); return (NormalizeDouble(startLots, lotPrecision); } Это вычисление лотности будет работать очень быстро, но имеет сомнительную точность, по двум причинам: - при вычислении кумулятивного множителя мы не учитывали необходимость округлять лотность на каждом колене. Соответственно, то, как этот лот будет округляться, влияет на результат. Сравнительно пуленепробиваемый подход - если мы всегда округляем до ближайшего кратного шагу лотности значения вниз (что реализовано в коде выше, строчка с MathFloor) - тогда мы гарантируем, что заданная величина убытка никогда не будет превышена. - мы в любом случае вынуждены округлять финальный результат В любом случае, нам нужно принять решение о том, какого рода ошибку мы готовы принять. Например, мы не хотим, чтобы наш убыток превысил заданную величину - тогда код выше будет работать прекрасно, при условии округления лота на каждом колене вниз. Если же мы хотим максимально соблюсти геометрию сетки на каждом шаге, округляя лотность в ближайшую сторону (иногда вверх) - нам придется добавить дополнительный while цикл, в котором мы будем пересчитывать реальную лотность на каждом шаге и проверять ее на непревышение totalLots, понижать при необходимости стартовый лот на lotStep и повторять итерацию проверки. Особый случай - если старт минлотом превышает ожидаемый totalLots - здесь, видимо, нужно возвращать ноль и обрабатывать этот результат в точке принятия торговых решений. Примерно так: input int StepLimit = 4; //Лимит количества колен input double LotMultiplier = 1.6; //Множитель лота double lotCumulativeMultiplier = 0.0; //посчитаем кумулятивный множитель для колен один раз на инициализации, просто ради оптимизации double minLot, maxLot, lotStep; //константы, вытащим их один раз int lotPrecision = 2; int OnInit() { .... lotCumulativeMultiplier = 1.0; //первое колено множится на один for(int i = 1; i < StepLimit; i++) //пропускаем нулевую степень, она добавлена предыдущей строчкой lotCumulativeMultiplier += MathPow(LotMultiplier, i); minLot = SymbolInfo(Symbol(), MODE_MINLOT); maxLot = SymbolInfo(Symbol(), MODE_MAXLOT); lotStep = SymbolInfo(Symbol(), MODE_LOTSTEP); //пишу по памяти, константы MODE_ перепроверить! if(lotStep >= 0.1) lotPrecision = 1; if(lotsStep >= 1.0) lotPrecision = 0; .... } double getStartLot(double channel_w) { //я предполагаю, что ширина канала выше - в абсолютных единицах. Не в поинтах и не в пипсах double loss = AccountBalance() * inp_max_lossPres / 100; // сохранил, пересчет из процентов в деньги double totalLots = loss * SymbolInfo(Symbol(), MODE_TICKSIZE) / channel_w / SymbolInfo(Symbol(), MODE_TICKVALUE); // проверить константы, пишу прямо на сайте, могу перепутать MODE_TICKSIZE и проч double startLots = NormalizeLots(totalLots / lotCumulativeMultiplier) + lotStep; //здесь намеренно прибавим lotStep, чтобы итерировать вниз на следующем шаге верификации, до полного удовлетворения while(true) { double sumLots = startLots; for(int i = 1; i < StepLimit; i++) sumLots += NormalizeLots(startLots * MathPow(LotMultiplier, i)); if(sumLots <= totalLots) break; startLots -= lotStep; } return (startLots); } double NormalizeLots(double lots) { return (NormalizeDouble(MathMin(MathMax(MathRound(lots / lotStep) * lotStep, minLot), maxLot), lotPrecision)); } Хочется отдельно отметить, что в редких случаях с брокерами-извращенцами, у которых minLot не равен lotStep на этот код нужно будет глянуть с пристрастием. Я не очень понимаю, каковы ожидания в такой комбинации, но предпринял максимум усилий, чтобы обработать эту ситуацию правильно. Изменено 14 января, 2023 пользователем Rigal 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
ademen Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 9 часов назад, Rigal сказал: Вариант два: - когда у нас ноль ордеров, мы выставляем два: на синей мы выставляем бай стоп, на красной - селл стоп (судя по вот этому рисунку) Игорь, второй вариант верный. На рисунку два стоп ордера потому что цена на момент выставления была между линиями. 9 часов назад, Rigal сказал: сли я правильно понимаю идею, хочется дождаться выхода из этого канала и закрыть прибыль на удаление от канала. Эта идея не реализуется накоплением пар ордеров одинаковой величины. Нужно или использовать вдвое больший лот на втором ордере и дальше (1-2-2-2-...), чтобы каждый следующий выход имел совокупный вес в сторону пробоя равный исходному лоту Либо, куда более осмысленно, закрывать предыдущий ордер стопом при открытии нового - тогда лот тот же можно использовать. Это легко визуализировать, если вспомнить, что стоп открытой позиции - это как раз стоп ордер в противоположном направлении. Да, есть мульт, деф значения 2. Когда нет набранного максимального к-ва ордеров - на выходе из канала по обоих сторонах выставлен сл и тп всех - выше сл всех продаж и тп всех покупок, ниже - наоборот. Если на верхней границы открыли последний ордер - выше границы будет тп всех покупок и сл всех продаж, а на нижней границе сл всех покупок и тп всех продаж. Игорь, спасибо за два интересных варианта кода, только ночью удалось зайти посмотреть, но сразу вижу что написано интересно и умно, спасибо за возможность снова поучиться у тебя. 9 часов назад, Rigal сказал: //я предполагаю, что ширина канала выше - в абсолютных единицах. Не в поинтах и не в пипсах Что ты имеешь в виду? В абсолютных значения, имеется ввиду без знака „-“? В моем варианте кода используется пипс (5 знаков). Я на вскидку попробовал первый вариант запустить, уж сильно интересно он был написан, но пока при любых значениях - старт лот 0.01, возможно из-за того что я передаю пипсы, или уже в полу сне. Завтра на работу возьму планшета и снова попробую разобраться. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 42 минуты назад, ademen сказал: Что ты имеешь в виду? В абсолютных значения, имеется ввиду без знака „-“? В моем варианте кода используется пипс (5 знаков). Я имею в виду, дистанция Например, между 1.22220 и 1.11110 дистанция в 1111 пипса, 11110 поинтов и абсолютная дистанция 0.11110 Я написал, полагая, что ширина канала передается абсолютной величиной. Если она в пипсах - домножь на величину пипса. Второй вариант кода точнее и ненамного затратнее. Кроме того, там удобная функция нормализации лота (или ты можешь использовать свою без потери работоспособности кода). Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 14 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 14 января, 2023 47 минут назад, ademen сказал: выше сл всех продаж и тп всех покупок Ты только помни, что сл продажи - это покупка. А тп покупки - это продажа. Первые исполняются по аску, вторые - по биду. Поэтому, если поставить их все в одну точку, могут исполниться стопы и не исполниться тейки Ссылка на сообщение Поделиться на другие сайты More sharing options...
ademen Опубликовано 15 января, 2023 Поделиться Доработка советников: общая тема Опубликовано 15 января, 2023 11 часов назад, Rigal сказал: Второй вариант кода точнее и ненамного затратнее. Кроме того, там удобная функция нормализации лота (или ты можешь использовать свою без потери работоспособности кода). Игорь, я проверил оба варианта, но к сожалению ни один не смог закрыть все сделки на противоположной стороне канала, или близко от него. Возможно проблема в том, что позиции разнонаправленны? Я не увидел, где этот пункт обрабатывается в коде (если он есть - укажи, пожалуйста, на строчку, тогда будет яснее работа алгоритма). Твой алгоритм скорее всего классно бы работал в ситуации когда у нас сетка с бай или селл ордеров, у меня же идет чередование бай и селл Ссылка на сообщение Поделиться на другие сайты More sharing options...
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти