Пример стратегии Пересечение скользящих средних
using System;
using System.Collections.Generic;
using System.Linq;
using TSLab.Script;
using TSLab.Script.Handlers;
using TSLab.Script.Helpers;
using TSLab.Script.Optimization;
namespace MyLib
{
public class CrossMA : IExternalScript
{
// Параметры оптимизации
public OptimProperty PeriodFast = new OptimProperty(10, 10, 50, 5);
public OptimProperty PeriodSlow = new OptimProperty(50, 50, 200, 10);
// Метод обработки, запускается при пересчете скрипта
public virtual void Execute(IContext ctx, ISecurity sec)
{
// Вычисляем быструю и медленную SMA
// Используем GetData для кеширования данных и ускорения оптимизации
var smaSlow = ctx.GetData("SMA", new[] { PeriodSlow.ToString() },
() => Series.SMA(sec.GetClosePrices(ctx), PeriodSlow));
var smaFast = ctx.GetData("SMA", new[] { PeriodFast.ToString() },
() => Series.SMA(sec.GetClosePrices(ctx), PeriodFast));
// Если последняя свеча до конца не сформировалась, ее не нужно использовать в цикле торговли
var barsCount = sec.Bars.Count;
if (!ctx.IsLastBarUsed)
{
barsCount--;
}
var startBar = Math.Max(PeriodSlow, ctx.TradeFromBar);
// Торговля
for (int i = startBar; i < barsCount; i++)
{
// Вычисляем сигналы
var sLong = smaFast[i] > smaSlow[i] && smaFast[i - 1] <= smaSlow[i - 1];
var sShort = smaFast[i] < smaSlow[i] && smaFast[i - 1] >= smaSlow[i - 1];
// Получаем активные позиции
var posLong = sec.Positions.GetLastActiveForSignal("LE", i);
var posShort = sec.Positions.GetLastActiveForSignal("SE", i);
if (posLong == null)
{
// Если нет активной длинной позиции и есть сигнал на покупку, то покупаем по рынку
if (sLong)
{
sec.Positions.BuyAtMarket(i + 1, 1, "LE");
}
}
else
{
// Если есть длинная позиция и есть сигнал на продажу, то закрывам лонг по рынку
if (sShort)
{
posLong.CloseAtMarket(i + 1, "LX");
}
}
if (posShort == null)
{
// Если нет активной короткой позиции и есть сигнал на продажу, то продаем по рынку
if (sShort)
{
sec.Positions.SellAtMarket(i + 1, 1, "SE");
}
}
else
{
// Если есть короткая позиция и есть сигнал на покупку, то закрываем шорт по рынку
if (sLong)
{
posShort.CloseAtMarket(i + 1, "SX");
}
}
}
// Если идет процесс оптимизации, то графики рисовать не нужно, это замедляет работу
if (ctx.IsOptimization)
{
return;
}
// Отрисовка графиков
ctx.First.AddList(string.Format("SMAFast({0})", PeriodFast), smaFast, ListStyles.LINE, ScriptColors.Green,
LineStyles.SOLID, PaneSides.RIGHT);
ctx.First.AddList(string.Format("SMASlow({0})", PeriodSlow), smaSlow, ListStyles.LINE, ScriptColors.Red,
LineStyles.SOLID, PaneSides.RIGHT);
}
}
}
Last updated