0
И еще, Вы не пробовали тралить просто какую-то цену? Не цену SL ордера, а, например, цену БУ группы ордеров. В чем разница?

Попробуйте. Много интересного.
avatar

kvashnin007

  • 7 мая 2022, 20:46
0
ЕЩЕ РАЗ ПОИЗУЧАЛ ВАШЕ ОПИСАНИЕ АЛГОРИТМА.
Таки защита ценового канала. Единственно что хотел вставить свой пятак, так это ордера лимитные должны быть.
Все что я писал ранее, подтверждаю.
Про SL. Смотрите, при отходе цены от канала на расстояние, равное ширине канала, вы выходите в БУ. В этот момент сами закрываются противоположные ордера по стопу и вы тралите прибыль попутными ордерами. Но так как тралить вы будете не от БУ непосредственно, то в SL надо что-то добавлять. В моем случае добавляю дистанцию трала SL.
Т.е. тралить будду от БУ и максимум, что мне грозит, заработать ничего. Я просто не понимаю, как положительные ордера могут закрыться в нашем варианте в минус по SL.
avatar

kvashnin007

  • 7 мая 2022, 20:19
0
Приношу извинения. Вы написали про стоповый на покупку и я понял, что он ставится ниже продажи. У вас не стратегия зашиты канала. Не совсем вник. Вы работаете вовнутрь, а я наружу. Поэтому забудьте все, что к вам не относится.
Только на сеточник это тоже не похоже. Либо вы вяло отписались в описании алгоритма вначале.

А на счет другого алгоритма расчета лотов все просто.
Сел 1 лот. ЦЕНА ВЫШЕ НА ШАГ — БАЙ В ДВА РАЗА БОЛЬШЕ. 2 ЛОТА. ВСЕ КАК И РАНЬШЕ. ТОЛЬКО 1 ЛОТ НА ПРОДАЖУ ЗАКРЫВАЕМ. НИЖЕ — ОПЯТЬ СЕЛ В 2 РАЗА БОЛЬШЕ. 4 ЛОТА. 2 БАЯ ЗАКРЫВАЕМ. И Т.Д. ТЕКУЩАЯ ПРОСАДКА БУДЕТ ВЫШЕ, ЗАТО МАРЖА СВОБОДНЕЕ. В КОНЕЧНОМ ИТОГЕ ПО МОЕМУ АЛГОРИТМУ ПОЛОВИНА ЭТИХ ОРДЕРОВ ВСЕ ОДНО ЗАКРОЕТСЯ В МИНУС, ТОЛЬКО НАБРАВ УБЫТОК В ДВА РАЗА БОЛЬШИЙ. ПРАВДА ВТОРАЯ ПОЛОВИНА ОРДЕРОВ МОГЛА БЫ ДАТЬ ПРИБЫЛЬ ПРИ ТРАЛЕ ЭКВИТМИ.
НО ТУТ УЖ САМОМУ РЕШАТЬ ЧТО ВАЖНЕЕ. ДЕПОЗИТ СОХРАНЯТЬ ИЛИ БАБЛО РУБИТЬ.

Удачи.
avatar

kvashnin007

  • 7 мая 2022, 20:00
0
Да с тралом могу и не попасть. Нужен тест.
Тут проблема в том, что из-за проскальзывания и реквот, ордера не будут в реале открываться, как в тестере, на одних уровнях. И канал будет расширяться. С одной стороны хорошо — брокер сам поможет уйти от лишних хлопт при флете и с другой, проще организовать трал по эквити. У меня трал по SL лучше из-за своей фишки, а вашего алгоритма открытия я не знаю. Но не факт, что мой вариант лучше. Просто дальнейшее развитие моего алгоритма предпочитает мой вариант.
avatar

kvashnin007

  • 6 мая 2022, 22:29
0
Да и трал эквити будет здесь менее эффективным, чем трал SL каждого ордера, когда они останутся однонаправленными.
И еще, если начнет прижимать просадка по свободным бабулям, посмотрите у меня на блоге еще один вариант расчета ордеров.

Удачи.
avatar

kvashnin007

  • 6 мая 2022, 22:26
0
Хотите, чтобы полет был лучше, чем нормальный?
Добавьте SL, равный двум ширинам канала плюс дистанция трала SL и будет вам счастье.
avatar

kvashnin007

  • 6 мая 2022, 22:13
0
P.S.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void calculateTma(int limit)
{
   int i,j,k;
   double FullLength = 2.0*HalfLength+1.0;
   
   for (i=limit; i>=0; i--)
     {
     double sum  = (HalfLength+1)*iMA(NULL,0,1,0,MODE_SMA,Price,i);
     double sumw = (HalfLength+1);
     
     for(j=1, k=HalfLength; j<=HalfLength; j++, k--)
       {
       sum  += k*iMA(NULL,0,1,0,MODE_SMA,Price,i+j);
       sumw += k;
       }
     tmBuffer[i] = sum/sumw;
            
       double diff = iMA(NULL,0,1,0,MODE_SMA,Price,i)-tmBuffer[i];
       
       if (i> (Bars-HalfLength-1)) 
         continue;
       if (i==(Bars-HalfLength-1))
         {
         upBuffer[i] = tmBuffer[i];
         dnBuffer[i] = tmBuffer[i];
         if (diff>=0)
           {
           wuBuffer[i] = MathPow(diff,2);
           wdBuffer[i] = 0;
           }
         else
           {               
           wdBuffer[i] = MathPow(diff,2);
           wuBuffer[i] = 0;
           }                  
         continue;
         }
         if(diff>=0)
           {
           wuBuffer[i] = (wuBuffer[i+1]*(FullLength-1)+MathPow(diff,2))/FullLength;
           wdBuffer[i] =  wdBuffer[i+1]*(FullLength-1)/FullLength;
           }
         else
           {
           wdBuffer[i] = (wdBuffer[i+1]*(FullLength-1)+MathPow(diff,2))/FullLength;
           wuBuffer[i] =  wuBuffer[i+1]*(FullLength-1)/FullLength;
           }
         upBuffer[i] = tmBuffer[i] + Deviation*MathSqrt(wuBuffer[i]);
         dnBuffer[i] = tmBuffer[i] - Deviation*MathSqrt(wdBuffer[i]);
     }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void doAlert(string doWhat)
{
   static string   previousAlert="";
   static datetime previousTime;
   string message;
   
   if (previousAlert!=doWhat || previousTime!=Time[0]) 
     {
     previousAlert = doWhat;
     previousTime  = Time[0];

     message= StringConcatenate(_Symbol," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," TMA+CG:  ",doWhat);
     
     if (alertsMessage) 
       Alert(message);
     if (alertsEmail)   
       SendMail(StringConcatenate(_Symbol," TMA+CG "),message);
     if (alertsMobile)  
       SendNotification(_Symbol+" TMA+CG "+ message);
     if (alertsSound)   
       PlaySound(soundFile);  //"alert2.wav");
     }
}
//----------------------------------------------------------------
int stringToTimeFrame(string tfs)
{
   for(int l = StringLen(tfs)-1; l >= 0; l--)
     {
      int charr = StringGetChar(tfs,l);
      
      if((charr > 96 && charr < 123) || (charr > 223 && charr < 256))
         tfs = StringSetChar(tfs, 1, charr - 32);
      else 
        if(charr > -33 && charr < 0)
          tfs = StringSetChar(tfs, 1, charr + 224);
     }
   int tf=0;
         if (tfs=="M1" || tfs=="1")     tf=PERIOD_M1;
         if (tfs=="M5" || tfs=="5")     tf=PERIOD_M5;
         if (tfs=="M15"|| tfs=="15")    tf=PERIOD_M15;
         if (tfs=="M30"|| tfs=="30")    tf=PERIOD_M30;
         if (tfs=="H1" || tfs=="60")    tf=PERIOD_H1;
         if (tfs=="H4" || tfs=="240")   tf=PERIOD_H4;
         if (tfs=="D1" || tfs=="1440")  tf=PERIOD_D1;
         if (tfs=="W1" || tfs=="10080") tf=PERIOD_W1;
         if (tfs=="MN" || tfs=="43200") tf=PERIOD_MN1;
         if (tf==0 || tf<_Period)      tf=_Period;
   return(tf);
}
//----------------------------------------------------------------
avatar

kvashnin007

  • 6 мая 2022, 22:00
0
P.S.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void calculateTma(int limit)
{
   int i,j,k;
   double FullLength = 2.0*HalfLength+1.0;
   
   for (i=limit; i>=0; i--)
     {
     double sum  = (HalfLength+1)*iMA(NULL,0,1,0,MODE_SMA,Price,i);
     double sumw = (HalfLength+1);
     
     for(j=1, k=HalfLength; j<=HalfLength; j++, k--)
       {
       sum  += k*iMA(NULL,0,1,0,MODE_SMA,Price,i+j);
       sumw += k;
       }
     tmBuffer[i] = sum/sumw;
            
       double diff = iMA(NULL,0,1,0,MODE_SMA,Price,i)-tmBuffer[i];
       
       if (i> (Bars-HalfLength-1)) 
         continue;
       if (i==(Bars-HalfLength-1))
         {
         upBuffer[i] = tmBuffer[i];
         dnBuffer[i] = tmBuffer[i];
         if (diff>=0)
           {
           wuBuffer[i] = MathPow(diff,2);
           wdBuffer[i] = 0;
           }
         else
           {               
           wdBuffer[i] = MathPow(diff,2);
           wuBuffer[i] = 0;
           }                  
         continue;
         }
         if(diff>=0)
           {
           wuBuffer[i] = (wuBuffer[i+1]*(FullLength-1)+MathPow(diff,2))/FullLength;
           wdBuffer[i] =  wdBuffer[i+1]*(FullLength-1)/FullLength;
           }
         else
           {
           wdBuffer[i] = (wdBuffer[i+1]*(FullLength-1)+MathPow(diff,2))/FullLength;
           wuBuffer[i] =  wuBuffer[i+1]*(FullLength-1)/FullLength;
           }
         upBuffer[i] = tmBuffer[i] + Deviation*MathSqrt(wuBuffer[i]);
         dnBuffer[i] = tmBuffer[i] - Deviation*MathSqrt(wdBuffer[i]);
     }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void doAlert(string doWhat)
{
   static string   previousAlert="";
   static datetime previousTime;
   string message;
   
   if (previousAlert!=doWhat || previousTime!=Time[0]) 
     {
     previousAlert = doWhat;
     previousTime  = Time[0];

     message= StringConcatenate(_Symbol," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," TMA+CG:  ",doWhat);
     
     if (alertsMessage) 
       Alert(message);
     if (alertsEmail)   
       SendMail(StringConcatenate(_Symbol," TMA+CG "),message);
     if (alertsMobile)  
       SendNotification(_Symbol+" TMA+CG "+ message);
     if (alertsSound)   
       PlaySound(soundFile);  //"alert2.wav");
     }
}
//----------------------------------------------------------------
int stringToTimeFrame(string tfs)
{
   for(int l = StringLen(tfs)-1; l >= 0; l--)
     {
      int charr = StringGetChar(tfs,l);
      
      if((charr > 96 && charr < 123) || (charr > 223 && charr < 256))
         tfs = StringSetChar(tfs, 1, charr - 32);
      else 
        if(charr > -33 && charr < 0)
          tfs = StringSetChar(tfs, 1, charr + 224);
     }
   int tf=0;
         if (tfs=="M1" || tfs=="1")     tf=PERIOD_M1;
         if (tfs=="M5" || tfs=="5")     tf=PERIOD_M5;
         if (tfs=="M15"|| tfs=="15")    tf=PERIOD_M15;
         if (tfs=="M30"|| tfs=="30")    tf=PERIOD_M30;
         if (tfs=="H1" || tfs=="60")    tf=PERIOD_H1;
         if (tfs=="H4" || tfs=="240")   tf=PERIOD_H4;
         if (tfs=="D1" || tfs=="1440")  tf=PERIOD_D1;
         if (tfs=="W1" || tfs=="10080") tf=PERIOD_W1;
         if (tfs=="MN" || tfs=="43200") tf=PERIOD_MN1;
         if (tf==0 || tf<_Period)      tf=_Period;
   return(tf);
}
//----------------------------------------------------------------


avatar

kvashnin007

  • 6 мая 2022, 21:59
0
Не люблю индюшатину, но этот ТМА вроде не рисует.

#property indicator_chart_window
#property indicator_buffers 5
//------
#property indicator_color1  clrLightSteelBlue  //clrDarkTurquoise
#property indicator_color2  clrDarkOrange  //clrRed
#property indicator_color3  clrDeepSkyBlue  //clrLimeGreen
#property indicator_color4  clrBlue
#property indicator_color5  clrRed
//------
#property indicator_width4  2
#property indicator_width5  2
//------
#property indicator_style1  STYLE_DOT

extern string TimeFrame         = "Current TimeFrame";
extern int    HalfLength        = 24;  //56;
extern ENUM_APPLIED_PRICE Price = PRICE_CLOSE;
extern double Deviation         = 1.32;
input double  DevATR            = 2.687;     
extern int    BARTYPE           = 0;
extern int    ArrUP             = 108,
              ArrDN             = 108;
extern bool   alertsOn          = false;
extern int    SIGNALBAR         = 1;
extern bool   alertsOnHighLow   = true;
extern bool   alertsMessage     = true;
extern bool   alertsSound       = true;
extern bool   alertsEmail       = false;
extern bool   alertsMobile      = false;
extern string soundFile         = "alert.wav";   

double tmBuffer[];
double upBuffer[];
double dnBuffer[];
double wuBuffer[];
double wdBuffer[];
double upArrow[];
double dnArrow[];
string IndicatorFileName;
bool   calculatingTma = false;
bool   returningBars  = false;
int    timeFrame;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
{
   timeFrame  = stringToTimeFrame(TimeFrame);
   HalfLength = MathMax(HalfLength,1);
   IndicatorBuffers(7);
         SetIndexBuffer(0,tmBuffer);  SetIndexDrawBegin(0,HalfLength);  SetIndexStyle(0,DRAW_LINE);
         SetIndexBuffer(1,upBuffer);  SetIndexDrawBegin(1,HalfLength);  SetIndexStyle(1,DRAW_LINE);
         SetIndexBuffer(2,dnBuffer);  SetIndexDrawBegin(2,HalfLength);  SetIndexStyle(2,DRAW_LINE);
         SetIndexBuffer(3,upArrow);   SetIndexStyle(3,DRAW_ARROW); SetIndexArrow(3,ArrUP);
         SetIndexBuffer(4,dnArrow);   SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,ArrDN);
         SetIndexBuffer(5,wuBuffer);  SetIndexStyle(5,DRAW_NONE);
         SetIndexBuffer(6,wdBuffer);  SetIndexStyle(6,DRAW_NONE);
         
   SetIndexLabel(0,stringToTimeFrame(TimeFrame)+": TMA+CG NRP ["+(string)HalfLength+"]");
   SetIndexLabel(1,stringToTimeFrame(TimeFrame)+": Band UPPER");
   SetIndexLabel(2,stringToTimeFrame(TimeFrame)+": Band LOWER");
   SetIndexLabel(3,stringToTimeFrame(TimeFrame)+": ArrowUP");  
   SetIndexLabel(4,stringToTimeFrame(TimeFrame)+": ArrowDN");
     
   IndicatorShortName(stringToTimeFrame(TimeFrame)+": TMA+CG NRP ["+(string)HalfLength+"]");
   
         if (TimeFrame=="calculateTma")  { calculatingTma=true; return(0); }
         if (TimeFrame=="returnBars")    { returningBars=true;  return(0); }
   IndicatorFileName = WindowExpertName();

   return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
{
   int counted_bars=IndicatorCounted();
   int i,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=MathMin(Bars-1,Bars-counted_bars+HalfLength);

           if (returningBars)  { tmBuffer[0] = limit; return(0); }
           if (calculatingTma) { calculateTma(limit); return(0); }
           if (timeFrame > _Period) limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,IndicatorFileName,"returnBars",0,0)*timeFrame/_Period));
   
 	for(i = limit; i >= 0; i--)
     {
      int      shift1 = iBarShift(NULL,timeFrame,Time[i]);
      datetime time1  = iTime    (NULL,timeFrame,shift1);
      
         tmBuffer[i] = iCustom(NULL,timeFrame,IndicatorFileName,"calculateTma",HalfLength,Price,Deviation,0,shift1);
         upBuffer[i] = iCustom(NULL,timeFrame,IndicatorFileName,"calculateTma",HalfLength,Price,Deviation,1,shift1);
         dnBuffer[i] = iCustom(NULL,timeFrame,IndicatorFileName,"calculateTma",HalfLength,Price,Deviation,2,shift1);

         upArrow[i] = EMPTY_VALUE;
         dnArrow[i] = EMPTY_VALUE;
       
       if(BARTYPE==0)
         {              
         if ( Close[i+1]<dnBuffer[i+1] && Close[i+1]<Open[i+1] && Close[i]>Open[i]) 
           upArrow[i] = Close[i];
         if (Close[i+1]>upBuffer[i+1] && Close[i+1]>Open[i+1] && Close[i]<Open[i]) 
           dnArrow[i] = Close[i];
         }
       if(BARTYPE==1)
         {              
         if ( Close[i+1]<dnBuffer[i+1] && Close[i+1]<Open[i+1] && Close[i]<Open[i]+iATR(NULL,0,5,i)* DevATR) 
           upArrow[i] = Close[i];
         if (Close[i+1]>upBuffer[i+1] && Close[i+1]> Open[i+1] && Close[i]>Open[i]-iATR(NULL,0,5,i)* DevATR) 
           dnArrow[i] = Close[i];
         }
       if(BARTYPE==2)
         {              
         if ( Low[i+1]<dnBuffer[i+1] && Open[i+1]>dnBuffer[i+1] && Close[i]<Close[i+1]-iATR(NULL,0,5,i)* DevATR) 
           upArrow[i] = Close[i+1];
         if (High[i+1]>upBuffer[i+1] && Open[i+1]<upBuffer[i+1] && Close[i]>Close[i+1]+iATR(NULL,0,5,i)*DevATR) 
           dnArrow[i] = Close[i+1];
         }  

         if (timeFrame <= _Period || shift1==iBarShift(NULL,timeFrame,Time[i-1])) continue;

         for(int n = 1; i+n < Bars && Time[i+n] >= time1; n++) continue;
         double factor = 1.0 / n;
         
         for(int k = 1; k < n; k++)
            {
            tmBuffer[i+k] = k*factor*tmBuffer[i+n] + (1.0-k*factor)*tmBuffer[i];
            upBuffer[i+k] = k*factor*upBuffer[i+n] + (1.0-k*factor)*upBuffer[i];
            dnBuffer[i+k] = k*factor*dnBuffer[i+n] + (1.0-k*factor)*dnBuffer[i];
            }               
     }
   if (alertsOn)
     {
      if (alertsOnHighLow)       
        {
        if ((Low[SIGNALBAR]  < dnBuffer[SIGNALBAR] && Low[SIGNALBAR+1]  > dnBuffer[SIGNALBAR+1]) || upArrow[SIGNALBAR]!=EMPTY_VALUE) 
          doAlert("LOW пробил Нижнюю Полосу  =  BUY");  //penetrated lower bar");
        if ((High[SIGNALBAR] > upBuffer[SIGNALBAR] && High[SIGNALBAR+1] < upBuffer[SIGNALBAR+1]) || dnArrow[SIGNALBAR]!=EMPTY_VALUE) 
          doAlert("HIGH пробил Верхнюю Полосу  =  SELL");  //penetrated upper bar");
        }
      else
        {
        if (Close[SIGNALBAR] < dnBuffer[SIGNALBAR] && Close[SIGNALBAR+1] > dnBuffer[SIGNALBAR+1]) 
          doAlert("CLOSE ниже Нижней Полосы  =  BUY");  //penetrated lower bar");
        if (Close[SIGNALBAR] > upBuffer[SIGNALBAR] && Close[SIGNALBAR+1] < upBuffer[SIGNALBAR+1]) 
          doAlert("CLOSE выше Верхней Полосы  =  SELL");  //penetrated upper bar");
        }
     } 
   return(0);
}
avatar

kvashnin007

  • 6 мая 2022, 21:56
0
Для душевного удовольствия и полноты ощущений добавили бы открытие ордера не только по закрытию свечи внутрь канала, а и при условии, когда цена вернулась вовнутрь выше-ниже цены открытия предыдущей свечи. За углом Вас ждет нежданчик.
avatar

kvashnin007

  • 6 мая 2022, 21:50
0
Бай или сел тралить нужно, когда средняя цена вышла в плюс. Тут все просто. Тралить и то и другое глупо по определению. Надо какую-то сторону ликвидировать. Либо закрыть одинаковое количество противоположных ордеров, если есть перевес в какую-то сторону и туда же тралить. Либо если уверены, что цена пойдет в ту степь, закрыть все противоположные.
А иначе наличие смысла отсутствует.
avatar

kvashnin007

  • 6 мая 2022, 20:48
0
Извечный вопрос: что лучше? Торговать на свои на бирже или торговать своим около биржи.

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

kvashnin007

  • 6 мая 2022, 20:39
0
Просто удалите строку на которую я обратил внимание. Она не задействована.
avatar

kvashnin007

  • 28 апреля 2022, 23:18
0
Кроме того добавляется «хитрый» функционал для пользователя.
Например, SL ордера поставили для себя или для недобросовестного брокера. А цена до него не дошла N пипсов и он взял и закрылся. Облом.
avatar

kvashnin007

  • 28 апреля 2022, 23:07
0
Вспоминал про RSI и вспомнил, это девочка какая-то просила помощи по ее советнику. Получилось, что на странице блога. Советник не рабочий и интересен только представителям слабого пола.
Ну учится ребенок и хвала всевышнему. Лишь бы не…
avatar

kvashnin007

  • 28 апреля 2022, 22:55
0
Ходи таки голодный.
В Одессе был? Или мимикрия?
В википедии мимикрия переводится как «косить под одессита».
Смотри, дам надфиль. Алмазный.
Доброй ночи.
avatar

kvashnin007

  • 28 апреля 2022, 22:49
0
Ок!
avatar

kvashnin007

  • 28 апреля 2022, 22:42
0
Сергей, я не критикую Вашу работу. Просто смотрю и высказываю свое мнение. Думаю, что на пользу Вам. Да и мне в карму.
Вы можете задуматься, можете проигнорировать.
А Баба-Яга всегда против. Работа у нее такая.
И еще, Сергей. Идеального нет ничего. Всюду компромиссы. Так все устроено. Очень часто многое зависит от везения. Слово то какое. Поэтому, приходится изгаляться, чтобы сдвинуть вероятность какого-то события хоть на долю процента.
Я Вам про SL ничего не говорил. Есть в сове и слава богу.
А вот BU и трал только называются стопами. Можете не включать.
А вот стратегия частичного закрытия ордеров по математике, вроде, не в тему, а вот при тестировании дает очень интересные результаты.
Вы правы — лучший расчет — тестирование.
avatar

kvashnin007

  • 28 апреля 2022, 22:34
0
Виртуальный стоп до реального (какой я хитрый).
Судя по картинке ордера закрываются не по тралу, а по общему SL-ТР, при чем без заметного профита. Если цена подошла к нашему общему SL, Цикл — профит больше «0» закрыли. Дальше цикл — закрываем, все остальное.
avatar

kvashnin007

  • 28 апреля 2022, 22:16
0
Проанализировал график доходности. Сделайте таки закрытие ордеров "+"-"-".
avatar

kvashnin007

  • 28 апреля 2022, 21:44