Частичное закрытие ордера - страница 2

 
Dmitry Fedoseev:

В комментарии частично закрытого ордера записан тикет ордера из которого он получился, можно отделить его, выделить ордер в истории, и т.д. по всей цепочке.

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

Мне первая Ваша идея больше понравилась с комментарием к ордеру - ну чтобы в глобальные переменные не записывать - анализировать только комментарий, ничего с ним не далая и всё.
 

 


extern string    General_settings        ="-------------------------------------------------------";

extern double Lots = 0.01;

extern int Delta = 1;

extern string    Order_settings          ="-------Настройки СЛ и ТП-------------------------------";

extern int TakeProfit = 500;

extern int StopLoss = 400;

extern string    Order_management        ="-------Настройки Риск Менеджмента----------------------";

extern bool fixed_sl=true;

extern int NoLoss = 100;

extern int NoLossFiboLevels = 60;

extern int NoLossProfit = 0;

extern string    st5                     ="-Настройки Дистанции и Процента для закрытия-----------"; 

extern bool Lot_Mode_Percent = true;

extern int Lot_Percent_23_6 = 5; 

extern int Lot_Percent_38_2 = 20; 

extern int Lot_Percent_50 = 30;

extern int Lot_Percent_61_8 = 40; 

extern string    st6                     ="-Веремя работы советника------------------------------"; 

extern int TimeStart = 01;             // Время начала работы советника

extern int TimeEnd = 23;               // Время окончания работы советника

extern int TimeStartMonday = 3;        // Время начало торговли в понидельник 

extern int TimeEndFriday = 17;         // Время после которого не торгуем в пятницу

// Глобальные переменные

int LastTradeTimeBuy = 0;      // Время последней открытой сделки

int LastTradeTimeSell = 0;

int LastTradeBuy = 0;      // Время последней открытой сделки

int LastTradeSell = 0;      // Время последней открытой сделки

int MagicNumber= 0;

double StopLossValue = 0;

#define HR2400 86400       // 24 * 3600

int      TimeOfDay(datetime when){  return( when % HR2400          );         }

datetime DateOfDay(datetime when){  return( when - TimeOfDay(when) );         }

datetime Today(){                   return(DateOfDay( TimeCurrent() ));       }

datetime Tomorrow(){                return(Today() + HR2400);                 }

datetime Yesterday(){               return( iTime(NULL, PERIOD_D1, 1) );      }

int tomorrow_day =0;

int current_day = 0;

int count_buy = 0;

int count_sell = 0;

//------- Внешние параметры модуля -----------------------------------

extern string _Parameters_b_Lot          = "- Параметры модуля расчёта лота----------------------";

extern int LotsWayChoice  = 1;    // Способ выбора рабочего лота:

                                  //  0-фиксированный,

                                  //  1-процент от депозита,

                                  //  2-фиксированно-пропорциональный,

                                  //  3-фракционно-фиксированный,

extern int LotsPercent    = 10;   // Процент от депозита

extern int LotsDeltaDepo  = 500;  // Коэффициент приращения депозита

extern int LotsDepoForOne = 500;  // Размер депозита для одного минилота

extern int LotsMax        = 1000; // Максимальное количество минилотов

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

//| expert start function                                            |

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

double fPreviousBid = 0;  // значение bid на предыдущем тике

string symb;

int OnInit()

{

   fPreviousBid = 0;

   return(INIT_SUCCEEDED);

}


void OnTick()

 {

  symb = _Symbol;

 

   Bkl();

 }

 

 

void Bkl() 

 {

 

   static datetime bodCurr; datetime bodPrev = bodCurr; bodCurr = DateOfDay( TimeCurrent() );

   bool isNewDay = bodPrev != bodCurr;

   if(isNewDay){

   int part_order_close_sell_23_6 = 0;

   };

 

if (TradeStatuse() > 0) return (0);

double SL=0,TP=0,NoLossTP=0,Current_Value,Bid_Value_23_6=0,Ask_Value_23_6=0,Bid_Value_38_2=0,Ask_Value_38_2=0,Bid_Value_50=0,Ask_Value_50=0,Bid_Value_61_8=0,Ask_Value_61_8=0,

Lot_23_6=0,

Lot_38_2=0,

Lot_50=0,

Lot_61_8=0,

Spread=Ask-Bid,

StopLevel=Point*MarketInfo(Symbol(),MODE_STOPLEVEL),

HighD1=iHigh(Symbol(),PERIOD_D1,1),

LowD1=iLow(Symbol(),PERIOD_D1,1),

HighD1Today=iHigh(Symbol(),PERIOD_D1,0),

LowD1Today=iLow(Symbol(),PERIOD_D1,0),

HighH4=iHigh(Symbol(),PERIOD_H4,1),

LowH4=iLow(Symbol(),PERIOD_H4,1),

HighH6=iHigh(Symbol(),PERIOD_H6,0),

LowH6=iLow(Symbol(),PERIOD_H6,0),

HighW1=iHigh(Symbol(),PERIOD_W1,1),

LowW1=iLow(Symbol(),PERIOD_W1,1),

CheckHiLivels = 0, CheckLowLivels = 0;


  static double max_23_6 = 0;

  static double max_38_2 = 0;

  static double max_50_0 = 0;

  static double max_61_8 = 0;


  static double min_23_6 = 0;

  static double min_38_2 = 0;

  static double min_50_0 = 0;

  static double min_61_8 = 0;

    static double high_day = 0;

  static double low_day = 0;

  high_day = iHigh(Symbol(), PERIOD_D1, 1);

  low_day = iLow(Symbol(), PERIOD_D1, 1);

int total = OrdersTotal(); // сколько всего ордеров открыто

   double fUpperLevel = iHigh(Symbol(), PERIOD_D1, 1) + Delta * Point();

   double fLowerLevel = iLow(Symbol(), PERIOD_D1, 1) - Delta * Point();

  double TodayHi = iHigh(Symbol(),PERIOD_D1,0);                          // Цена закрытия предпоследнего дня

  double TodayLow = iLow(Symbol(),PERIOD_D1,0);                         // Цена закрытия последнего дня

   if (TodayHi>fUpperLevel && Open[0] < fUpperLevel) CheckHiLivels = 1;

   if (TodayLow<fLowerLevel && Open[0] > fLowerLevel) CheckLowLivels = 1;

   bool Open_Bay = fPreviousBid > 0 && Bid > fUpperLevel && fPreviousBid <= fUpperLevel && CheckHiLivels == 1;

   bool Open_Sell = fPreviousBid > 0 && Bid < fLowerLevel && fPreviousBid >= fLowerLevel && CheckLowLivels == 1;

   // запоминаем текущий бид

   fPreviousBid = Bid;

int Ticket,cnt,Total=0;


   double spread=ask-bid; 

   int spread_points=(int)MathRound(spread/SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 

   comm=comm+"Вычисленный спред = "+(string)spread_points+" пунктов"; 

for(cnt=0;cnt<OrdersTotal();cnt++)

   {

   OrderSelect(cnt,SELECT_BY_POS);

   if(OrderSymbol()==Symbol())

      {

      Total++;

         Lot_23_6 = OrderLots()*Lot_Percent_23_6/100;if(Lot_23_6>OrderLots()||Lot_23_6<0.01){Lot_23_6 = OrderLots();if(Lot_23_6>100)Lot_23_6=100;}

         Lot_23_6 = (NormalizeLot(Lot_23_6, False));

         Lot_38_2 = OrderLots()*Lot_Percent_38_2/100;if(Lot_38_2>OrderLots()||Lot_38_2<0.01){Lot_38_2 = OrderLots();if(Lot_38_2>100)Lot_38_2=100;}

         Lot_38_2 = (NormalizeLot(Lot_38_2, False));         

         Lot_50 = OrderLots()*Lot_Percent_50/100;if(Lot_50>OrderLots()||Lot_50<0.01){Lot_50 = OrderLots();if(Lot_50>100)Lot_50=100;}

         Lot_50 = (NormalizeLot(Lot_50, False));        

         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));    



      if(OrderType()==OP_BUY)// long position is opened

         {

     max_23_6 = high_day + (MathAbs(high_day - low_day) / 4.236);

     max_38_2 = high_day + (MathAbs(high_day - low_day) / 2.582);

     max_50_0 = high_day + (MathAbs(high_day - low_day) / 1.960);

     max_61_8 = high_day + (MathAbs(high_day - low_day) / 1.618);


         if(Lot_38_2>0&& Bid> max_38_2) 

            {

            if(Lot_38_2>0){

            Print ("Частичное закрытие ордера Buy на уровне 32.2"); 

            OrderClose(OrderTicket(), Lot_38_2, Bid, 20, Blue);return(0);}

            return(0);

            }  

         if(Lot_50>0&&Bid > max_50_0) 

            {

            if(Lot_50>0){

            Print ("Частичное закрытие ордера Buy на уровне 50"); 

            OrderClose(OrderTicket(), Lot_50, Bid, 20, Blue);return(0);}


            return(0);

            }             

         if(Lot_61_8>0&&Bid > max_61_8) 

            {

            if(Lot_61_8 > 0){

            Print ("Частичное закрытие ордера Buy на уровне 61.8", Lot_61_8); 

            OrderClose(OrderTicket(), Lot_61_8, Bid, 20, Blue);return(0);}

            return(0);

            } 

                     

         if( Bid > OrderOpenPrice()+(NoLoss*Point) && NoLoss>0 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice()+(NoLoss*Point),Digits);

            if(!CompareDoubles(OrderStopLoss(),SL)){ 

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0);

            }

            return(0);

            }   

         if( Bid > max_23_6 && OrderStopLoss()<max_23_6 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() + (NoLossFiboLevels*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            Print ("Частичное закрытие ордера Buy на уровне 23.6"); 

            OrderClose(OrderTicket(), Lot_23_6, Bid, 20, Blue);return(0);            

            }            


            }     

            

                

   }

      if(OrderType()==OP_SELL)

      {


//--sell---------------------------------------------------------------------------------------------------------------------

     min_23_6 = low_day - (MathAbs(high_day - low_day) / 4.236);// Alert("min_23_6 ", min_23_6);

     min_38_2 = low_day - (MathAbs(high_day - low_day) / 2.582);

     min_50_0 = low_day - (MathAbs(high_day - low_day) / 1.960);

     min_61_8 = low_day - (MathAbs(high_day - low_day) / 1.618);// Alert("min_61_8 ", min_61_8);   



         if(Lot_38_2>0&&Ask < min_38_2) 

            {

            if(Lot_38_2>0){

            Print ("Частичное закрытие ордера Sell на уровне -38.2 ",Ask," Размер лота ",Lot_38_2); 

            OrderClose(OrderTicket(), Lot_38_2, Ask, 20, Blue);return(0);}


            }

         if(Lot_50>0&&Ask < min_50_0) 

            {

            if(Lot_50>0){

            Print ("Частичное закрытие ордера Sell на уровне -50 ",Ask," Размер лота ",Lot_50); 

            OrderClose(OrderTicket(), Lot_50, Ask, 20, Blue);return(0);}


            }                 

         if(Lot_61_8>0&& Ask<min_61_8) 

            {

            if(Lot_61_8>0){

            Print ("Частичное закрытие ордера Sell на уровне -61.8 ",Ask," Размер лота ",Lot_61_8); 

            OrderClose(OrderTicket(), Lot_61_8, Ask, 20, Blue);return(0);}


            }           

         if( Ask < OrderOpenPrice()-(Point*NoLoss) && NoLoss>0 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() - (NoLoss*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            }

   

            return(0);

            }

            if( Ask < min_23_6 && OrderStopLoss()> min_23_6 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() - (NoLossFiboLevels*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            Print ("Частичное закрытие ордера Sell на уровне -23.6 ",Ask," Размер лота ", Lot_23_6); 

            OrderClose(OrderTicket(), Lot_23_6, MarketInfo(Symbol(), MODE_ASK), 20, Blue);            

            }            


            }

          

   }

   }

   }

//+----Открытие позиций

int TradeTime=TimeDay(TimeCurrent());

int TradeTimeBuy=TimeDay(TimeCurrent());

int TradeTimeSell=TimeDay(TimeCurrent());

if(Total<1 )

   {

   if(Open_Bay && LastTradeTimeBuy!=TradeTimeBuy )

      {      

         SL = iLow(symb,PERIOD_D1,0);

         // Alert("(Bid-SL)*10000 ", (Bid-SL)*100000);

         if((Bid-SL)*100000>StopLoss){SL = Bid - (StopLoss*Point);}

         if(TakeProfit>0) TP = Ask + TakeProfit*Point;

         if(Bid-SL<StopLevel-Delta*Point) return(0);  // проверяем минимальный уровень стопов   

         Ticket=OrderSend(Symbol(),OP_BUY,GetSizeLot(),Ask + Spread ,20,SL,TP);

         if (Ticket > 0)                                                  

         {            

            LastTradeTimeBuy=TradeTimeBuy; // задаем время сделки, чтобы сегодня больше не торговать 

         }     

      return(0);

      }

//+----

   if(Open_Sell && LastTradeTimeSell!=TradeTimeSell)

           {  

         SL = iHigh(symb,PERIOD_D1,0);

         if((Ask+SL)*100000>StopLoss){SL = Ask + (StopLoss*Point);}

         if(TakeProfit>0) TP = Bid - TakeProfit*Point;

         if (SL-Ask<StopLevel-Delta*Point) return(0); // проверяем минимальный уровень стопов     

         Ticket = OrderSend(Symbol(),OP_SELL,GetSizeLot(),Bid - Spread,20,SL,TP);

         if (Ticket > 0)                                                  

         { 

            LastTradeTimeSell=TradeTimeSell;  // задаем время сделки, чтобы сегодня больше не торговать

         }    

         return(0);     

      }

   }

  // return(0);

 }

int TradeStatuse()

{

   if ((!IsTesting()) && IsStopped()) return (1); //--- Если не тестовый режим и советник приостановлен (IsStopped).

   if ((!IsTesting()) && !IsTradeAllowed()) return (2); //--- Если не тестовый режим и торговля заблокирована (IsTradeAllowed).

   if ((!IsTesting()) && IsTradeContextBusy()) return (3); //--- Если не тестовый режим и поток для выполнения торговых операции занят (IsTradeContextBusy).

   if (Hour() < TimeStartMonday + DayOfWeek() == 1) return (4); //--- Проверка на торговое время в понидельник.

   if (Hour() >= TimeEndFriday + DayOfWeek() == 5) return (5); //--- Проверка на торговое время в пятницу.

   if (TimeEnd < TimeStart) 

      {  

      if(Hour() >= TimeEnd && Hour() < TimeStart) return (6);

      }

   else

      {

      if ((Hour() < TimeStart) || (Hour() >= TimeEnd)) return (6); //--- Проверка на торговое время.

      }

   if ((DayOfWeek() == 0) || (DayOfWeek() == 6)) return (7); //--- Выходные, некоторые брокеры как RVD торговля начинаеться в воскресение вечером

   //---

   return(0);

}

double GetSizeLot()

{

  double dLot;

  if (LotsWayChoice==0) dLot=Lots;

  // фиксированный процент от депозита

  if (LotsWayChoice==1)

  {

    // dLot=MathCeil(AccountFreeMargin()/10000*LotsPercent)/10;

    dLot=MathFloor(AccountFreeMargin()/MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_MINLOT)*AccountLeverage()/100.0*LotsPercent) * MarketInfo(Symbol(),MODE_MINLOT);

  }

  // фиксированно-пропорциональный

  if (LotsWayChoice==2)

  {

    int k=LotsDepoForOne;

    for (double i=2; i<=LotsMax; i++)

    {

      k=k+i*LotsDeltaDepo;

      if (k>AccountFreeMargin())

      {

        dLot=(i-1)/10000; break;

      }

    }

  }

  // фракционно-фиксированный

  if (LotsWayChoice==3)

  {

    dLot=MathCeil((AccountFreeMargin()-LotsDepoForOne)/LotsDeltaDepo)/10;

  }

  if (dLot<0.01) dLot=0.01;

  if (dLot>100) dLot=100;

  return(dLot);

}



double NormalizeLot(double lo, bool ro=False, string sy="") {

  double l, k;

  if (sy=="" || sy=="0") sy=Symbol();

  double ls=MarketInfo(sy, MODE_LOTSTEP);

  double ml=MarketInfo(sy, MODE_MINLOT);

  double mx=MarketInfo(sy, MODE_MAXLOT);

  if (ml==0) ml=0.01;

  if (mx==0) mx=100;

  if (ls>0) k=1/ls; else k=1/ml;

  if (ro) l=MathCeil(lo*k)/k; else l=MathFloor(lo*k)/k;

  if (l<ml) l=ml;

  if (l>mx) l=mx;

  return(l);

}


bool CompareDoubles(double number1,double number2) 

  { 

   if(NormalizeDouble(number1-number2,8)==0) return(true); 

   else return(false); 

  } 

void NoLoss() { 

   int tip,Ticket; 

   double StLo,OSL,OOP; 

   for (int i=0; i<OrdersTotal(); i++) { 

      if (OrderSelect(i, SELECT_BY_POS)) { 

tip = OrderType(); 

  if (tip<2 && OrderSymbol()==Symbol()) { 

  OSL = NormalizeDouble(OrderStopLoss(),Digits); 

  OOP = NormalizeDouble(OrderOpenPrice(),Digits); 

  Ticket = OrderTicket(); 

     if (tip==OP_BUY) { 

        if (OSL>OOP) continue; 

        StLo = NormalizeDouble(OOP+Point,Digits); 

        if (NormalizeDouble((Bid-OOP)/Point,0)>=NoLoss) { 

           if (!OrderModify(Ticket,OOP,StLo,OrderTakeProfit(),0,White)) 

        Print("NoLoss Error ",GetLastError()," buy SL ",OSL,"->",StLo); 

        } 

     } 

     if (tip==OP_SELL) { 

        if (OSL<OOP) continue; 

        StLo = NormalizeDouble(OOP-Point,Digits); 

        if (NormalizeDouble((OOP-Ask)/Point,0)>=NoLoss) { 

           if (!OrderModify(Ticket,OOP,StLo,OrderTakeProfit(),0,White)) 

     Print("NoLoss Error ",GetLastError()," sell SL ",OSL,"->",StLo); 

        } 

  } 

      } 

   } 



 



такой вот код получился ... но частичная фиксация не корректно отратывает.. так и не получилось сделать условие для частичного закрытия ордера 

 
Sergey Lapshov:

 


extern string    General_settings        ="-------------------------------------------------------";

extern double Lots = 0.01;

extern int Delta = 1;

extern string    Order_settings          ="-------Настройки СЛ и ТП-------------------------------";

extern int TakeProfit = 500;

extern int StopLoss = 400;

extern string    Order_management        ="-------Настройки Риск Менеджмента----------------------";

extern bool fixed_sl=true;

extern int NoLoss = 100;

extern int NoLossFiboLevels = 60;

extern int NoLossProfit = 0;

extern string    st5                     ="-Настройки Дистанции и Процента для закрытия-----------"; 

extern bool Lot_Mode_Percent = true;

extern int Lot_Percent_23_6 = 5; 

extern int Lot_Percent_38_2 = 20; 

extern int Lot_Percent_50 = 30;

extern int Lot_Percent_61_8 = 40; 

extern string    st6                     ="-Веремя работы советника------------------------------"; 

extern int TimeStart = 01;             // Время начала работы советника

extern int TimeEnd = 23;               // Время окончания работы советника

extern int TimeStartMonday = 3;        // Время начало торговли в понидельник 

extern int TimeEndFriday = 17;         // Время после которого не торгуем в пятницу

// Глобальные переменные

int LastTradeTimeBuy = 0;      // Время последней открытой сделки

int LastTradeTimeSell = 0;

int LastTradeBuy = 0;      // Время последней открытой сделки

int LastTradeSell = 0;      // Время последней открытой сделки

int MagicNumber= 0;

double StopLossValue = 0;

#define HR2400 86400       // 24 * 3600

int      TimeOfDay(datetime when){  return( when % HR2400          );         }

datetime DateOfDay(datetime when){  return( when - TimeOfDay(when) );         }

datetime Today(){                   return(DateOfDay( TimeCurrent() ));       }

datetime Tomorrow(){                return(Today() + HR2400);                 }

datetime Yesterday(){               return( iTime(NULL, PERIOD_D1, 1) );      }

int tomorrow_day =0;

int current_day = 0;

int count_buy = 0;

int count_sell = 0;

//------- Внешние параметры модуля -----------------------------------

extern string _Parameters_b_Lot          = "- Параметры модуля расчёта лота----------------------";

extern int LotsWayChoice  = 1;    // Способ выбора рабочего лота:

                                  //  0-фиксированный,

                                  //  1-процент от депозита,

                                  //  2-фиксированно-пропорциональный,

                                  //  3-фракционно-фиксированный,

extern int LotsPercent    = 10;   // Процент от депозита

extern int LotsDeltaDepo  = 500;  // Коэффициент приращения депозита

extern int LotsDepoForOne = 500;  // Размер депозита для одного минилота

extern int LotsMax        = 1000; // Максимальное количество минилотов

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

//| expert start function                                            |

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

double fPreviousBid = 0;  // значение bid на предыдущем тике

string symb;

int OnInit()

{

   fPreviousBid = 0;

   return(INIT_SUCCEEDED);

}


void OnTick()

 {

  symb = _Symbol;

 

   Bkl();

 }

 

 

void Bkl() 

 {

 

   static datetime bodCurr; datetime bodPrev = bodCurr; bodCurr = DateOfDay( TimeCurrent() );

   bool isNewDay = bodPrev != bodCurr;

   if(isNewDay){

   int part_order_close_sell_23_6 = 0;

   };

 

if (TradeStatuse() > 0) return (0);

double SL=0,TP=0,NoLossTP=0,Current_Value,Bid_Value_23_6=0,Ask_Value_23_6=0,Bid_Value_38_2=0,Ask_Value_38_2=0,Bid_Value_50=0,Ask_Value_50=0,Bid_Value_61_8=0,Ask_Value_61_8=0,

Lot_23_6=0,

Lot_38_2=0,

Lot_50=0,

Lot_61_8=0,

Spread=Ask-Bid,

StopLevel=Point*MarketInfo(Symbol(),MODE_STOPLEVEL),

HighD1=iHigh(Symbol(),PERIOD_D1,1),

LowD1=iLow(Symbol(),PERIOD_D1,1),

HighD1Today=iHigh(Symbol(),PERIOD_D1,0),

LowD1Today=iLow(Symbol(),PERIOD_D1,0),

HighH4=iHigh(Symbol(),PERIOD_H4,1),

LowH4=iLow(Symbol(),PERIOD_H4,1),

HighH6=iHigh(Symbol(),PERIOD_H6,0),

LowH6=iLow(Symbol(),PERIOD_H6,0),

HighW1=iHigh(Symbol(),PERIOD_W1,1),

LowW1=iLow(Symbol(),PERIOD_W1,1),

CheckHiLivels = 0, CheckLowLivels = 0;


  static double max_23_6 = 0;

  static double max_38_2 = 0;

  static double max_50_0 = 0;

  static double max_61_8 = 0;


  static double min_23_6 = 0;

  static double min_38_2 = 0;

  static double min_50_0 = 0;

  static double min_61_8 = 0;

    static double high_day = 0;

  static double low_day = 0;

  high_day = iHigh(Symbol(), PERIOD_D1, 1);

  low_day = iLow(Symbol(), PERIOD_D1, 1);

int total = OrdersTotal(); // сколько всего ордеров открыто

   double fUpperLevel = iHigh(Symbol(), PERIOD_D1, 1) + Delta * Point();

   double fLowerLevel = iLow(Symbol(), PERIOD_D1, 1) - Delta * Point();

  double TodayHi = iHigh(Symbol(),PERIOD_D1,0);                          // Цена закрытия предпоследнего дня

  double TodayLow = iLow(Symbol(),PERIOD_D1,0);                         // Цена закрытия последнего дня

   if (TodayHi>fUpperLevel && Open[0] < fUpperLevel) CheckHiLivels = 1;

   if (TodayLow<fLowerLevel && Open[0] > fLowerLevel) CheckLowLivels = 1;

   bool Open_Bay = fPreviousBid > 0 && Bid > fUpperLevel && fPreviousBid <= fUpperLevel && CheckHiLivels == 1;

   bool Open_Sell = fPreviousBid > 0 && Bid < fLowerLevel && fPreviousBid >= fLowerLevel && CheckLowLivels == 1;

   // запоминаем текущий бид

   fPreviousBid = Bid;

int Ticket,cnt,Total=0;


   double spread=ask-bid; 

   int spread_points=(int)MathRound(spread/SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 

   comm=comm+"Вычисленный спред = "+(string)spread_points+" пунктов"; 

for(cnt=0;cnt<OrdersTotal();cnt++)

   {

   OrderSelect(cnt,SELECT_BY_POS);

   if(OrderSymbol()==Symbol())

      {

      Total++;

         Lot_23_6 = OrderLots()*Lot_Percent_23_6/100;if(Lot_23_6>OrderLots()||Lot_23_6<0.01){Lot_23_6 = OrderLots();if(Lot_23_6>100)Lot_23_6=100;}

         Lot_23_6 = (NormalizeLot(Lot_23_6, False));

         Lot_38_2 = OrderLots()*Lot_Percent_38_2/100;if(Lot_38_2>OrderLots()||Lot_38_2<0.01){Lot_38_2 = OrderLots();if(Lot_38_2>100)Lot_38_2=100;}

         Lot_38_2 = (NormalizeLot(Lot_38_2, False));         

         Lot_50 = OrderLots()*Lot_Percent_50/100;if(Lot_50>OrderLots()||Lot_50<0.01){Lot_50 = OrderLots();if(Lot_50>100)Lot_50=100;}

         Lot_50 = (NormalizeLot(Lot_50, False));        

         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));    



      if(OrderType()==OP_BUY)// long position is opened

         {

     max_23_6 = high_day + (MathAbs(high_day - low_day) / 4.236);

     max_38_2 = high_day + (MathAbs(high_day - low_day) / 2.582);

     max_50_0 = high_day + (MathAbs(high_day - low_day) / 1.960);

     max_61_8 = high_day + (MathAbs(high_day - low_day) / 1.618);


         if(Lot_38_2>0&& Bid> max_38_2) 

            {

            if(Lot_38_2>0){

            Print ("Частичное закрытие ордера Buy на уровне 32.2"); 

            OrderClose(OrderTicket(), Lot_38_2, Bid, 20, Blue);return(0);}

            return(0);

            }  

         if(Lot_50>0&&Bid > max_50_0) 

            {

            if(Lot_50>0){

            Print ("Частичное закрытие ордера Buy на уровне 50"); 

            OrderClose(OrderTicket(), Lot_50, Bid, 20, Blue);return(0);}


            return(0);

            }             

         if(Lot_61_8>0&&Bid > max_61_8) 

            {

            if(Lot_61_8 > 0){

            Print ("Частичное закрытие ордера Buy на уровне 61.8", Lot_61_8); 

            OrderClose(OrderTicket(), Lot_61_8, Bid, 20, Blue);return(0);}

            return(0);

            } 

                     

         if( Bid > OrderOpenPrice()+(NoLoss*Point) && NoLoss>0 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice()+(NoLoss*Point),Digits);

            if(!CompareDoubles(OrderStopLoss(),SL)){ 

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0);

            }

            return(0);

            }   

         if( Bid > max_23_6 && OrderStopLoss()<max_23_6 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() + (NoLossFiboLevels*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            Print ("Частичное закрытие ордера Buy на уровне 23.6"); 

            OrderClose(OrderTicket(), Lot_23_6, Bid, 20, Blue);return(0);            

            }            


            }     

            

                

   }

      if(OrderType()==OP_SELL)

      {


//--sell---------------------------------------------------------------------------------------------------------------------

     min_23_6 = low_day - (MathAbs(high_day - low_day) / 4.236);// Alert("min_23_6 ", min_23_6);

     min_38_2 = low_day - (MathAbs(high_day - low_day) / 2.582);

     min_50_0 = low_day - (MathAbs(high_day - low_day) / 1.960);

     min_61_8 = low_day - (MathAbs(high_day - low_day) / 1.618);// Alert("min_61_8 ", min_61_8);   



         if(Lot_38_2>0&&Ask < min_38_2) 

            {

            if(Lot_38_2>0){

            Print ("Частичное закрытие ордера Sell на уровне -38.2 ",Ask," Размер лота ",Lot_38_2); 

            OrderClose(OrderTicket(), Lot_38_2, Ask, 20, Blue);return(0);}


            }

         if(Lot_50>0&&Ask < min_50_0) 

            {

            if(Lot_50>0){

            Print ("Частичное закрытие ордера Sell на уровне -50 ",Ask," Размер лота ",Lot_50); 

            OrderClose(OrderTicket(), Lot_50, Ask, 20, Blue);return(0);}


            }                 

         if(Lot_61_8>0&& Ask<min_61_8) 

            {

            if(Lot_61_8>0){

            Print ("Частичное закрытие ордера Sell на уровне -61.8 ",Ask," Размер лота ",Lot_61_8); 

            OrderClose(OrderTicket(), Lot_61_8, Ask, 20, Blue);return(0);}


            }           

         if( Ask < OrderOpenPrice()-(Point*NoLoss) && NoLoss>0 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() - (NoLoss*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            }

   

            return(0);

            }

            if( Ask < min_23_6 && OrderStopLoss()> min_23_6 ) 

            {

            SL = NormalizeDouble(OrderOpenPrice() - (NoLossFiboLevels*Point),Digits);

            if (!CompareDoubles(OrderStopLoss(),SL)){

            OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Blue);

            Print ("Частичное закрытие ордера Sell на уровне -23.6 ",Ask," Размер лота ", Lot_23_6); 

            OrderClose(OrderTicket(), Lot_23_6, MarketInfo(Symbol(), MODE_ASK), 20, Blue);            

            }            


            }

          

   }

   }

   }

//+----Открытие позиций

int TradeTime=TimeDay(TimeCurrent());

int TradeTimeBuy=TimeDay(TimeCurrent());

int TradeTimeSell=TimeDay(TimeCurrent());

if(Total<1 )

   {

   if(Open_Bay && LastTradeTimeBuy!=TradeTimeBuy )

      {      

         SL = iLow(symb,PERIOD_D1,0);

         // Alert("(Bid-SL)*10000 ", (Bid-SL)*100000);

         if((Bid-SL)*100000>StopLoss){SL = Bid - (StopLoss*Point);}

         if(TakeProfit>0) TP = Ask + TakeProfit*Point;

         if(Bid-SL<StopLevel-Delta*Point) return(0);  // проверяем минимальный уровень стопов   

         Ticket=OrderSend(Symbol(),OP_BUY,GetSizeLot(),Ask + Spread ,20,SL,TP);

         if (Ticket > 0)                                                  

         {            

            LastTradeTimeBuy=TradeTimeBuy; // задаем время сделки, чтобы сегодня больше не торговать 

         }     

      return(0);

      }

//+----

   if(Open_Sell && LastTradeTimeSell!=TradeTimeSell)

           {  

         SL = iHigh(symb,PERIOD_D1,0);

         if((Ask+SL)*100000>StopLoss){SL = Ask + (StopLoss*Point);}

         if(TakeProfit>0) TP = Bid - TakeProfit*Point;

         if (SL-Ask<StopLevel-Delta*Point) return(0); // проверяем минимальный уровень стопов     

         Ticket = OrderSend(Symbol(),OP_SELL,GetSizeLot(),Bid - Spread,20,SL,TP);

         if (Ticket > 0)                                                  

         { 

            LastTradeTimeSell=TradeTimeSell;  // задаем время сделки, чтобы сегодня больше не торговать

         }    

         return(0);     

      }

   }

  // return(0);

 }

int TradeStatuse()

{

   if ((!IsTesting()) && IsStopped()) return (1); //--- Если не тестовый режим и советник приостановлен (IsStopped).

   if ((!IsTesting()) && !IsTradeAllowed()) return (2); //--- Если не тестовый режим и торговля заблокирована (IsTradeAllowed).

   if ((!IsTesting()) && IsTradeContextBusy()) return (3); //--- Если не тестовый режим и поток для выполнения торговых операции занят (IsTradeContextBusy).

   if (Hour() < TimeStartMonday + DayOfWeek() == 1) return (4); //--- Проверка на торговое время в понидельник.

   if (Hour() >= TimeEndFriday + DayOfWeek() == 5) return (5); //--- Проверка на торговое время в пятницу.

   if (TimeEnd < TimeStart) 

      {  

      if(Hour() >= TimeEnd && Hour() < TimeStart) return (6);

      }

   else

      {

      if ((Hour() < TimeStart) || (Hour() >= TimeEnd)) return (6); //--- Проверка на торговое время.

      }

   if ((DayOfWeek() == 0) || (DayOfWeek() == 6)) return (7); //--- Выходные, некоторые брокеры как RVD торговля начинаеться в воскресение вечером

   //---

   return(0);

}

double GetSizeLot()

{

  double dLot;

  if (LotsWayChoice==0) dLot=Lots;

  // фиксированный процент от депозита

  if (LotsWayChoice==1)

  {

    // dLot=MathCeil(AccountFreeMargin()/10000*LotsPercent)/10;

    dLot=MathFloor(AccountFreeMargin()/MarketInfo(Symbol(),MODE_LOTSIZE)/MarketInfo(Symbol(),MODE_MINLOT)*AccountLeverage()/100.0*LotsPercent) * MarketInfo(Symbol(),MODE_MINLOT);

  }

  // фиксированно-пропорциональный

  if (LotsWayChoice==2)

  {

    int k=LotsDepoForOne;

    for (double i=2; i<=LotsMax; i++)

    {

      k=k+i*LotsDeltaDepo;

      if (k>AccountFreeMargin())

      {

        dLot=(i-1)/10000; break;

      }

    }

  }

  // фракционно-фиксированный

  if (LotsWayChoice==3)

  {

    dLot=MathCeil((AccountFreeMargin()-LotsDepoForOne)/LotsDeltaDepo)/10;

  }

  if (dLot<0.01) dLot=0.01;

  if (dLot>100) dLot=100;

  return(dLot);

}



double NormalizeLot(double lo, bool ro=False, string sy="") {

  double l, k;

  if (sy=="" || sy=="0") sy=Symbol();

  double ls=MarketInfo(sy, MODE_LOTSTEP);

  double ml=MarketInfo(sy, MODE_MINLOT);

  double mx=MarketInfo(sy, MODE_MAXLOT);

  if (ml==0) ml=0.01;

  if (mx==0) mx=100;

  if (ls>0) k=1/ls; else k=1/ml;

  if (ro) l=MathCeil(lo*k)/k; else l=MathFloor(lo*k)/k;

  if (l<ml) l=ml;

  if (l>mx) l=mx;

  return(l);

}


bool CompareDoubles(double number1,double number2) 

  { 

   if(NormalizeDouble(number1-number2,8)==0) return(true); 

   else return(false); 

  } 

void NoLoss() { 

   int tip,Ticket; 

   double StLo,OSL,OOP; 

   for (int i=0; i<OrdersTotal(); i++) { 

      if (OrderSelect(i, SELECT_BY_POS)) { 

tip = OrderType(); 

  if (tip<2 && OrderSymbol()==Symbol()) { 

  OSL = NormalizeDouble(OrderStopLoss(),Digits); 

  OOP = NormalizeDouble(OrderOpenPrice(),Digits); 

  Ticket = OrderTicket(); 

     if (tip==OP_BUY) { 

        if (OSL>OOP) continue; 

        StLo = NormalizeDouble(OOP+Point,Digits); 

        if (NormalizeDouble((Bid-OOP)/Point,0)>=NoLoss) { 

           if (!OrderModify(Ticket,OOP,StLo,OrderTakeProfit(),0,White)) 

        Print("NoLoss Error ",GetLastError()," buy SL ",OSL,"->",StLo); 

        } 

     } 

     if (tip==OP_SELL) { 

        if (OSL<OOP) continue; 

        StLo = NormalizeDouble(OOP-Point,Digits); 

        if (NormalizeDouble((OOP-Ask)/Point,0)>=NoLoss) { 

           if (!OrderModify(Ticket,OOP,StLo,OrderTakeProfit(),0,White)) 

     Print("NoLoss Error ",GetLastError()," sell SL ",OSL,"->",StLo); 

        } 

  } 

      } 

   } 



 



такой вот код получился ... но частичная фиксация не корректно отратывает.. так и не получилось сделать условие для частичного закрытия ордера 

Чем моя функция частичного закрытия не устраивает, которую выложил на предыдущей странице ? Работает на реале идеально, вместо переменных берется цена stoploss которая никуда с сервера не денется. Если вам надо закрывать не половину сразу, а 66% например, но измените так коэффициент в формуле.

 
close_lot=NormalizeDouble(OrderLots()/2,2);
"2" это закрыть половину, округление согласно NormalizeDouble
 
Vladimir Zubov:
"2" это закрыть половину, округление согласно NormalizeDouble
получилось. спасибо
 
Vladimir Zubov:

Написал такую функцию, на ECN работает без проблем. Пользуйтесь на здоровье)

 

КАК ОЖИВИТЬ ТО ЭТУ ФУНКЦИЮ ? Написал так!

TimeBar=Time[0];

         ClosePartPosition(tr);

         if(stoploss!=0) SL=NormalizeDouble(Bid-stoploss*Point,Digits); else SL=0;

         LOT=LOT(risk,1);

         if(ORDERS(-1)==1) CLOSEORDER(-1);//Закрыть ордера открытые на продажу