public class Robot : IExternalScript
{
public OptimProperty LevelUpPeriod = new OptimProperty(50, 10, 100, 5); //период для верхней линии ценового канала
public OptimProperty LevelDownPeriod = new OptimProperty(50, 5, 100, 5); //период для нижней линии ценового канала
public OptimProperty SmaLongPeriod = new OptimProperty(35, 100, 5500, 100); //Период МА для Long
public OptimProperty SmaShortPeriod = new OptimProperty(50, 100, 5500, 100); //Период МА для Short
public OptimProperty Lot = new OptimProperty(2, 0, 100, 1); //цель по тестированию
public OptimProperty ExcesProboy = new OptimProperty(1, 0, 100, 1); //Величина пробоя
public OptimProperty Stop = new OptimProperty(50, 0, 100, 1); //величина стопа, умножаем на величину тика
public OptimProperty CompressIntervalLong = new OptimProperty(60, 1, 1440, 1);
public OptimProperty CompressIntervalShort = new OptimProperty(60, 1, 1440, 1);
public void Execute(IContext ctx, ISecurity source)
{
ISecurity sourceCompressLong = source.CompressTo(new Interval(CompressIntervalLong, source.IntervalBase));
if (sourceCompressLong == null || sourceCompressLong.Bars.Count <= 1)
return;
ISecurity sourceCompressShort = source.CompressTo(new Interval(CompressIntervalShort, source.IntervalBase));
if (sourceCompressShort == null || sourceCompressShort.Bars.Count <= 1)
return;
IList<double> levelUp = ctx.GetData("Верхняя граница канала", new[] { LevelUpPeriod.ToString() },
() => Series.Highest(sourceCompressLong.HighPrices, LevelUpPeriod));
IList<double> levelDown = ctx.GetData("Нижняя граница канала", new[] { LevelUpPeriod.ToString() },
() => Series.Lowest(sourceCompressShort.LowPrices, LevelDownPeriod));
IList<double> sma = Series.SMA(sourceCompressLong.ClosePrices, (int)SmaLongPeriod.Value);
IList<double> smaShort = Series.SMA(sourceCompressShort.ClosePrices, (int)SmaShortPeriod.Value);
levelUp = sourceCompressLong.Decompress(levelUp, DecompressMethodWithDef.Method2);
sma = sourceCompressLong.Decompress(sma, DecompressMethodWithDef.Method2);
levelDown = sourceCompressShort.Decompress(levelDown, DecompressMethodWithDef.Method2);
smaShort = sourceCompressShort.Decompress(smaShort, DecompressMethodWithDef.Method2);
IPane mainPane = ctx.First; // Первая панель графика
mainPane.AddList(string.Format("Верхняя граница канала ({0}) ", LevelUpPeriod), levelUp, ListStyles.LINE,
0x00ff00, LineStyles.SOLID, PaneSides.RIGHT);
mainPane.AddList(string.Format("Нижняя граница канала ({0}) ", LevelDownPeriod), levelDown, ListStyles.LINE,
0xff0000, LineStyles.SOLID, PaneSides.RIGHT);
mainPane.AddList("smaLong." + SmaLongPeriod.Value, sma, ListStyles.LINE_WO_ZERO, 0x00ff00, LineStyles.SOLID, PaneSides.RIGHT);
mainPane.AddList("smaShort." + SmaShortPeriod.Value, smaShort, ListStyles.LINE_WO_ZERO, 0x0000ff, LineStyles.SOLID, PaneSides.RIGHT);
int barsCount = source.Bars.Count; // Количество баров (свечек) в исходном источнике
for (int bar = 5; bar < barsCount - 1; bar++)
{
IPositionsList pos = source.Positions;
IPosition longPos = source.Positions.GetLastLongPositionActive(bar);
IPosition shortPos = source.Positions.GetLastShortPositionActive(bar);
if (longPos == null)
{
if (shortPos != null)
shortPos.CloseAtStop(bar + 1, levelUp[bar] + ExcesProboy.Value*source.Tick,
"Переворот. Close Шорт.");
if (sma[bar] < levelUp[bar])
pos.BuyIfGreater(bar + 1, Lot, levelUp[bar] + ExcesProboy.Value*source.Tick,
"Лонг" + " " + levelUp[bar - 1]);
}
if (shortPos == null)
{
if (longPos != null)
longPos.CloseAtStop(bar + 1, levelDown[bar] - ExcesProboy.Value*source.Tick,
"Переворот. Close Лонг.");
if (smaShort[bar] > levelDown[bar])
pos.SellIfLess(bar + 1, Lot, levelDown[bar] - ExcesProboy.Value*source.Tick,
"Шорт" + " " + levelDown[bar - 1]);
}
#region Выход по стопу
if (shortPos != null)
shortPos.CloseAtStop(bar + 1, shortPos.EntryPrice + Stop.Value*source.Tick, "Выход по стоп.");
if (longPos != null)
longPos.CloseAtStop(bar + 1, longPos.EntryPrice - Stop.Value*source.Tick, "Выход по стоп");
#endregion
}
}
}