Сделал блок, в котором происходит частичное закрытие позции, при достижении ценой определённого уровня:
Но проблема в том, что этот кусок отрабатывает каждый раз, как цена достигает этого уровня, т.к. образом, в итоге, у меня закрывается весь обьем ))
Как сделать так, что бы этот закрытие произошло единожды и больше не отрабатывалось для данного ордера ?
rf как то так, переменную flag необходимо сбрасывать при открытии этого ордера
//+------------------------------------------------------------------+ //| тест.mq4 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict bool flag=true; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS)) { if(OrderType()==1) { Lot_61_8=OrderLots()*Lot_Percent_61_8/100;if(Lot_61_8>OrderLots() || Lot_61_8<0.01){Lot_61_8=OrderLots();if(Lot_61_8>100)Lot_61_8=100;} Lot_61_8=(NormalizeLot(Lot_61_8,False)); Ask_Value_61_8=OrderOpenPrice()-(61.8*OrderOpenPrice())/10000; if(Lot_61_8>0 && flag) { error=OrderClose(OrderTicket(),Lot_61_8,MarketInfo(Symbol(),MODE_BID),20,CLR_NONE); if(error)flag=false; else PrintFormat("Ошибка № %d закрытия ордера. Тикет: %d",GetLastError(),OrderTicket()); } } } } } //+------------------------------------------------------------------+
Сделал блок, в котором происходит частичное закрытие позции, при достижении ценой определённого уровня:
for (int i=0; i<OrdersTotal(); i++)
{
if (OrderSelect(i, SELECT_BY_POS))
{
if (OrderType()==1)
{
Lot_61_8 = OrderLots()*Lot_Percent_61_8/100;if(Lot_61_8>OrderLots()||Lot_61_8<0.01){Lot_61_8 = OrderLots();if(Lot_61_8>100)Lot_61_8=100;}
Lot_61_8 = (NormalizeLot(Lot_61_8, False));
Ask_Value_61_8=OrderOpenPrice()-(61.8*OrderOpenPrice())/10000;
if (Lot_61_8>0)
error=OrderClose(OrderTicket(), Lot_61_8, MarketInfo(Symbol(), MODE_BID), 20, CLR_NONE);
}
}
}
Но проблема в том, что этот кусок отрабатывает каждый раз, как цена достигает этого уровня, т.к. образом, в итоге, у меня закрывается весь обьем ))
Как сделать так, что бы этот закрытие произошло единожды и больше не отрабатывалось для данного ордера ?
Сделал блок, в котором происходит частичное закрытие позции, при достижении ценой определённого уровня:
Но проблема в том, что этот кусок отрабатывает каждый раз, как цена достигает этого уровня, т.к. образом, в итоге, у меня закрывается весь обьем ))
Как сделать так, что бы этот закрытие произошло единожды и больше не отрабатывалось для данного ордера ?
Ну и... ?
Какая логика, такой и код, так и будет работать.
....
У каждого ордера есть номер - тикет. Тикет ордера при частичном закрытии поменяется. Так что запоминать нужно будет только при удачном частичном закрытии.
Если error>0, то это и будет номером ордера, т.е. тикетом
error=OrderClose(OrderTicket(), Lot_61_8, MarketInfo(Symbol(), MODE_BID), 20, CLR_NONE);
for (int i=0; i<OrdersTotal(); i++)
с конца начни перебор
с флажками это примитив. проверьте в истории по комментарию ордера какая часть уже закрыта.
советники не должны зависиь от переменных которые могут сброситься при перезапуске. я гдето в похожей теме давал тут мой код с поиском частей и проверкой какая часть закрыта.
Написал такую функцию, на ECN работает без проблем. Пользуйтесь на здоровье)
input int tr = 250; // Distance to close input int mn = 16384; // Magic number input color CloseColor = clrLime; // Close color input color StopColor = clrTomato; // Stop color
// ======================================================================================================== // = Функция частичного закрытия позиции (c) Kino 2016 = // = = // = По достижении определенного уровня закрывается половина позиции и подтягивается стоп в безубыток. = // = По достижении следующего уровня опять половина и подтяжка стопа. И т.д. пока не закроется вся поза. = // = tr расстояние закрытия в пунтах позиции = // ======================================================================================================== bool ClosePartPosition (int tr) { double ml = MarketInfo(Symbol(),MODE_LOTSTEP); double close_lot; int cnt = OrdersTotal(); for (int i=cnt-1; i>=0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; //Опционально if (OrderSymbol() != Symbol()) continue; //Опционально if (OrderMagicNumber() != mn) continue; close_lot=NormalizeDouble(OrderLots()/2,2); if (close_lot<ml) close_lot=ml; if (OrderType()==OP_BUY) { if (OrderStopLoss()==0 || OrderStopLoss() < OrderOpenPrice()) { if ((MarketInfo(OrderSymbol(),MODE_BID) - (OrderOpenPrice() + (OrderCommission()*MarketInfo(OrderSymbol(),MODE_POINT)) + (OrderSwap()*MarketInfo(OrderSymbol(),MODE_POINT)))) > (tr*MarketInfo(OrderSymbol(),MODE_POINT))) { Print(Symbol()," ClosePartPosition. Move stop and close half"); bool ModifyBuy_1 = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble((MarketInfo(OrderSymbol(),MODE_BID) - tr*MarketInfo(OrderSymbol(),MODE_POINT)),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),OrderTakeProfit(),0,StopColor); if(!ModifyBuy_1) Print(Symbol()," ClosePartPosition. OrderModify Buy fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderModify Buy successfully"); bool CloseBuy_1 = OrderClose (OrderTicket(),close_lot,MarketInfo(OrderSymbol(),MODE_BID),Slippage,CloseColor); if(!CloseBuy_1) Print(Symbol()," ClosePartPosition. OrderClose Buy fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderClose Buy successfully"); } } else { if ((MarketInfo(OrderSymbol(),MODE_BID) - OrderStopLoss()) > (tr*MarketInfo(OrderSymbol(),MODE_POINT)*2)) { Print(Symbol()," ClosePartPosition. Move stop and close half"); bool ModifyBuy_2 = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble((MarketInfo(OrderSymbol(),MODE_BID) - tr*MarketInfo(OrderSymbol(),MODE_POINT)),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),OrderTakeProfit(),0,StopColor); if(!ModifyBuy_2) Print(Symbol()," ClosePartPosition. OrderModify Buy fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderModify Buy successfully"); bool CloseBuy_2 = OrderClose (OrderTicket(),close_lot,MarketInfo(OrderSymbol(),MODE_BID),Slippage,CloseColor); if(!CloseBuy_2) Print(Symbol()," ClosePartPosition. OrderClose Buy fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderClose Buy successfully"); } } } if (OrderType()==OP_SELL) { if (OrderStopLoss()==0 || OrderStopLoss() > OrderOpenPrice()) { if (((OrderOpenPrice() - (OrderCommission()*MarketInfo(OrderSymbol(),MODE_POINT)) - (OrderSwap()*MarketInfo(OrderSymbol(),MODE_POINT))) - MarketInfo(OrderSymbol(),MODE_ASK) ) > (tr*MarketInfo(OrderSymbol(),MODE_POINT))) { Print(Symbol()," ClosePartPosition. Move stop and close half"); bool ModifySell_1 = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble((MarketInfo(OrderSymbol(),MODE_ASK) + tr*MarketInfo(OrderSymbol(),MODE_POINT)),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),OrderTakeProfit(),0,StopColor); if(!ModifySell_1) Print(Symbol()," ClosePartPosition. OrderModify Sell fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderModify Sell successfully"); bool CloseSell_1 = OrderClose (OrderTicket(),close_lot,MarketInfo(OrderSymbol(),MODE_ASK),Slippage,CloseColor); if(!CloseSell_1) Print(Symbol()," ClosePartPosition. OrderClose Sell fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderClose Sell successfully"); } } else { if (OrderStopLoss()-MarketInfo(OrderSymbol(),MODE_ASK)>tr*MarketInfo(OrderSymbol(),MODE_POINT)*2) { Print(Symbol()," ClosePartPosition. Move stop and close half"); bool ModifySell_2 = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble((MarketInfo(OrderSymbol(),MODE_ASK) + tr*MarketInfo(OrderSymbol(),MODE_POINT)),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),OrderTakeProfit(),0,StopColor); if(!ModifySell_2) Print(Symbol()," ClosePartPosition. OrderModify Sell fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderModify Sell successfully"); bool CloseSell_2 = OrderClose (OrderTicket(),close_lot,MarketInfo(OrderSymbol(),MODE_ASK),Slippage,CloseColor); if(!CloseSell_2) Print(Symbol()," ClosePartPosition. OrderClose Sell fail #",GetLastError()); else Print(Symbol()," ClosePartPosition. OrderClose Sell successfully"); } } } } return (True); } //End
Посмотрите чем отличается комментарий свежего ордера и частичного закрытого. По комментарию можно отличить частично закрытый ордер.
А если частично закрытый закрылся ещё раз?
В комментарии частично закрытого ордера записан тикет ордера из которого он получился, можно отделить его, выделить ордер в истории, и т.д. по всей цепочке.
Можно не ходить по всей цепочке, а создать глобальные переменные привязанные к тикету и перебрасывать данные только с предыдущего ордера.

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Сделал блок, в котором происходит частичное закрытие позции, при достижении ценой определённого уровня:
for (int i=0; i<OrdersTotal(); i++)
{
if (OrderSelect(i, SELECT_BY_POS))
{
if (OrderType()==1)
{
Lot_61_8 = OrderLots()*Lot_Percent_61_8/100;if(Lot_61_8>OrderLots()||Lot_61_8<0.01){Lot_61_8 = OrderLots();if(Lot_61_8>100)Lot_61_8=100;}
Lot_61_8 = (NormalizeLot(Lot_61_8, False));
Ask_Value_61_8=OrderOpenPrice()-(61.8*OrderOpenPrice())/10000;
if (Lot_61_8>0)
error=OrderClose(OrderTicket(), Lot_61_8, MarketInfo(Symbol(), MODE_BID), 20, CLR_NONE);
}
}
}
Но проблема в том, что этот кусок отрабатывает каждый раз, как цена достигает этого уровня, т.к. образом, в итоге, у меня закрывается весь обьем ))
Как сделать так, что бы этот закрытие произошло единожды и больше не отрабатывалось для данного ордера ?