Список форумов AmiSite.ru AmiSite.ru
Форум по Ами
 FAQ  •  Поиск  •  Пользователи  •  Группы   •  Регистрация  •  Профиль  •  Войти и проверить личные сообщения  •  Вход
 Chartmill Channels Следующая тема
Предыдущая тема
Начать новую тему  Ответить на тему
Автор Сообщение
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Пн Май 15, 2017 3:09 pm Ответить с цитатой Вернуться к началу

Нашел такую штуку:

https://www.chartmill.com/documentation.php?a=170&title=TRADERS%20%E2%80%93%20Chartmill%20(fka%20Monest)%20Channels

По сути это каналы Дончиана, но адаптивные. По описанию не сразу понял, как это строится, но потом раздобыл реализацию на WL.
Код:
      protected override void Execute()
      {
         int atrPeriod = 14;
         int barEnd = 0;
         double atrUnits = 0.5;                                 // yATR higher than the last close
         double tick = Bars.SymbolInfo.Tick;
         DataSeries upBars = new DataSeries( Bars, "upper" );
         DataSeries dnBars = new DataSeries( Bars, "lower" );
         DataSeries upC = new DataSeries( Bars, "upper channel" );
         DataSeries dnC = new DataSeries( Bars, "lower channel" );
         
         for(int bar = GetTradingLoopStartBar(atrPeriod) * 3; bar < Bars.Count; bar++)
         {
            //if( bar < Bars.Count-1 )                           // last bar only
            //   continue;
           
            double atr = ATR.Series( Bars,atrPeriod )[bar] * atrUnits;   // yATR higher than the last close
            //atr = Close[bar] * 0.05;                           // price levels x%
            double lastCloseUP = Close[bar] + tick;
            double lastCloseDN = Close[bar] - tick;
            double lastCloseLowStop = Close[bar] + atr;
            double lastCloseHighStop = Close[bar] - atr;
            int lower = 0;
            int higher = 0;
         
            while( lastCloseUP < lastCloseLowStop )
            {
               int tempLower = 0;
               
               for( int i = bar; i >= barEnd; i-- )
               {
                  if( Close[i] < lastCloseUP )
                  {
                     tempLower++;
                  }
                 
                  if( tempLower > lower )
                     lower = tempLower;
                     
                  lastCloseUP += Bars.SymbolInfo.Tick;
               }
            }
           
            while( lastCloseDN > lastCloseHighStop )
            {
               int tempHigher = 0;
               
               for( int i = bar; i >= barEnd; i-- )
               {
                  if( Close[i] > lastCloseDN )
                  {
                     tempHigher++;
                  }
                 
                  if( tempHigher > higher )
                     higher = tempHigher;
                     
                  lastCloseDN -= Bars.SymbolInfo.Tick;
               }
            }
           
            upBars[bar] = lower;
            dnBars[bar] = higher;
            //PrintDebug( lower + "\t" + higher );
           
            upC[bar] = Highest.Series( High, lower )[bar];
            dnC[bar] = Lowest.Series( Low, lower )[bar];
         }
         
         //PrintDebug( upC[Bars.Count-1] + "\t" + dnC[Bars.Count-1] );
         
         ChartPane upPane = CreatePane( 20,true,true );
         ChartPane dnPane = CreatePane( 20,true,true );
         PlotSeries( upPane, upBars, Color.Blue, WealthLab.LineStyle.Solid, 1 );
         PlotSeries( dnPane, dnBars, Color.Red, WealthLab.LineStyle.Solid, 1 );
         PlotSeriesFillBand( PricePane, upC, dnC, Color.Red, Color.Transparent, LineStyle.Solid, 1 );
         HideVolume();
      }


Перенес код на Ami, но получается какая-то фигня. Во всяком случае выглядит не так, как на картинках.
Код:
SetBarsRequired(sbrAll,sbrAll);

atrPeriod = Param( "atrPeriod", 14, 3, 30, 1 );
atrUnits = Param( "atrUnits", 0.5, 0.25, 2.0, 0.25 );
tick = TickSize;

A = ATR( atrPeriod ) * atrUnits;

upBars = dnBars = upC = dnC = 0;
for ( bar = atrPeriod * 3; bar < BarCount; bar++ ) {
   lastCloseUP = Close[bar] + tick;
   lastCloseDN = Close[bar] - tick;
   lastCloseLowStop = Close[bar] + A[bar];
   lastCloseHighStop = Close[bar] - A[bar];
   lower = 0;
   higher = 0;

   while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) lower = tempLower;
        lastCloseUP += tick;
      }
   }

   while( lastCloseDN > lastCloseHighStop ) {
      tempHigher = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) {
       if( Close[i] > lastCloseDN ) tempHigher++;
        if( tempHigher > higher ) higher = tempHigher;
        lastCloseDN -= tick;
      }
   }
   
   upBars[bar] = lower;
   dnBars[bar] = higher;

   HH = HHV( High, lower );
   LL = LLV( Low, higher ); // тут мне кажется опечатка в WL и нужно использовать higher, а не lower
   
   upC[bar] = HH[bar];
   dnC[bar] = LL[bar];
}

Plot( upC, "upC", colorYellow );
Plot( dnC, "dnC", colorRed );
Plot( C, "", colorDefault, styleBar );
Мне кажется, что каналы не должны так скакать вверх-вниз. По аналогии с обычным HHV, например, линия должна как минимум не повышаться до ее пробоя. Поскольку в коде используется закрытие, то добавил такую штуку:
Код:
upC2 = IIf( C > Ref( upC, -1 ), upC, Min( upC, Ref( upC, -1 ) ) );
Т.е. если текущее закрытие превысило прошлое значение upC, то взять текущее upC, иначе минимальное между текущим и прошлым upC. Вроде местами чуть лучше, но в целом та же фигня... В связи с этим два вопроса:

1. Что я делаю не так?
2. Как сделать, чтоб не тормозило?
Посмотреть профиль Отправить личное сообщение
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Пн Май 15, 2017 8:04 pm Ответить с цитатой Вернуться к началу

Каналы стали более канальными после добавления такой "концовки":
Код:
   HH = HHV( High, lower );
   LL = LLV( Low, higher );
   
   upC[bar] = HH[bar];
   dnC[bar] = LL[bar];
   
   if ( C[bar] < upC[bar-1] ) upC[bar] = Min( upC[bar-1], upC[bar] );
   if ( C[bar] > dnC[bar-1] ) dnC[bar] = Max( dnC[bar-1], dnC[bar] );
}

Осталось победить тормоза.
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Май 18, 2017 12:01 am Ответить с цитатой Вернуться к началу

Попытался разобраться. Ерунда какая-то.
Код:
while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) lower = tempLower;
        lastCloseUP += tick;
      }
   }

Идем на 200 баров назад и считаем сколько баров ниже lastCloseUP
if( Close[i] < lastCloseUP ) tempLower++;. Запомнили.
Потом повышаем lastCloseUP += tick; и опять считаем сколько баров ниже и если их стало больше чем при прошлом прогоне, то запоминаем новую цифру. if( tempLower > lower ) lower = tempLower;

Понятно, что самое большое значение получится при последнем прогоне т.к. уровень lastCloseUP максимальный. Тогда зачем весь этот геморой? Просто считаем lower при lastCloseUP == lastCloseLowStop...

Или я чего-то не понял.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Чт Май 18, 2017 12:22 pm Ответить с цитатой Вернуться к началу

000 писал(а):
Понятно, что самое большое значение получится при последнем прогоне т.к. уровень lastCloseUP максимальный.

Не факт. Для примера добавим заполнение массива, в котором будем накапливать "период" HHV.
Код:

upPer = 0;
...
while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) { lower = tempLower; upPer[bar] = bar - i; }
        lastCloseUP += tick;
      }
   }
....
Plot( upPer, "upPer", colorBrightGreen, styleLeftAxisScale );

На графике видно, что период все же переменный.
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Май 18, 2017 12:51 pm Ответить с цитатой Вернуться к началу

Конечно он будет переменный.
Но.
Хм.
Попробуй вот так сделать. Вместо
Код:
while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) lower = tempLower;
        lastCloseUP += tick;
      }
   }


Поставь
Код:

for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseLowStop - tick ) lower++;
}

И скорее всего результат будет идентичный

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Чт Май 18, 2017 12:58 pm Ответить с цитатой Вернуться к началу

Посмотрю еще раз на досуге. Честно говоря, по исходному описанию я мало что понял. Но графики там красивые получаются. "Базы" рисуются очень убедительно.
Посмотреть профиль Отправить личное сообщение
Marcello



Зарегистрирован: 30.05.2015
Сообщения: 69

СообщениеДобавлено: Чт Май 18, 2017 3:29 pm Ответить с цитатой Вернуться к началу

Линии местами совпадают один в один, а местами заметно различаются. Но общая динамика одинакова, тут согласен. Вот код:
Код:
SetBarsRequired(sbrAll,sbrAll);

atrPeriod = Param( "atrPeriod", 14, 3, 30, 1 );
atrUnits = Param( "atrUnits", 0.5, 0.25, 2.0, 0.25 );
tick = TickSize;

A = ATR( atrPeriod ) * atrUnits;

upBars = upBars2 = 0;
for ( bar = atrPeriod * 3; bar < BarCount; bar++ ) {
   lastCloseUP = Close[bar] + tick;
   lastCloseLowStop = Close[bar] + A[bar];
   lower = 0;

   while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) lower = tempLower;
        lastCloseUP += tick;
      }
   }

   lastCloseUP = Close[bar] + tick;
   lastCloseLowStop = Close[bar] + A[bar];
   lower2 = 0;

   for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
      if( Close[i] < lastCloseLowStop - tick ) lower2++;
   }

   upBars[bar] = lower;
   upBars2[bar] = lower2;
}

Plot( upBars, "upBars", colorYellow );
Plot( upBars2, "upBars2", colorBrightGreen );
Посмотреть профиль Отправить личное сообщение
Orange2000



Зарегистрирован: 15.10.2009
Сообщения: 185

СообщениеДобавлено: Чт Май 18, 2017 7:36 pm Ответить с цитатой Вернуться к началу

Marcello писал(а):
Линии местами совпадают один в один, а местами заметно различаются. Но общая динамика одинакова, тут согласен. Вот код:
Код:
SetBarsRequired(sbrAll,sbrAll);

atrPeriod = Param( "atrPeriod", 14, 3, 30, 1 );
atrUnits = Param( "atrUnits", 0.5, 0.25, 2.0, 0.25 );
tick = TickSize;

A = ATR( atrPeriod ) * atrUnits;

upBars = upBars2 = 0;
for ( bar = atrPeriod * 3; bar < BarCount; bar++ ) {
   lastCloseUP = Close[bar] + tick;
   lastCloseLowStop = Close[bar] + A[bar];
   lower = 0;

   while( lastCloseUP < lastCloseLowStop ) {
      tempLower = 0;
      for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
       if( Close[i] < lastCloseUP ) tempLower++;
        if( tempLower > lower ) lower = tempLower;
        lastCloseUP += tick;
      }
   }

   lastCloseUP = Close[bar] + tick;
   lastCloseLowStop = Close[bar] + A[bar];
   lower2 = 0;

   for( i = bar; i >= Max( 0, bar - 200 ); i-- ) { // тут ограничил 200 барами, т.к. больше считаю не нужно, да и тормозит...
      if( Close[i] < lastCloseLowStop - tick ) lower2++;
   }

   upBars[bar] = lower;
   upBars2[bar] = lower2;
}

Plot( upBars, "upBars", colorYellow );
Plot( upBars2, "upBars2", colorBrightGreen );

Интересная идея. Но код не работает(
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Май 18, 2017 8:22 pm Ответить с цитатой Вернуться к началу

Наверное у тебя TickSize не задан.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:      
Начать новую тему  Ответить на тему


 Перейти:   



Следующая тема
Предыдущая тема
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы не можете скачивать файлы


Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme :: Часовой пояс: GMT + 3

File Attachment © by Meik Sievertsen