/*================================================================================
* Стратегия: 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
//--------------------------------------------------------------------------------
}
}
}