Alexav SpeedUp M1 — прямой порт экспертного советника MetaTrader 4 «Alexav_SpeedUp_M1». Стратегия анализирует тела закрывшихся внутридневных свечей и сразу же открывает рыночную позицию, если размер тела превышает заданный порог. После входа включается классическое сопровождение позиции: устанавливаются стоп-лосс, тейк-профит и плавающий стоп в стиле MetaTrader.
Для конверсии использован высокоуровневый API StockSharp. Свечи поступают через SubscribeCandles, данные best bid/ask для трейлинга — через level1 подписку, защитные приказы выставляются стандартными методами BuyStop, SellStop, BuyLimit и SellLimit. Дополнительные индикаторы или сложные вычисления не требуются.
Генерация сигналов
Обрабатывается каждая завершённая свеча выбранного таймфрейма.
Если свеча закрылась выше открытия и разница превышает параметр Body Threshold, стратегия открывает (или переворачивает в) длинную позицию по рынку.
Если свеча закрылась ниже открытия на ту же величину, открывается (или переворачивается в) короткая позиция.
Наличие встречной позиции учитывается автоматически: объём рыночного ордера увеличивается так, чтобы закрыть старый объём и при необходимости открыть новую позицию в нужном направлении.
Управление приказами
Начальный стоп-лосс: при увеличении позиции немедленно регистрируется защитный стоп на заданное число пунктов ниже (для лонга) или выше (для шорта) цены входа.
Тейк-профит: на соответствующем удалении выставляется лимитный приказ на фиксацию прибыли.
Трейлинг-стоп: по данным level1 отслеживается текущая прибыль. Как только она превышает расстояние трейлинга, стоп-ордер переносится ближе к цене, сохраняя заданный зазор и не откатываясь назад.
Все защитные приказы отменяются, когда позиция становится нулевой.
Логика сохранена максимально близко к оригинальному советнику: никаких дополнительных фильтров или ограничений сверх MQL-версии не добавлено.
Параметры
Название
Описание
Lot Size
Базовый торговый объём в лотах для рыночных ордеров. При развороте добавляется объём, необходимый для закрытия встречной позиции.
Take Profit (points)
Расстояние от цены входа до тейк-профита в пунктах MetaTrader (преобразуется через шаг цены инструмента).
Initial Stop (points)
Расстояние от цены входа до первичного стоп-лосса в пунктах.
Trailing Stop (points)
Размер шага плавающего стопа. Значение 0 отключает трейлинг.
Body Threshold
Минимальная разница между ценами открытия и закрытия свечи, при превышении которой совершается сделка.
Candle Type
Тип свечей (таймфрейм), используемый для анализа. По умолчанию соответствует минутному графику оригинала.
Рекомендации по применению
Убедитесь, что инструмент предоставляет корректный PriceStep. При его отсутствии стратегия трактует «пункты» как абсолютное ценовое смещение.
Для работы трейлинга необходимы данные level1 (лучшие bid/ask). Если доступны только свечи, перенос стопа выполняться не будет.
Стратегия ориентирована на внутридневную торговлю и, как и исходный советник, совершает не более одной сделки по каждой свече.
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>
/// Alexav SpeedUp M1 Body strategy.
/// Trades based on large candle body breakouts.
/// Buys after a large bullish candle, sells after a large bearish candle.
/// Uses ATR to define "large" body threshold.
/// </summary>
public class AlexavSpeedUpM1BodyBreakStrategy : Strategy
{
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _bodyMultiplier;
private readonly StrategyParam<DataType> _candleType;
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public decimal BodyMultiplier { get => _bodyMultiplier.Value; set => _bodyMultiplier.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AlexavSpeedUpM1BodyBreakStrategy()
{
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetDisplay("ATR Period", "ATR period for body threshold", "Indicators");
_bodyMultiplier = Param(nameof(BodyMultiplier), 1.0m)
.SetDisplay("Body Multiplier", "Body must exceed ATR * multiplier", "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();
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var atr = new AverageTrueRange { Length = AtrPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(atr, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal atrValue)
{
if (candle.State != CandleStates.Finished)
return;
var body = candle.ClosePrice - candle.OpenPrice;
var absBody = Math.Abs(body);
var threshold = atrValue * BodyMultiplier;
if (absBody < threshold)
return;
// Large bullish candle - buy
if (body > 0 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Large bearish candle - sell
else if (body < 0 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
}
}
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 AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class alexav_speed_up_m1_body_break_strategy(Strategy):
"""Alexav SpeedUp M1 Body strategy.
Trades based on large candle body breakouts.
Buys after a large bullish candle, sells after a large bearish candle.
Uses ATR to define large body threshold."""
def __init__(self):
super(alexav_speed_up_m1_body_break_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR period for body threshold", "Indicators")
self._body_multiplier = self.Param("BodyMultiplier", 1.0) \
.SetDisplay("Body Multiplier", "Body must exceed ATR * multiplier", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def AtrPeriod(self):
return self._atr_period.Value
@property
def BodyMultiplier(self):
return self._body_multiplier.Value
def OnReseted(self):
super(alexav_speed_up_m1_body_break_strategy, self).OnReseted()
def OnStarted2(self, time):
super(alexav_speed_up_m1_body_break_strategy, self).OnStarted2(time)
atr = AverageTrueRange()
atr.Length = self.AtrPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(atr, self._process_candle).Start()
def _process_candle(self, candle, atr_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
body = close - open_price
abs_body = abs(body)
atr_val = float(atr_value)
threshold = atr_val * float(self.BodyMultiplier)
if abs_body < threshold:
return
# Large bullish candle - buy
if body > 0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Large bearish candle - sell
elif body < 0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return alexav_speed_up_m1_body_break_strategy()