0
По закрытию очередного бара. Для ускорения можно и индюка активировать один раз по закрытию-открытию бара. а тестирование вм1 равно по тикам.
avatar

kvashnin007

  • 10 августа 2022, 21:08
0
Борис, здравствуйте. Как-то давно, окончив обучение по сливу дэпо, пытался заработать. Чуть заработал, чуть прокакал, так возле нуля и чалился. Психанул и начал торговать против сигналов всяких там RSI. Начал потихоньку со стопами выходить в плюс. Против толпы называется. Но заметил одну особенность. Надо пропускать один-три первых сигнала. Потом уже узнал про усреднение и пр. прибабахи. Помогали.
avatar

kvashnin007

  • 10 августа 2022, 21:05
0
Не вместилось.

Скачайте библиотеку по ссылке: disk.yandex.ru/d/HsPzU7URY4uOOA

Сама сова с изменениями: disk.yandex.ru/d/pBv9GLPI8spGeQ
avatar

kvashnin007

  • 7 августа 2022, 09:53
0
Добавил библиотеку по ошибкам.
У кого нет закиньте в папку Libraries:

<code>//---
   green_value<<=8;
   blue_value<<=16;
   return(red_value+green_value+blue_value);
  }
//+------------------------------------------------------------------+
//| right comparison of 2 doubles                                    |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2)
  {
   if(NormalizeDouble(number1-number2,8)==0) return(true);
   else return(false);
  }
//+------------------------------------------------------------------+
//| up to 16 digits after decimal point                              |
//+------------------------------------------------------------------+
string DoubleToStrMorePrecision(double number,int precision)
  {
   static double DecimalArray[17]=
     {
      1.0,
      10.0,
      100.0,
      1000.0,
      10000.0,
      100000.0,
      1000000.0,
      10000000.0,
      100000000.0,
      1000000000.0,
      10000000000.0,
      100000000000.0,
      1000000000000.0,
      10000000000000.0,
      100000000000000.0,
      1000000000000000.0,
      10000000000000000.0
     };

   double rem,integer,integer2;
   string intstring,remstring,retstring;
   bool   isnegative=false;
   int    rem2;
//---
   if(precision<0)  precision=0;
   if(precision>16) precision=16;
//---
   double p=DecimalArray[precision];
   if(number<0.0)
     {
      isnegative=true;
      number=-number;
     }
   integer=MathFloor(number);
   rem=MathRound((number-integer)*p);
   remstring="";
   for(int i=0; i<precision; i++)
     {
      integer2=MathFloor(rem/10);
      rem2=(int)NormalizeDouble(rem-integer2*10,0);
      remstring=IntegerToString(rem2)+remstring;
      rem=integer2;
     }
//---
   intstring=DoubleToStr(integer,0);
   if(isnegative)
      retstring="-"+intstring;
   else
      retstring=intstring;

   if(precision>0)
      retstring=retstring+"."+remstring;
//---
   return(retstring);
  }
//+------------------------------------------------------------------+
//| convert integer to string contained input's hexadecimal notation |
//+------------------------------------------------------------------+
string IntegerToHexString(int integer_number)
  {
   string hex_string="00000000";
   int    value,shift=28;
//---
   for(int i=0; i<8; i++)
     {
      value=(integer_number>>shift)&0x0F;
      if(value<10)
         hex_string=StringSetChar(hex_string,i,ushort(value+'0'));
      else
         hex_string=StringSetChar(hex_string,i,ushort((value-10)+'A'));
      shift-=4;
     }
//---
   return(hex_string);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                       stdlib.mq4 |
//|                   Copyright 2005-2015, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "2005-2015, MetaQuotes Software Corp."
#property link      "http://www.mql4.com"
#property library
//+------------------------------------------------------------------+
//| return error description                                         |
//+------------------------------------------------------------------+
string ErrorDescription(int error_code)
  {
   string error_string;

</code>


Не вместилось. Не копируйте.
avatar

kvashnin007

  • 7 августа 2022, 09:33
0
Не скучайте. Это по существу. А без демагогии это на базаре. Сказал три рубля и без всякой там демагогии.
avatar

kvashnin007

  • 6 августа 2022, 23:51
+1
Продолжение

bool _IsTime = IsTime(); //узнаем, подходит ли текущее время для торговли
   
   if(Update_Time != iTime(NULL,0,0) && _IsTime) //обновлять данные всех индикаторов   раз в период   //   < ???
      { 
      Update_Time = iTime(NULL,0,0); //перезаписываем значение переменной для хранения времени текущей свечи
      //импорт данных индикатора Stochastic для предыдущей свечи [1]
      Stoh = iStochastic(NULL,0,InpKPeriod,InpDPeriod,InpSlowing,MODE_SMA,1,MODE_MAIN,1);
      }
   if(_IsTime) 
      {
      if(cnt_b == 0 && Stoh < 100-StohLevel)   //условие для открытия ордера на покупку
         OpenTrade(OP_BUY);                    //открытие ордера на покупку
      if(cnt_s == 0 && Stoh > StohLevel)       //условие для открытия ордера на продажу
         OpenTrade(OP_SELL);                   //открытие ордера на продажу
      }   
   int Error = GetLastError(); //поиск ошибок по завершению тика
   if(Error != 0) Print("OnTick() Error ", GetLastError());   
}
//+------------------------------------------------------------------+
bool OpenTrade(int OP_Type)  //функция для открытия рыночного ордера  
{   
   if(MaxSpread > 0 && (Ask - Bid) > MaxSpread*Point) 
      return(false);     
   
   double price    = (OP_Type == OP_BUY ? Ask : Bid);                   //определение цены для открытия рыночного ордера
   color  col_type = (OP_Type == OP_BUY ? clrBlue : clrRed);            //определение цвета стрелки ордера
   string op_str   = (OP_Type == OP_BUY ? "на покупку" : "на продажу"); //определение текста для принта
   double lot      = getLastCloseLot (OP_Type);
   
   int ticket = OrderSend(Symbol(), OP_Type, lot, price, Slippage, 0, 0, "", MagicNumber, 0, col_type); //открытие ордера
   if(ticket > 0)  //Если ордер был открыт
      {
      Print("Ордер #",IntegerToString(ticket)," успешно открыт");
      return(true);
      }
   else  //при ошибке открытия ордера
      {
      int Error = GetLastError();
      Update_Time = 0;
      Print("Ошибка открытия ордера ", GetLastError());
      }
   return(false);
}
//+------------------------------------------------------------------+
bool IsTime() //проверка разрешенного времени для торговли 
{
   datetime _TimeCurrent = TimeCurrent();
   
   if(StartTime > EndTime) 
      if ((_TimeCurrent >= StartTime && _TimeCurrent < EndTime+60*60*60*24) || (_TimeCurrent >= StartTime-60*60*60*24 && _TimeCurrent < EndTime)) 
         return(true);
   else 
      if(StartTime < EndTime) 
         if (_TimeCurrent >= StartTime && _TimeCurrent < EndTime)  
            return(true);
   return(false);
}
//+------------------------------------------------------------------+
void CheckBE(int OP_Type)  //проверка для перевода ордеров в безубыток
{   
      if(OP_Type == OP_BUY)  //если ордер на покупку
         {
         double NewSL = NormalizeDouble(OrderOpenPrice()+BE_Step*Point,Digits);
         
         if(OrderStopLoss() < NewSL)  //если СЛ еще не был перенесен
            {
            if((Bid - OrderOpenPrice()) >= TakeProfit*SetBEDistance/100*Point && NewSL != OrderStopLoss()) 
               {
               if(!OrderModify(OrderTicket(), OrderOpenPrice(), NewSL, OrderTakeProfit(), 0, clrNONE))  //модификация ордера
                  {
                  int Error = GetLastError();
                  Print("Ошибка модификации ордера ", GetLastError()); //принт от ошибки модификации
                  }
               else 
                  Print("Перевод ордера на покупку в Безубыток с отступом " + IntegerToString(BE_Step) + " пунктов.");
               }
            }
         }
      //---
      else 
         if(OP_Type == OP_SELL)  //если ордер на продажу
            {
            double NewSL = NormalizeDouble(OrderOpenPrice()-BE_Step*Point,Digits);
            
            if(OrderStopLoss() > NewSL)  //если СЛ еще не был перенесен
               {
               if((OrderOpenPrice() - Ask) >= TakeProfit*SetBEDistance/100*Point && NewSL != OrderStopLoss()) 
                  {
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), NewSL, OrderTakeProfit(), 0, clrNONE))  //модификация ордера
                     {
                     int Error = GetLastError();
                     Print("Ошибка модификации ордера ", GetLastError()); //принт от ошибки модификации
                     }
                  else 
                     Print("Перевод ордера на продажу в Безубыток с отступом " + IntegerToString(BE_Step) + " пунктов.");
                  }
               }
            }   
}
//+------------------------------------------------------------------+
double getLastCloseLot (int o_type)
{
      double   lot    = 0;
      double   prof_B = 0;
      double   prof_S = 0;
      int      type   =-1;
      datetime time   = 0;
      
      for(int pos = OrdersHistoryTotal() - 1; pos >= 0; pos--)                 //цикл по всем закрытым ордерам
         if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))                     //выделение закрытого ордера для получения его данных
            if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) //проверка, чтобы ордер относился в нашему советнику
               {
               if(OrderType()==OP_BUY)
                  if (time<OrderCloseTime())
                     {
                     time   = OrderCloseTime();
                     prof_B = OrderProfit();
                     lot    = OrderLots();
                     }
               if(OrderType()==OP_SELL)
                  if (time<OrderCloseTime())
                     {
                     time   = OrderCloseTime();
                     prof_S = OrderProfit();
                     lot    = OrderLots();
                     }
               } 
      if(o_type == OP_SELL)
         {
         if((prof_B == 0 && time == 0)|| prof_B>0)
            lot = Lot;
         else
            lot = MathCeil(lot*100*LotK)/100;
         }
      //---  
      if(o_type == OP_BUY)
         {
         if((prof_S == 0 && time == 0)|| prof_S>0)
            lot = Lot;
         else
            lot = MathCeil(lot*100*LotK)/100;
         }  
          
   return (NormalizeDouble(lot,2));
}
//+------------------------------------------------------------------+

avatar

kvashnin007

  • 6 августа 2022, 23:04
+1
Пробуйте, кому интересно.
Тест EURUSD, М5, по КТ за месяц.
<

<code>//+------------------------------------------------------------------+
//|                                                 Asia Session KAE |
//+------------------------------------------------------------------+
#property description "Asia Session KAE"
#property version   "1.00"
#property strict

extern string s0 = "<== General Settings ==>"; //>  >  >
extern double  Lot                  = 0.01;
extern double  LotK                  =1.8;  
extern int     Slippage             = 30;
extern int     StopLoss             = 349;
extern int     TakeProfit           = 103;
extern int     MagicNumber          = 1961;
extern double  MaxSpread            = 30;

extern string s1 = "<== Stochastic Settings ==>"; //>  >  >
extern int     StohLevel            = 92;
extern int     InpKPeriod           = 5;   // K Period
extern int     InpDPeriod           = 5;    // D Period
extern int     InpSlowing           = 3;    // Slowing

extern string s2 = "<== Breakeven ==>"; //>  >  >
extern double  SetBEDistance        = 66;   // BU Distance % 
extern int     BE_Step              = 1;   // BU Step pips

extern string s3 = "<== Time Settings ==>"; //>  >  >
extern int     GMT_Offset           = 2;    //GMT Offset
extern int     Start_Trade_Hour     = 23;   //Start Trade Hour
extern int     Start_Trade_Minute   = 0;    //Start Trade Minute
extern int     End_Trade_Hour       = 8;    //End Trade Hour
extern int     End_Trade_Minute     = 0;    //End Trade Minute 

datetime StartTime, EndTime;
datetime Update_Time  = 0;
int day_of_year_trade = 0;
double Stoh           = 0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() 
{
   return(INIT_SUCCEEDED);  
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() 
{
   if (day_of_year_trade != DayOfYear()) 
      {
      day_of_year_trade = DayOfYear();
      
      datetime _CurrentDate = StrToTime(TimeToStr(TimeCurrent(),TIME_DATE));//??????????????

      StartTime =_CurrentDate+Start_Trade_Hour*60*60+Start_Trade_Minute*60+GMT_Offset*60*60;
      EndTime = _CurrentDate+End_Trade_Hour*60*60+End_Trade_Minute*60+GMT_Offset*60*60;
      }
   
   //модификация открытых ордеров
   int cnt_b = 0, cnt_s = 0;
   int _OrdersTotal = OrdersTotal();
   
   for(int pos = _OrdersTotal - 1; pos >= 0; pos--)  //цикл по всем открытым ордерам
      {
      if(!OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))  //выделение ордера для получения его данных
		   Print(" не удалось выделить ордер! " , GetLastError());   
      else 
         if(OrderType() <= 2 && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) //проверка, чтобы ордер относился в нашему советнику
            { 
            if(OrderType() == OP_BUY) 
               cnt_b++; //подсчет ордеров на покупку
            else 
               cnt_s++; //подсчет ордеров на продажу
            
            if(SetBEDistance > 0) //проверка для перевода в БУ 
               CheckBE(OrderType());                                               
            
            if(OrderTakeProfit() == 0 || OrderStopLoss() == 0)  //если у ордера нет одной из целей - модификация
               {
               double SL = 0, TP = 0;
               
               if(OrderType() == OP_BUY)  //определение целей текущего ордера
                  {
                  SL = OrderOpenPrice()-StopLoss*Point;
                  TP = OrderOpenPrice()+TakeProfit*Point;
                  }
               else 
                  {
                  SL = OrderOpenPrice()+StopLoss*Point;
                  TP = OrderOpenPrice()-TakeProfit*Point;
                  }
               if(!OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, clrNONE))  //модификация ордера
                  {
                  int Error = GetLastError();
                  Print("Ошибка модификации ордера ", GetLastError()); //принт от ошибки модификации
                  }
               else 
                  Print("Ордер #" + IntegerToString(OrderTicket()) + " успешно модифицирован");
               }
            }      
      }         
      //--- end for
</code>
avatar

kvashnin007

  • 6 августа 2022, 23:03
0
И Вообще я отказался от ATR. Толку ноль.
А вообще то я ожидал большего эффекта от своих потуг. Помощи мало, а сам быстро нахожу признаки бесперспективности. Хотя часто ошибаюсь с выводами.
avatar

kvashnin007

  • 5 августа 2022, 15:42
0
АТR здесь я использовал просто как единицу измерения. Рулеткой не удобно.
АТR брал за последние свечи, довольно свежие данные, но это не критично.
Подгонка под приемлемые величины у меня ограничена диапазоном и шагом как на картинке.
avatar

kvashnin007

  • 5 августа 2022, 15:39
+1
НЕ ВМЕСТИЛОСЬ.

<code>// --------------------------------------------------------
bool ValidLot(double volume)// Проверка лота на валидность
{
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
      return(false);

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
      return(false);

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
      return(false);

   return(true);
}
//---------------------------------------------------------------   
double NTP(int dir, double _op) // Нормализация цены тейкпрофита
{
	if (TakeProfit==0) 
	   return 0;
	double StopLvl=MarketInfo(Symbol(), MODE_STOPLEVEL)*Point;
	double pr=NP((dir==OP_BUY)?Bid:Ask);
	if (dir==OP_BUY) 
	   { 
	   tp=_op+TakeProfit*Point; 
	   return NP(MathMax(tp, pr+StopLvl)); 
	   }
	if (dir==OP_SELL) 
	   { 
	   tp=_op-TakeProfit*Point; 
	   return NP(MathMin(tp, pr-StopLvl)); 
	   }
	return 0;
}
//---------------------------------------------------------------   
double NSL(int dir, double _op) // Нормализация цены стоплоса
{
	if (StopLoss==0) 
	   return 0;
	double StopLvl=MarketInfo(Symbol(), MODE_STOPLEVEL)*Point;
	double pr=NP((dir==OP_BUY)?Bid:Ask);
	if (dir==OP_BUY) 
	   { 
	   sl=_op-StopLoss*Point; 
	   return NP(MathMin(sl, pr-StopLvl)); 
	   }
	if (dir==OP_SELL) 
	   { 
	   sl=_op+StopLoss*Point; 
	   return NP(MathMax(sl, pr+StopLvl)); 
	   }
	return 0;
}
//---------------------------------------------------------------   
double ND(double d, int n=-1) 
   { 
   if (n<0) 
      return NormalizeDouble(d, Digits); 
   return NormalizeDouble(d, n); 
   }
//---------------------------------------------------------------   
double NP(double d) 
   { 
   double TickSize=MarketInfo(Symbol(), MODE_TICKSIZE); 
   if (TickSize==0) 
      TickSize=1; 
   return ND(MathRound(d/TickSize)*TickSize); 
   }
//---------------------------------------------------------------   
</code>




За месяц, как обычно. При PointOrderStep=0 работает как обычная неваляшка, но с учетом закрытия бара. Не лучший вариант.
avatar

kvashnin007

  • 2 августа 2022, 16:26
+1
Чисто Неваляшка по барам без дополнительных примочек.

#property strict

//--- input parameters
input ENUM_TIMEFRAMES TF             = PERIOD_H4; // Тайм Фрейм для свечей
input double          StartLot       = 0.01;      // Лот базовый
input double          LotK           = 2.2;       // Коэф. увеличения лота  
input double          MaximalLots    = 1.28;      // Maximal Lots 
input int             StopLoss       = 408;       // Потери в пунктах
input int             TakeProfit     = 353;       // Прибыль в пунктах
input int             PointOrderStep = 431;       // Point order step (in pips)
input int             Slippage       = 30;        // Slippage
input int             MagicNumber    = 1961;      // Magic Number
//---                                          
int      iB=1, LastCloseType; 
double   tp,sl,Lot,step,LastCloseLot;
datetime LastTimeSL=0;
string   LastCloseTP_SL="0";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{ 
      step =  PointOrderStep*Point; 
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
      int b=0,s=0; 
      
      //-------------------- CURENT -------------------------------------
      for(int i=OrdersTotal()-1;i>=0;i--)
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
            if(OrderMagicNumber()==MagicNumber)
               if(OrderSymbol()==Symbol())
                  {
                  if(OrderType() == OP_SELL)
                     s++;
                  if(OrderType() == OP_BUY)
                    b++;
                  }
      //-------------------- HISTORY -------------------------------------
      if(s+b==0)
         for (int i = OrdersHistoryTotal()-1; i >=0; i--)
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && (OrderType()==OP_BUY || OrderType()==OP_SELL))
                  {
                  if (StringFind(OrderComment(),"[sl]")>-1 && iBarShift(NULL,TF,OrderCloseTime())==0)
                     {
                     LastCloseTP_SL = "SL";
                     LastCloseType  = OrderType();
                     LastCloseLot   = OrderLots();
                     break;
                     }
                  if (StringFind(OrderComment(),"[tp]")>-1 && iBarShift(NULL,TF,OrderCloseTime())==0)
                     {
                     LastCloseTP_SL = "TP";
                     LastCloseType  = OrderType();
                     LastCloseLot   = OrderLots();
                     break;
                     }
                  }
      //--------------- Открытие самого первого ордера --------------------------------
      double open1 = iOpen(Symbol(),TF,1);

      if(s+b==0 && LastCloseLot==0)                // Нет и не открывались ордера
         {
         if(Bid < open1)
            if(! OrderSend(Symbol(),OP_SELL,NL(StartLot),Bid,Slippage,0,0," ",MagicNumber,0,clrRed)) 
               { 
               Print("Order Send завершилась с ошибкой #",GetLastError());
               return;
               }    
          //---
          if(Bid > open1)
             if(!OrderSend(Symbol(),OP_BUY,NL(StartLot),Ask,Slippage,0,0," ",MagicNumber,0,clrRed)) 
                { 
                Print("Order Send завершилась с ошибкой #",GetLastError());
                return;
                } 
           }
      //--------------- Открытие последующих ордеров ----------------------------
      
         //---------------------------- последний закрылся по ТР  
      if(LastCloseTP_SL=="TP" && s+b==0)  // Нет ордеров, а полследний закрылся по ТР
         {
         Lot = StartLot;
         Lot = NL(Lot);
         if(!ValidLot(Lot)) return;  
               
         if(LastCloseType==OP_BUY && Ask>open1+step)
            {
            if(!OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0," ",MagicNumber,0,clrBlue)) 
               { 
               Print("Order Send завершилась с ошибкой #",GetLastError());
               return;
               } 
            }
         if(LastCloseType==OP_SELL && Bid<open1-step)
            {
            if(!OrderSend(Symbol(),OP_SELL,Lot,Bid,Slippage,0,0," ",MagicNumber,0,clrRed)) 
               { 
               Print("Order Send завершилась с ошибкой #",GetLastError());
               return;
               }    
            }
         }
         //---------------------------- последний закрылся по SL  
      if(LastCloseTP_SL=="SL" && s+b==0)  // Нет ордеров, а полследний закрылся по SL
         {   
         Lot = MathCeil((LastCloseLot * LotK)*100)/100;
         if(Lot > MaximalLots)
            Lot = MaximalLots;
         Lot = NL(Lot);
         if(!ValidLot(Lot)) return;  
               
         if(LastCloseType==OP_BUY && Bid<open1-step)
            {
            if(!OrderSend(Symbol(),OP_SELL,Lot,Bid,Slippage,0,0," ",MagicNumber,0,clrRed)) 
               { 
               Print("Order Send завершилась с ошибкой #",GetLastError());
               return;
               }    
            }
         if(LastCloseType==OP_SELL && Ask>open1+step)
            {
            if(!OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0," ",MagicNumber,0,clrBlue)) 
               { 
               Print("Order Send завершилась с ошибкой #",GetLastError());
               return;
               } 
            }
         }
            //--------------- Расчет ТР и SL ------------------------------- 
                         
         	double StopLvl = NormalizeDouble(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point,Digits);
         	   
            sl = StopLoss*Point;
            if(sl<StopLvl)
               sl=StopLvl;
            
            tp = TakeProfit*Point;
            if(tp<StopLvl)
               tp=StopLvl;
               
            //--------------- Установка ТР и SL ----------------------------
            
            for(int i=OrdersTotal()-1;i>=0;i--)
               if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
                  if(OrderSymbol()==Symbol())
                     {
                     double oop = OrderOpenPrice();
                     double TP  = OrderTakeProfit();
                     double SL  = OrderStopLoss();
                     int    tk  = OrderTicket();
                     
                     if(OrderMagicNumber()==MagicNumber)
                           {
                           if(OrderType()==OP_BUY && TP==0 && SL==0)
                               {
                               if(!OrderModify(tk,oop,NSL(OP_BUY,oop),NTP(OP_BUY,oop),0,clrBlue))
                                 Print("Order Modify error #",GetLastError());
                               }
                           if(OrderType()==OP_SELL && TP==0 && SL==0)
                             if(OrderTakeProfit()==0)
                               if(!OrderModify(tk,oop,NSL(OP_SELL,oop),NTP(OP_SELL,oop),0,clrRed))
                                 Print("Order Modify error #",GetLastError());
                           }

                     }
}
//---------------------------------------------------------------   
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
avatar

kvashnin007

  • 2 августа 2022, 16:24
0
И ещё… Я бы не пытался всё воткнуть в один советник. один бы сделал на пробой, второй на отбой.
Потом бы, после отработки по-отдельности, объединял.
Уверен, что Вы тоже так планировали, но всё же ляпну. На всякий случай.

Удачи.
avatar

kvashnin007

  • 13 июля 2022, 08:04
0
Да… и ещё.
Утренний флэт Можно использовать как простой ориентир. Пробой, например, равный 30 пипсов (3 пункта) выше-ниже канала на 5-ти знаке, при отходе цены от канала >= половине ширине канала закрываем половину лота, а вторую тралим от канала.
Отбой (при возврате в канал?) аналогично до середины канала, БУ и до ТР или трал стопа от канала. Каналы, как правило, превышают два спреда. Да и тралить можно не от середины канала, а от минимально разрешенного брокером стопа.

Очень специфически цена во время пиндоской сессии реагирует на шалости европейских скаутов.
Если упереться в короткие флеты до 4-х часов (даже меньше), вырисуется хорошая стратегия на выход из накопления.

Помнить, что утренний гэп закрывается с вероятность более 94%. Правда и спрэд в это время расширяется раз в 5-10 (а некоторые брокеры и не такие стеснительные).

Пахать и пахать. Борис, удачи Вам.
avatar

kvashnin007

  • 13 июля 2022, 07:47
0
Неплохо было бы на графике оформить врмя формирования, верхнюю и нижнюю границы. Я такого ещё никогда не делал.
avatar

kvashnin007

  • 13 июля 2022, 00:39
0
Внёс небольшое исправление.
Теперь буферы равны верхней-нижней цене только после формирования временнОй полосы и до окончания (голубая полоса). Остальное время = EMPTY_VALUE.

<code>// [MT4 BREAKOUT BOX]               
#property indicator_chart_window
     
extern string periodBegin     = "00:00";  // Начало для расчета полосы
extern string periodEnd       = "03:55";  // Окончание расчета полосы
extern string BoxEnd          = "23:00";  // Время обрезания полосы
extern color  BoxHLColor      = clrPowderBlue;
extern color  BoxPeriodColor  = clrPaleGreen;
extern int    NumberOfDays    = 50; 
//---
double PriceHigh[];
double PriceLow[];

//==========================================================================================================
int   init() 
{
      SetIndexBuffer(0,PriceHigh); 
      SetIndexBuffer(1,PriceLow); 
   return(INIT_SUCCEEDED);
}
//==========================================================================================================
int deinit() 
{
   string TradeDate; 
   
   for(int i=ObjectsTotal(); i>=0;i--) 
      {
      TradeDate=ObjectName(i);
      if(StringFind(TradeDate,"Box",0)==0) 
         ObjectDelete(TradeDate);
      } 
   return(0);
}
//==========================================================================================================
int  start() 
{
   datetime TradeDate=TimeCurrent();
   
   if(Period()<=60) 
      {
      for (int i=0; i<NumberOfDays; i++) 
         {
         DrawObjects(TradeDate,"BoxHighLow  "    +TimeToStr(TradeDate,TIME_DATE),periodBegin,periodEnd,BoxEnd,BoxHLColor,0,1);
         DrawObjects(TradeDate,"Box Period  "+TimeToStr(TradeDate,TIME_DATE),periodBegin,periodEnd,periodEnd,BoxPeriodColor,0,2);
           
         TradeDate=decrementTradeDate(TradeDate);
         
         while (TimeDayOfWeek(TradeDate)>5) 
            TradeDate=decrementTradeDate(TradeDate);
         }
      } 
   return(0);
}
//==========================================================================================================
void DrawObjects(datetime dtTradeDate,string sObjName,string sTimeBegin,string sTimeEnd,string sTimeObjEnd,color cObjColor,int iOffSet,int iForm) 
{
      datetime dtTimeBegin,dtTimeEnd,dtTimeObjEnd; 
      double dPriceHigh,dPriceLow; 
      int iBarBegin,iBarEnd;
   
      PriceHigh[iBarEnd]=EMPTY_VALUE;
      PriceLow[iBarEnd]=EMPTY_VALUE;

       dtTimeBegin  = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeBegin);
       dtTimeEnd    = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeEnd);
       dtTimeObjEnd = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeObjEnd);
         
       iBarBegin=iBarShift(NULL,0,dtTimeBegin);
       iBarEnd=iBarShift(NULL,0,dtTimeEnd);
       dPriceHigh =High[Highest(NULL,0,MODE_HIGH,iBarBegin-iBarEnd+1,iBarEnd)];
       if(iTime(NULL, 0, 0)>dtTimeEnd) 
          PriceHigh[iBarEnd]=dPriceHigh;
       dPriceLow  = Low [Lowest (NULL,0,MODE_LOW, iBarBegin-iBarEnd+1,iBarEnd)];
       if(iTime(NULL, 0, 0)>dtTimeEnd) 
          PriceLow[iBarEnd]=dPriceLow;
//==========================================================================================================  
                ObjectCreate(sObjName,OBJ_RECTANGLE,0,0,0,0,0);
                ObjectSet(sObjName,OBJPROP_TIME1,dtTimeBegin);
                ObjectSet(sObjName,OBJPROP_TIME2,dtTimeObjEnd);
   if(iForm==1)   // Бокс до конца
      {
      ObjectSet(sObjName,OBJPROP_PRICE1,dPriceHigh);  
      ObjectSet(sObjName,OBJPROP_PRICE2,dPriceLow);
      ObjectSet(sObjName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(sObjName,OBJPROP_COLOR,cObjColor);
      ObjectSet(sObjName,OBJPROP_BACK,True);
      }
   if(iForm==2)   // Бокс на участке
      {
      ObjectSet(sObjName,OBJPROP_PRICE1,dPriceHigh+iOffSet*Point);
      ObjectSet(sObjName,OBJPROP_PRICE2,dPriceLow-iOffSet*Point);
      ObjectSet(sObjName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(sObjName,OBJPROP_COLOR,cObjColor);
      ObjectSet(sObjName,OBJPROP_WIDTH,1);
      ObjectSet(sObjName,OBJPROP_BACK,true);
      }
}        
//==========================================================================================================
datetime decrementTradeDate (datetime Time_Date) 
{
   int   iTimeYear   = TimeYear(Time_Date);
   int   iTimeMonth  = TimeMonth(Time_Date);
   int   iTimeDay    = TimeDay(Time_Date);
   int   iTimeHour   = TimeHour(Time_Date);
   int   iTimeMinute = TimeMinute(Time_Date);
   
   iTimeDay--; 
   
   if(iTimeDay==0) 
      {
      iTimeMonth--; 
      if(iTimeMonth==0) 
         {
         iTimeYear--; 
         iTimeMonth=12;
         }
      // Thirty days hath September...  
      if(iTimeMonth==4||iTimeMonth==6||iTimeMonth==9||iTimeMonth==11)
         iTimeDay=30;
      // ...all the rest have thirty-one...
      if(iTimeMonth==1||iTimeMonth==3||iTimeMonth==5||iTimeMonth==7||iTimeMonth==8||iTimeMonth==10||iTimeMonth==12)
         iTimeDay=31;
      // ...except...
      if(iTimeMonth==2)
         if(MathMod(iTimeYear,4)==0) 
           iTimeDay=29; 
         else 
           iTimeDay=28;
      }
   return(StrToTime(iTimeYear + "." + iTimeMonth + "." + iTimeDay + " " + iTimeHour + ":" + iTimeMinute));
}
//==========================================================================================================</code>
avatar

kvashnin007

  • 13 июля 2022, 00:36
0
Индюк зовется TZ-Breaktout.
Посмотрел код. Не понял. Как-то через задний проход.
Настройки 2-6-0.
Как 9-ти часовую полосу организовать? САМ ногу сломает. А с буферами никаких проблем. А вот понимания не хватает.

Нашёл того индюка, которого не мог раньше.
Исправил ошибку с нулевым баром. Раньше не учитывался.
Сделал буфера, как у соседки. Тфу ты… отрастила.
Теперь есть буферы верхней и нижней цены полосы.
Прибавляйте отнимайте дельту и вперёд.

Да… и 9 часов, помоему, перебор.2-3 приемлемо. Подумайте.



<code>// [MT4 BREAKOUT BOX]               
#property indicator_chart_window
     
extern string periodBegin     = "00:00";  // Начало для расчета полосы
extern string periodEnd       = "03:55";  // Окончание расчета полосы
extern string BoxEnd          = "23:00";  // Время обрезания полосы
extern color  BoxHLColor      = clrPowderBlue;
extern color  BoxPeriodColor  = clrPaleGreen;
extern int    NumberOfDays    = 50; 
//---
double PriceHigh[];
double PriceLow[];

//==========================================================================================================
int   init() 
{
      SetIndexBuffer(0,PriceHigh); 
      SetIndexBuffer(1,PriceLow); 
   return(0);
}
//==========================================================================================================
int deinit() 
{
   string TradeDate; 
   
   for(int i=ObjectsTotal(); i>=0;i--) 
      {
      TradeDate=ObjectName(i);
      if(StringFind(TradeDate,"Box",0)==0) 
         ObjectDelete(TradeDate);
      } 
   return(0);
}
//==========================================================================================================
int  start() 
{
   datetime TradeDate=TimeCurrent();
   
   if(Period()<=60) 
      {
      for (int i=0; i<NumberOfDays; i++) 
         {
         DrawObjects(TradeDate,"BoxHighLow  "    +TimeToStr(TradeDate,TIME_DATE),periodBegin,periodEnd,BoxEnd,BoxHLColor,0,1);
         DrawObjects(TradeDate,"Box Period  "+TimeToStr(TradeDate,TIME_DATE),periodBegin,periodEnd,periodEnd,BoxPeriodColor,0,2);
           
         TradeDate=decrementTradeDate(TradeDate);
         
         while (TimeDayOfWeek(TradeDate)>5) 
            TradeDate=decrementTradeDate(TradeDate);
         }
      } 
   return(0);
}
//==========================================================================================================
void DrawObjects(datetime dtTradeDate,string sObjName,string sTimeBegin,string sTimeEnd,string sTimeObjEnd,color cObjColor,int iOffSet,int iForm) 
{
      datetime dtTimeBegin,dtTimeEnd,dtTimeObjEnd; 
      double dPriceHigh,dPriceLow; 
      int iBarBegin,iBarEnd;
   
       dtTimeBegin  = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeBegin);
       dtTimeEnd    = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeEnd);
       dtTimeObjEnd = StrToTime(TimeToStr(dtTradeDate,TIME_DATE)+" "+sTimeObjEnd);
         
       iBarBegin=iBarShift(NULL,0,dtTimeBegin);
       iBarEnd=iBarShift(NULL,0,dtTimeEnd);
       dPriceHigh =High[Highest(NULL,0,MODE_HIGH,iBarBegin-iBarEnd+1,iBarEnd)];
       PriceHigh[iBarEnd]=dPriceHigh;
       dPriceLow  = Low [Lowest (NULL,0,MODE_LOW, iBarBegin-iBarEnd+1,iBarEnd)];
       PriceLow[iBarEnd]=dPriceLow;
//==========================================================================================================  
                ObjectCreate(sObjName,OBJ_RECTANGLE,0,0,0,0,0);
                ObjectSet(sObjName,OBJPROP_TIME1,dtTimeBegin);
                ObjectSet(sObjName,OBJPROP_TIME2,dtTimeObjEnd);
   if(iForm==1)   // Бокс до конца
      {
      ObjectSet(sObjName,OBJPROP_PRICE1,dPriceHigh);  
      ObjectSet(sObjName,OBJPROP_PRICE2,dPriceLow);
      ObjectSet(sObjName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(sObjName,OBJPROP_COLOR,cObjColor);
      ObjectSet(sObjName,OBJPROP_BACK,True);
      }
   if(iForm==2)   // Бокс на участке
      {
      ObjectSet(sObjName,OBJPROP_PRICE1,dPriceHigh+iOffSet*Point);
      ObjectSet(sObjName,OBJPROP_PRICE2,dPriceLow-iOffSet*Point);
      ObjectSet(sObjName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(sObjName,OBJPROP_COLOR,cObjColor);
      ObjectSet(sObjName,OBJPROP_WIDTH,1);
      ObjectSet(sObjName,OBJPROP_BACK,true);
      }
}        
//==========================================================================================================
datetime decrementTradeDate (datetime Time_Date) 
{
   int   iTimeYear   = TimeYear(Time_Date);
   int   iTimeMonth  = TimeMonth(Time_Date);
   int   iTimeDay    = TimeDay(Time_Date);
   int   iTimeHour   = TimeHour(Time_Date);
   int   iTimeMinute = TimeMinute(Time_Date);
   
   iTimeDay--; 
   
   if(iTimeDay==0) 
      {
      iTimeMonth--; 
      if(iTimeMonth==0) 
         {
         iTimeYear--; 
         iTimeMonth=12;
         }
      // Thirty days hath September...  
      if(iTimeMonth==4||iTimeMonth==6||iTimeMonth==9||iTimeMonth==11)
         iTimeDay=30;
      // ...all the rest have thirty-one...
      if(iTimeMonth==1||iTimeMonth==3||iTimeMonth==5||iTimeMonth==7||iTimeMonth==8||iTimeMonth==10||iTimeMonth==12)
         iTimeDay=31;
      // ...except...
      if(iTimeMonth==2)
         if(MathMod(iTimeYear,4)==0) 
           iTimeDay=29; 
         else 
           iTimeDay=28;
      }
   return(StrToTime(iTimeYear + "." + iTimeMonth + "." + iTimeDay + " " + iTimeHour + ":" + iTimeMinute));
}
//==========================================================================================================</code>

avatar

kvashnin007

  • 12 июля 2022, 22:44
0
Берите Шамана в оборот. Нечего ему потчевать на лаврах. Пусть делится опытом, нарабатывая этим свой.

Просто, когда пытаешься объяснить свою мысль другому, она как бы лучше формализуется. Становится стройнее, что ли.
avatar

kvashnin007

  • 12 июля 2022, 08:48
0
Ой, Борис, забыл уже. Давно это было. Первый участок рисует полосу по указанному кол-ву свечей или времени (не помню уже) Дальше полоса расширяется (можно сужать) на указанное количество пунктов.

Я вечером внимательно гляну и напишу Вам подробнее.
Помню, что там какие-то напряги с буферами были. Давно это было.

У меня где-то был другой индюк с более внятной политикой, но сразу на глаза не попался. Вечером гдяну.
avatar

kvashnin007

  • 12 июля 2022, 08:40
+1
Я когда-то заказывал фрилансеру написать советник по главной идее:
Рискнули по индюку 1% дэпо- заработали до получения встречного сигнала.
Дальше уже рискуем заработанным и дальше при перевороте, пока в стоп не вляпаемся. Тогда считал за три подряд цикла разгон 32% при единичном риске.
Фрилансер распальцованный оказался. Одних только стрингов — не меряно.
Короче — полный тормоз. Отпустил с богом.
Так там у меня фиксированный SL. А ТР переворотнику вреден. Так что расчитывать нужно было только лот, что несомненно логичнее.
А на счет МА согласен — не канает. Индюк нужен с винрейтом выше 75%.
avatar

kvashnin007

  • 11 июля 2022, 23:22
0
Правда… не вижу связи 9-ти часов с ТФ — Д и W. Это дневная торговля.
Импульсы обычно пробивают границы вчерашнего дня. Но это другая тема.
Коррекции по полосам прогнозировать — не благодарное дело. Думаю сосредоточиться надо над тем, что делать?, если случилось. Фибоначи, поиграться с разными стопами. Есть признаки коррекции. Например, большое отклонение цены от средней (МА), свеча закрылась в обратную сторону или ниже-выше открытия предыдущей свечи, разные каналы.
У Шамана в его открытом советнике с полосами поддержки-сопротивления (не помню, как кликали) есть несколько вариантов на тему «что делать, если...».
avatar

kvashnin007

  • 11 июля 2022, 22:52