Автор: Laber
Стратегия Volatility breakout - Tue Jul 06 2010 06:28 PM
Для реализации стратегии Volatility breakout (пробой волатильности) за основу взят скрипт на сайте Wealth-Lab.
В классике волатильность определяется по диапазону High - Low свечей. В расмотренном примере для определения волатильности используются границы Боллинджера (Bollinger Bands).
В этом примере открытие позиции выполняется при пробитии верхней границы (по закрытию - то есть цена закрытия больше границы). Дополнительным условием принимается то, что закрытие последней свечи происходит выше скользящей средней.
Закрытие позиции производится при пробитии нижней границы конверта (цена закрытия меньше границы) также с дополнительным условием по скользящей средней.
В классическом варианте открытие происходит по стоп-ордеру, который выставляется на нужной цене. Однако в нашей реализации сохранена схема первоисточника. На этот раз каждую границу (верхнюю и нижнюю) вычисляем со своими парамметрами, для длинных и коротких позиций отдельно.
Пару слов об оптимизации.
Параметров слишком много, чтобы проводить сквозную оптиммизацию по всем параметрам сразу.
Поэтому для начала определяются оптимальные параметры для открытия позиций, а затем с применением уже найденных значений определяются параметры для закрытия позиций. Разумеется параметры для коротких и длинных позиций оптимизируются по отдельности.
Вот так эта система выглядит в коде:
Ссылка на файл: http://www.tslab.ru/ubb/ubbthreads.php?u...lity_scheme.xml
На графике отображены границы ценовых каналов:
Результаты тестирования стратегии.
Кривая капитала:
Отчет с результатами тестирования:
В прикрепленных файлах можно найти всю необходимую информацию по этой стратегии.
В классике волатильность определяется по диапазону High - Low свечей. В расмотренном примере для определения волатильности используются границы Боллинджера (Bollinger Bands).
В этом примере открытие позиции выполняется при пробитии верхней границы (по закрытию - то есть цена закрытия больше границы). Дополнительным условием принимается то, что закрытие последней свечи происходит выше скользящей средней.
Закрытие позиции производится при пробитии нижней границы конверта (цена закрытия меньше границы) также с дополнительным условием по скользящей средней.
В классическом варианте открытие происходит по стоп-ордеру, который выставляется на нужной цене. Однако в нашей реализации сохранена схема первоисточника. На этот раз каждую границу (верхнюю и нижнюю) вычисляем со своими парамметрами, для длинных и коротких позиций отдельно.
Пару слов об оптимизации.
Параметров слишком много, чтобы проводить сквозную оптиммизацию по всем параметрам сразу.
Поэтому для начала определяются оптимальные параметры для открытия позиций, а затем с применением уже найденных значений определяются параметры для закрытия позиций. Разумеется параметры для коротких и длинных позиций оптимизируются по отдельности.
Вот так эта система выглядит в коде:
Ссылка на файл: http://www.tslab.ru/ubb/ubbthreads.php?u...lity_scheme.xml
Code:
/*================================================================================ * Стратегия: Volatility breakout * Платформа: TSLab версия 1.1.8.0 * Дата создания: 06.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.Volatility { //================================================================================ public class Volatility : IExternalScript { // используем переменные-флаги для сигналов public bool bBuy; // флаг сигнала открытия длинной позиции public bool bSell; // флаг сигнала закрытия длинной позиции public bool bShort; // флаг сигнала открытия короткой позиции public bool bCover; // флаг сигнала закрытия короткой позиции public IPosition LongPos, ShortPos; //================================================================================ // Параметры оптимизации // параметра для длинных позиций public OptimProperty LongNBBPeriodParam = new OptimProperty(10, 5, 50, 5); public OptimProperty LongXBBPeriodParam = new OptimProperty(5, 5, 50, 5); public OptimProperty LongNKoefParam = new OptimProperty(1.5, 0.5, 3, 0.5); public OptimProperty LongXKoefParam = new OptimProperty(1, 0.5, 3, 0.5); public OptimProperty LongNPeriodParam = new OptimProperty(20, 20, 100, 10); public OptimProperty LongXPeriodParam = new OptimProperty(35, 10, 50, 5); // параметра для коротких позиций public OptimProperty ShortNBBPeriodParam = new OptimProperty(15, 5, 50, 5); public OptimProperty ShortXBBPeriodParam = new OptimProperty(5, 5, 50, 5); public OptimProperty ShortNKoefParam = new OptimProperty(1, 0.5, 3, 0.5); public OptimProperty ShortXKoefParam = new OptimProperty(1.5, 0.5, 3, 0.5); public OptimProperty ShortNPeriodParam = new OptimProperty(30, 20, 100, 10); public OptimProperty ShortXPeriodParam = new OptimProperty(20, 10, 50, 5); //================================================================================ public virtual void Execute(IContext ctx, ISecurity source) { int StartBar = 0; #region Variables // для длинных позиций // период расчета Bollinger Bands int LongNBBPeriod; // для открытия позиции int LongXBBPeriod; // для закрытия позиции // коэффициент стандартного отклонения для Bollinger Bands double LongNKoef; // для открытия позиции double LongXKoef; // для закрытия позиции // период расчета простой скользящей средней SMA int LongNPeriod; // для открытия позиции int LongXPeriod; // для закрытия позиции // для коротких позиций // период расчета Bollinger Bands int ShortNBBPeriod; // для открытия позиции int ShortXBBPeriod; // для закрытия позиции // коэффициент стандартного отклонения для Bollinger Bands double ShortNKoef; // для открытия позиции double ShortXKoef; // для закрытия позиции // период расчета простой скользящей средней SMA int ShortNPeriod; // для открытия позиции int ShortXPeriod; // для закрытия позиции #endregion //-------------------------------------------------------------------------------- #region Obtain parameters LongNBBPeriod = LongNBBPeriodParam; LongXBBPeriod = LongXBBPeriodParam; LongNKoef = LongNKoefParam; LongXKoef = LongXKoefParam; LongNPeriod = LongNPeriodParam; LongXPeriod = LongXPeriodParam; ShortNBBPeriod = ShortNBBPeriodParam; ShortXBBPeriod = ShortXBBPeriodParam; ShortNKoef = ShortNKoefParam; ShortXKoef = ShortXKoefParam; ShortNPeriod = ShortNPeriodParam; ShortXPeriod = ShortXPeriodParam; StartBar = LongNBBPeriod; if (LongXBBPeriod > StartBar) StartBar = LongXBBPeriod; if (LongNPeriod > StartBar) StartBar = ShortNPeriod; if (LongXPeriod > StartBar) StartBar = ShortXPeriod; if (ShortNBBPeriod > StartBar) StartBar = ShortNBBPeriod; if (ShortXBBPeriod > StartBar) StartBar = ShortXBBPeriod; if (ShortNPeriod > StartBar) StartBar = ShortNPeriod; if (ShortXPeriod > StartBar) StartBar = ShortXPeriod; // Вычисляем верхнюю и нижнюю границы Bollinger Bands. // Используем GetData для кеширования данных и ускорения оптимизации. // для длинных позиций // серия значений верхней границы - открытие позиции IList<double> nLongHighRange = ctx.GetData("LongHighRange", new[] {LongNBBPeriod.ToString()+LongNKoef.ToString()}, delegate { return Series.BollingerBands( source.ClosePrices, LongNBBPeriod, LongNKoef, true); }); // серия значений нижней границы - закрытие позиции IList<double> nLongLowRange = ctx.GetData("LongLowRange", new[] {LongXBBPeriod.ToString()+LongXKoef.ToString()}, delegate { return Series.BollingerBands( source.ClosePrices, LongXBBPeriod, LongXKoef, false); }); // серия для простой скользящей средней SMA для открытия позиции IList<double> nLongNSMA = ctx.GetData("LongNSMA", new[] {LongNPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, LongNPeriod); }); // серия для простой скользящей средней SMA для закрытия позиции IList<double> nLongXSMA = ctx.GetData("LongXSMA", new[] {LongXPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, LongXPeriod); }); // для коротких позиций // серия значений нижней границы - открытие позиции IList<double> nShortLowRange = ctx.GetData("ShortLowRange", new[] {ShortNBBPeriod.ToString()+ShortNKoef.ToString()}, delegate { return Series.BollingerBands( source.ClosePrices, ShortNBBPeriod, ShortNKoef, false); }); // серия значений верхней границы - закрытие позиции IList<double> nShortHighRange = ctx.GetData("ShortHighRange", new[] {ShortXBBPeriod.ToString()+ShortXKoef.ToString()}, delegate { return Series.BollingerBands( source.ClosePrices, ShortXBBPeriod, ShortXKoef, true); }); // серия для простой скользящей средней SMA для открытия позиции IList<double> nShortNSMA = ctx.GetData("ShortNSMA", new[] {ShortNPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, ShortNPeriod); }); // серия для простой скользящей средней SMA для закрытия позиции IList<double> nShortXSMA = ctx.GetData("ShortXSMA", new[] {ShortXPeriod.ToString()}, delegate { return Series.SMA(source.ClosePrices, ShortXPeriod); }); #endregion //================================================================================ #region основной цикл - проход по барам int barsCount = source.Bars.Count; for (int bar = StartBar; bar < barsCount-1; bar++) { //-------------------------------------------------------------------------------- #region generate signals // сброс значений сигналов bBuy = false; bSell = false; bShort = false; bCover = false; // установка сигналов по условиям // для длинных позиций if (source.ClosePrices[bar] > nLongNSMA[bar]) { if (source.ClosePrices[bar] > nLongHighRange[bar]) bBuy = true; } if (source.ClosePrices[bar] < nLongXSMA[bar]) { if (source.ClosePrices[bar] < nLongLowRange[bar]) bSell = true; } // для коротких позиций if (source.ClosePrices[bar] < nShortNSMA[bar]) { if (source.ClosePrices[bar] < nShortLowRange[bar]) bShort = true; } if (source.ClosePrices[bar] > nShortXSMA[bar]) { if (source.ClosePrices[bar] > nShortHighRange[bar]) bCover = true; } #endregion //================================================================================ #region execute signals //-------------------------------------------------------------------------------- // выполнение сигналов для длинной позиции IPosition LongPos = source.Positions.GetLastActiveForSignal("LN"); if (LongPos == null) { // Если нет активной длинной позиции if (bBuy) { // Если есть сигнал Buy, // выдаем ордер на открыте новой длинной позиции. source.Positions.BuyAtMarket(bar+1, 1, "LN"); } } else { // Если есть активная длинная позиция if (bSell) { // Если есть сигнал Sell, // выдаем ордер на закрыте длинной позиции. LongPos.CloseAtMarket(bar+1, "LX"); } } //-------------------------------------------------------------------------------- // выполнение сигналов для короткой позиции IPosition ShortPos = source.Positions.GetLastActiveForSignal("SN"); if (ShortPos == null) { // Если нет активной короткой позиции if (bShort) { // Если есть сигнал Short // выдаем ордер на открыте новой короткой позиции. source.Positions.SellAtMarket(bar+1, 1, "SN"); } } else { // Если есть активная короткая позиция, if (bCover) { // Если есть сигнал Cover // выдаем ордер на закрыте короткой позиции. ShortPos.CloseAtMarket(bar+1, "SX"); } } #endregion } #endregion //================================================================================ #region прорисовка графиков // Берем основную панель (Pane) IPane mainPane = ctx.First; // для длинных позиций // Отрисовка верхней и нижней границы Bollinger Bands mainPane.AddList("LongHighRange", nLongHighRange, ListStyles.LINE, 0x0000a0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("LongLowRange", nLongLowRange, ListStyles.LINE, 0xf07070, LineStyles.DOT, PaneSides.RIGHT); // Отрисовка скользящих средних mainPane.AddList("LongEntrySMA", nLongNSMA, ListStyles.LINE, 0x00a0a0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("LongExitSMA", nLongXSMA, ListStyles.LINE, 0x00a0a0, LineStyles.DOT, PaneSides.RIGHT); // для коротких позиций // Отрисовка верхней и нижней границы Bollinger Bands mainPane.AddList("ShortHighRange", nShortHighRange, ListStyles.LINE, 0x7070f0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("ShortLowRange", nShortLowRange, ListStyles.LINE, 0xa00000, LineStyles.DOT, PaneSides.RIGHT); // Отрисовка скользящих средних mainPane.AddList("ShortEntrySMA", nShortNSMA, ListStyles.LINE, 0xa000a0, LineStyles.DOT, PaneSides.RIGHT); mainPane.AddList("ShortExitSMA", nShortXSMA, ListStyles.LINE, 0xa000a0, LineStyles.DOT, PaneSides.RIGHT); #endregion //-------------------------------------------------------------------------------- } } }
На графике отображены границы ценовых каналов:
Результаты тестирования стратегии.
Кривая капитала:
Отчет с результатами тестирования:
В прикрепленных файлах можно найти всю необходимую информацию по этой стратегии.