Стратегия Expert Ichimoku представляет собой перенос оригинального советника MQL5 "Expert Ichimoku" на инфраструктуру StockSharp. Модель относится к трендовым системам: она анализирует индикатор Ichimoku Kinko Hyo, оценивает характер предыдущей свечи и при необходимости удваивает объём после убыточной сделки (опционально, в духе мартингейла).
Расчёты выполняются только на закрытых свечах выбранного таймфрейма. Стратегия работает с одной чистой позицией: при смене направления текущая позиция закрывается рыночной заявкой и лишь затем открывается противоположная. Вся информация берётся из подписки на свечи, дополнительные источники данных не требуются.
Логика работы
Настройка индикатора
Tenkan-sen (конверсионная линия) — быстрый компонент для отслеживания пересечений.
Senkou Span A / B — границы облака, оцениваемые по предыдущей свече для фильтрации тренда.
Chikou Span (запаздывающая линия) — подтверждает импульс прорывом относительно исторических цен.
Длины линий по умолчанию совпадают с настройками советника: 9 / 26 / 52 и могут изменяться пользователем.
Правила входа
Покупка выполняется, если соблюдены все условия:
Импульс: либо Tenkan пересекает Kijun снизу вверх на последней закрытой свече, либо Chikou пробивает выше цены 10–11 свечей назад.
Позиция цены относительно облака: текущая цена закрытия находится выше обеих линий Senkou на предыдущей свече (цена выше облака).
Характер предыдущей свечи: свеча t-1 закрылась ростом (Closet-1 > Opent-1).
Позиционный фильтр: нет активной длинной позиции. Если была короткая, она закрывается перед открытием новой длинной.
Продажа симметрична:
Tenkan пересекает Kijun сверху вниз или Chikou уходит ниже исторической цены (используются открытия свечей для проверки).
Текущая цена закрытия ниже обеих Senkou (цена ниже облака).
Предыдущая свеча медвежья (Closet-1 < Opent-1).
Перед открытием короткой позиции закрываются все длинные объёмы.
Управление объёмом
Базовый объём равен свойству Volume стратегии.
Если включена опция Use Martingale, следующий вход после убыточного выхода выполняется удвоенным объёмом. Прибыль или отсутствие потерь сбрасывают множитель.
Итоговый объём ограничивается значением Volume × Max Position Multiplier, что соответствует ограничению по количеству одновременно открытых позиций в оригинальном советнике.
Управление риском
Фиксированный стоп-лосс и тейк-профит задаются абсолютным отступом от цены входа. Значение 0 отключает соответствующий уровень.
Трейлинг-стоп активируется, если заданы ненулевые Trailing Stop Offset и Trailing Step. Стоп подтягивается только после того, как цена прошла расстояние offset + step в сторону прибыли, точно так же как в версии MQL5.
После закрытия позиции рассчитывается фактический результат, чтобы определить, нужно ли удваивать объём на следующем сигнале.
Параметры
Параметр
Описание
Значение по умолчанию
Tenkan Period
Длина линии Tenkan-sen.
9
Kijun Period
Длина линии Kijun-sen.
26
Senkou Span B Period
Длина Senkou Span B.
52
Stop Loss Offset
Абсолютное расстояние до стоп-лосса, 0 — отключён.
0
Take Profit Offset
Абсолютное расстояние до тейк-профита, 0 — отключён.
0
Trailing Stop Offset
Базовое расстояние трейлинг-стопа.
0
Trailing Step
Минимальное дополнительное движение для подтягивания стопа.
0
Max Position Multiplier
Максимальный множитель объёма относительно Volume.
5
Use Martingale
Включить удвоение объёма после убыточной сделки.
true
Candle Type
Таймфрейм используемых свечей.
1 час
Практические рекомендации
Для полноценной работы требуется не менее 12 закрытых свечей — проверки по Chikou используют цены до 11 баров назад.
Поскольку StockSharp оперирует чистой позицией, параметр Max Position Multiplier ограничивает максимальный объём ордера вместо ведения нескольких отдельных сделок.
Если трейлинг-стоп выключен (один из параметров равен 0), уровни не корректируются. При ненулевых значениях стоп смещается ступенчато при превышении порога offset + step.
Все события входа/выхода выводятся в журнал, что облегчает анализ на исторических данных.
Порядок использования
Настройте инструмент и таймфрейм свечей в контейнере стратегии или дизайнере.
Укажите базовый Volume и переведите точки (pip) из оригинальной версии в абсолютные ценовые отступы для выбранного рынка.
Запустите стратегию. После накопления достаточной истории индикатор будет анализировать каждый завершённый бар, автоматически управляя позициями, стопами и опциональным удвоением объёма.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Ichimoku strategy using Tenkan/Kijun crossover (midline of short/long channels).
/// </summary>
public class ExpertIchimokuStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _tenkanPeriod;
private readonly StrategyParam<int> _kijunPeriod;
private decimal? _prevTenkan;
private decimal? _prevKijun;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int TenkanPeriod
{
get => _tenkanPeriod.Value;
set => _tenkanPeriod.Value = value;
}
public int KijunPeriod
{
get => _kijunPeriod.Value;
set => _kijunPeriod.Value = value;
}
public ExpertIchimokuStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_tenkanPeriod = Param(nameof(TenkanPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Tenkan Period", "Short channel period", "Indicators");
_kijunPeriod = Param(nameof(KijunPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("Kijun Period", "Long channel period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevTenkan = null;
_prevKijun = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevTenkan = null;
_prevKijun = null;
// Tenkan: midline of short highest/lowest
var tenkanHigh = new Highest { Length = TenkanPeriod };
var tenkanLow = new Lowest { Length = TenkanPeriod };
// Kijun: midline of long highest/lowest
var kijunHigh = new Highest { Length = KijunPeriod };
var kijunLow = new Lowest { Length = KijunPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(tenkanHigh, tenkanLow, kijunHigh, kijunLow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal tHigh, decimal tLow, decimal kHigh, decimal kLow)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var tenkan = (tHigh + tLow) / 2;
var kijun = (kHigh + kLow) / 2;
if (_prevTenkan == null || _prevKijun == null)
{
_prevTenkan = tenkan;
_prevKijun = kijun;
return;
}
// Tenkan crosses above Kijun → buy
if (_prevTenkan.Value <= _prevKijun.Value && tenkan > kijun)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// Tenkan crosses below Kijun → sell
else if (_prevTenkan.Value >= _prevKijun.Value && tenkan < kijun)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
_prevTenkan = tenkan;
_prevKijun = kijun;
}
}