В программе TSLab предусмотрены два способа реализации индикаторов/стратегий. Один из них – визуальное
программирование, когда алгоритм индикатора/стратегии собирается из готовых блоков, второй – реализация
индикатора/стратегии в виде кода на языке C#.
Для реализации стратегии NRTR необходимо использовать индикатор NRTR, стратегия реализована в виде кода.
Пару слов о фильтре. NRTR (Nick Rypock Trailing Reverse) – индикатор, основанный на подходе, который используется в
«Скользящем фильтре» (информации по нему много в сети, достаточно забить в поисковик Trailing Reverse). Суть данного
индикатора – фильтрация незначительных колебаний цен в период тренда и определение разворота тенденции. В итоге мы
получаем формулы:
Для восходящих трендов:
NRTR = Highest(Close, period)*(1-(K/100)),
Для нисходящих трендов:
NRTR = Lowest(Close, period)*(1+(K/100)),
Где К – коэффициент, который задается человеком, использующим этот индикатор и отвечающий за величину, на которую
значение индикатора отстоит от локальных экстремумов цены.
По-сути, NRTR – это Максимум за/Минимум за, сдвинутые по оси цены на коэф. К и объединенные в одну кривую по
определенному правилу.
Для удобства код индикатора вынесен в отдельную функцию (GenNRTR). Код постарался подробно откомментировать, чтобы
можно было его быстрее и удобней читать и использовать. Комментарии и пожелания приветствуются!
Подробнее об этой стратегии можно прочитать по адресу первоисточника, из которого и взят материла.
http://konkop.narod.ru/nrma.htmВот так эта система выглядит в коде:
Ссылка на файл:
http://www.tslab.ru/ubb/ubbthreads.php?ubb=download&Number=1043&filename=nrtr_script.cs
/*================================================================================
* Стратегия: NRTR (на основе индикатора NRTR - Nick Rypock Trailing Reverse)
* Платформа: TSLab версия 1.1.7.0
* Дата создания: 01.07.2010
* Реализовано: Laber
*================================================================================*/
using System;
using System.Collections.Generic;
using TSLab.Script;
using TSLab.Script.Handlers;
using TSLab.Script.Optimization;
using TSLab.Script.Helpers;
namespace TSLab.NRTR
{
//================================================================================
public class NRTR : IExternalScript
{
public double StopBuyPrice, StopSellPrice, StopShortPrice, StopCoverPrice;
public IPosition LongPos, ShortPos;
//================================================================================
// функция вычисления индикатора NRTR (последовательность значений)
// Period - период скользящей средней для расчета NRTR
// Multiple - множитель для расчета NRTR
public IList<double> GenNRTR(ISecurity source, int Period, double Multiple)
{
double vNRTR;
double K, PrevK;
double Reverse = 0;
double Price;
double HighPrice;
double LowPrice;
int Trend = 0;
int NewTrend;
IList<double> nNRTR = new List<double>(source.Bars.Count);
//--------------------------------------------------------------------------------
K = source.ClosePrices[0];
vNRTR = source.ClosePrices[0];
HighPrice = source.HighPrices[0];
LowPrice = source.LowPrices[0];
for (int bar = 0; bar < source.Bars.Count-1; bar++)
{
//--------------------------------------------------------------------------------
#region calculate values
Price = source.ClosePrices[bar];
PrevK = K;
K = (PrevK + (Price - PrevK) / Period) * Multiple;
NewTrend = 0;
if (Trend >= 0)
{
if (Price > HighPrice) HighPrice = Price;
Reverse = HighPrice - K;
if (Price <= Reverse)
{
NewTrend = -1;
LowPrice = Price;
Reverse = LowPrice + K;
}
}
if (Trend <= 0)
{
if (Price < LowPrice) LowPrice = Price;
Reverse = LowPrice + K;
if (Price >= Reverse)
{
NewTrend = +1;
HighPrice = Price;
Reverse = HighPrice - K;
}
}
if (NewTrend != 0) Trend = NewTrend;
// значение NRTR
vNRTR = Reverse;
#endregion
//--------------------------------------------------------------------------------
// добавление нового значения в последовательность
nNRTR.Add(vNRTR);
}
return nNRTR;
}
//================================================================================
// Параметры оптимизации
// ParamPeriod - параметр оптимизации для периода скользящей средней
// ParamMultiple - параметр оптимизации для множителя
public OptimProperty ParamPeriod = new OptimProperty(10, 2, 20, 2);
public OptimProperty ParamMultiple = new OptimProperty(0.1, 0.1, 1, 0.1);
//================================================================================
public virtual void Execute(IContext ctx, ISecurity source)
{
#region Variables
double vNRTR; // значение NRTR для текущего бара
int Period; // период скользящей средней для расчета NRTR
double Multiple; // множитель для расчета NRTR
double Price; // текущая цена закрытия
#endregion
//--------------------------------------------------------------------------------
// Obtain parameters
Period = ParamPeriod;
Multiple = ParamMultiple;
// серия значений индикатора NRTR
// кэширование с учетом параметров Period и Multiple
IList<double> nNRTR = ctx.GetData("NRTR", new[] {Period.ToString()+"_"+Multiple.ToString()},
delegate { return GenNRTR(source, Period, Multiple); });
//================================================================================
#region основной цикл - проход по барам
int barsCount = source.Bars.Count;
for (int bar = 0; bar < barsCount-1; bar++)
{
//--------------------------------------------------------------------------------
#region calculate values
vNRTR = nNRTR[bar];
Price = source.ClosePrices[bar];
#endregion
//================================================================================
#region execute signals
//--------------------------------------------------------------------------------
// выполнение сигналов для длинной позиции
IPosition LongPos = source.Positions.GetLastActiveForSignal("LN");
if (LongPos == null)
{
// Если нет активной длинной позиции
if (Price > vNRTR)
{
// Если есть сигнал Buy,
// выдаем ордер на открыте новой длинной позиции.
source.Positions.BuyAtMarket(bar+1, 1, "LN");
}
}
else
{
// Если есть активная длинная позиция
if (Price < vNRTR)
{
// Если есть сигнал Sell,
// выдаем ордер на закрыте длинной позиции.
LongPos.CloseAtMarket(bar+1, "LX");
}
}
//--------------------------------------------------------------------------------
// выполнение сигналов для короткой позиции
IPosition ShortPos = source.Positions.GetLastActiveForSignal("SN");
if (ShortPos == null)
{
// Если нет активной короткой позиции
if (Price < vNRTR)
{
// Если есть сигнал Short
// выдаем ордер на открыте новой короткой позиции.
source.Positions.SellAtMarket(bar+1, 1, "SN");
}
}
else
{
// Если есть активная короткая позиция,
if (Price > vNRTR)
{
// Если есть сигнал Cover
// выдаем ордер на закрыте короткой позиции.
ShortPos.CloseAtMarket(bar+1, "SX");
}
}
#endregion
}
#endregion
//================================================================================
#region прорисовка графиков
// Берем основную панель (Pane)
IPane mainPane = ctx.First;
// Отрисовка
mainPane.AddList("NRTR", nNRTR, ListStyles.LINE, 0xa000a0, LineStyles.SOLID, PaneSides.RIGHT);
#endregion
//--------------------------------------------------------------------------------
}
}
}
На графике отображены границы ценовых каналов:
Результаты тестирования стратегии.
Кривая капитала:
Отчет с результатами тестирования:
В прикрепленных файлах можно найти всю необходимую информацию по этой стратегии.