Главная
/
Примеры стратегий
Открыть на GitHub
Стратегия Noah 10 Pips 2006
Краткое описание
Полностью повторяет алгоритм советника Noah10pips2006 для MetaTrader 4 в инфраструктуре StockSharp.
Использует диапазон предыдущей сессии для построения каналов и выставления стоп-заявок около средней цены.
Поддерживает фиксацию прибыли, последующее трейлинг-сопровождение и однократный реверс после закрытия первой позиции.
Алгоритм работы
Расчёт диапазона
В начале нового торгового дня (с учётом параметра TimeZoneOffset) стратегия запоминает максимум и минимум предыдущей сессии и рассчитывает:
Среднюю точку диапазона.
Буферные уровни на расстоянии 20 пунктов (pips) выше и ниже.
Зону входа: если диапазон ≤ 160 пунктов, используется фиксированные ±40 пунктов, иначе 25% от ширины диапазона.
Первая заявка
После наступления торгового окна проверяется последний закрытый бар:
Закрытие между средней и верхним буфером → размещается стоп-заявка на продажу по средней.
Закрытие между нижним буфером и средней → размещается стоп-заявка на покупку по средней.
Заявки выставляются только при ширине зоны выше MinimumRangePips.
Дополнительная заявка
Если активна только одна стоп-заявка, добавляется противоположная по соответствующему буферному уровню, чтобы подготовиться к пробою в любую сторону.
Сопровождение позиции
После срабатывания ордера выставляются защитные стоп-лосс и тейк-профит.
При достижении прибыли TrailSecureProfitPips стоп переносится на уровень, обеспечивающий SecureProfitPips.
При включённом TrailingStopPips стоп далее сопровождает цену с указанным шагом.
Завершение дня
Вне торгового окна и по пятничному дедлайну (FridayEndHour) все заявки и позиции закрываются.
Реверс
После закрытия первой позиции при отсутствии фиксации прибыли стратегия открывает рыночную позицию в противоположную сторону — так же, как оригинальный советник.
Основные параметры
CandleType — тип свечей для вычислений, по умолчанию 1 час.
TimeZoneOffset — смещение времени данных в часах.
StartHour/StartMinute, EndHour/EndMinute — границы торгового окна.
FridayEndHour, TradeFriday — настройка торговли по пятницам и принудительного закрытия.
StopLossPips, TakeProfitPips — дистанции защитных ордеров.
SecureProfitPips, TrailSecureProfitPips, TrailingStopPips — логика фиксации прибыли и трейлинг-стопа.
MinimumRangePips — минимальная ширина диапазона для постановки заявок.
MinVolume, MaxVolume, MaximumRiskPercent, FixedVolume — управление объёмом, эквивалент функции LotsRisk в MT4.
Практические рекомендации
Для риск-менеджмента инструмент должен иметь корректные PriceStep и StepPrice; иначе включите FixedVolume и задайте объём вручную.
Изменение защитных уровней происходит на закрытии свечи; при необходимости используйте более мелкий таймфрейм.
Константы 20/40 пунктов рассчитаны под четырёхзнаковый Forex. Для других инструментов адаптируйте параметры.
Графические объекты из MT4 не переносятся автоматически; их можно добавить через возможности графика StockSharp.
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>
/// Noah 10 Pips 2006 - session breakout strategy.
/// Tracks the previous session's high/low range.
/// Buys on breakout above the midpoint, sells on breakout below.
/// Uses Highest/Lowest indicators as channel reference.
/// </summary>
public class Noah10Pips2006Strategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _prevMid;
private decimal _prevClose;
private bool _hasPrev;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Noah10Pips2006Strategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 24)
.SetDisplay("Channel Period", "Lookback for high/low channel", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0m;
_prevLow = 0m;
_prevMid = 0m;
_prevClose = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var mid = (high + low) / 2m;
if (!_hasPrev)
{
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
_hasPrev = true;
return;
}
// Breakout above channel high - buy
if (_prevClose <= _prevHigh && close > high && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakout below channel low - sell
else if (_prevClose >= _prevLow && close < low && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Cross above midpoint from below - buy signal
else if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Cross below midpoint from above - sell signal
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class noah10_pips2006_strategy(Strategy):
"""Session breakout strategy. Tracks channel high/low/midpoint.
Buys on breakout above channel high or cross above midpoint.
Sells on breakout below channel low or cross below midpoint."""
def __init__(self):
super(noah10_pips2006_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 24) \
.SetDisplay("Channel Period", "Lookback for high/low channel", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._prev_mid = 0.0
self._prev_close = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def ChannelPeriod(self):
return self._channel_period.Value
def OnReseted(self):
super(noah10_pips2006_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._prev_mid = 0.0
self._prev_close = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(noah10_pips2006_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.ChannelPeriod
lowest = Lowest()
lowest.Length = self.ChannelPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._process_candle).Start()
def _process_candle(self, candle, high, low):
if candle.State != CandleStates.Finished:
return
high_val = float(high)
low_val = float(low)
close = float(candle.ClosePrice)
mid = (high_val + low_val) / 2.0
if not self._has_prev:
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
self._has_prev = True
return
# Breakout above channel high - buy
if self._prev_close <= self._prev_high and close > high_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakout below channel low - sell
elif self._prev_close >= self._prev_low and close < low_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Cross above midpoint from below - buy
elif self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Cross below midpoint from above - sell
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
def CreateClone(self):
return noah10_pips2006_strategy()