Это порт экспертного советника MetaTrader «Mission Impossible Power Two Open» на платформу StockSharp. Стратегия отслеживает направление последней завершённой свечи и открывает в том же направлении корзину сделок. Если цена движется против открытого направления, стратегия наращивает позицию по фиксированной сетке шагов. Объём каждой новой сделки увеличивается вместе с плавающим убытком корзины в соответствии с коэффициентом Power. После каждого исполнения заново рассчитываются общий тейк-профит и стоп-лосс, чтобы вся корзина закрывалась одновременно.
Логика работы
Определение сигнала. На закрытии каждой свечи стратегия сравнивает цену закрытия предыдущей свечи с ценой её открытия.
Если закрытие выше открытия — активируется сигнал на покупку.
Если закрытие ниже открытия — активируется сигнал на продажу.
Если свеча «внутренняя» (закрытие равно открытию), новых корзин не создаётся.
Первый вход. При отсутствии активной сетки в направлении сигнала отправляется рыночная заявка объёмом BaseVolume.
Сетка усреднения. При наличии открытых сделок стратегия отслеживает расстояние между последней ценой входа и текущим закрытием.
Для покупок новая сделка появляется, когда цена упала минимум на GridStepPips * PriceStep ниже последнего входа.
Для продаж добавление происходит после роста цены на ту же величину выше последнего входа.
Количество усреднений ограничено параметром MaxTrades на каждое направление.
Динамический объём. Перед каждым новым ордером вычисляется плавающий убыток корзины, умножается на Power * 0.0001 и добавляется к BaseVolume. Получившийся объём округляется к шагу объёма площадки, ограничивается биржевыми пределами и параметром MaxVolume.
Управление выходом. После каждого исполнения заново рассчитываются общие целевые уровни:
Для одной сделки тейк-профит находится на расстоянии TakeProfitFirstPips, стоп-лосс — на StopLossPips от цены входа.
Для двух и более сделок уровни привязываются к объёмно-взвешенной средней цене корзины с использованием TakeProfitNextPips и StopLossPips.
При достижении любого уровня вся корзина закрывается рыночной сделкой противоположного направления.
Независимые направления. Лонговая и шортовая сетки ведутся отдельно, поэтому стратегия может одновременно удерживать хеджирующие корзины, если сигналы быстро чередуются.
Параметры
Название
Тип
Значение по умолчанию
Описание
BaseVolume
decimal
0.01
Базовый объём первой сделки в корзине.
MaxVolume
decimal
2
Максимальный объём одной рыночной сделки после округления.
Power
decimal
13
Множитель плавающего убытка при расчёте объёма усреднения.
StopLossPips
int
400
Дистанция общего стоп-лосса в шагах цены.
TakeProfitFirstPips
int
15
Дистанция тейк-профита для первой сделки.
TakeProfitNextPips
int
7
Дистанция тейк-профита для корзины из двух и более сделок.
GridStepPips
int
21
Минимальное неблагоприятное движение (в шагах цены) перед добавлением новой сделки.
MaxTrades
int
16
Максимальное число сделок сетки в одном направлении.
CandleType
DataType
TimeSpan.FromMinutes(5).TimeFrame()
Тип свечей для генерации сигналов и контроля сетки.
Дополнительные замечания
Объёмы всегда приводятся к VolumeStep инструмента и ограничиваются доступными MinVolume и MaxVolume, если площадка возвращает такие значения.
Лонговая и шортовая логики полностью независимы, что соответствует поведению MQL4-версии с отдельными магическими номерами для каждого направления.
Уровни стоп-лосса и тейк-профита пересчитываются после каждого нового входа и округляются до ближайшего шага цены, воспроизводя постоянные модификации ордеров в исходном советнике.
Стратегия не использует индикаторы: все решения принимаются на основе свечей и текущего состояния портфеля, как и в оригинальном роботе.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Mission Impossible Power Two Open strategy: Candle direction with EMA trend filter.
/// Buys on bullish candle when above EMA, sells on bearish candle when below EMA.
/// </summary>
public class MissionImpossiblePowerTwoOpenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private bool _wasBullishSignal;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public MissionImpossiblePowerTwoOpenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullishSignal = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_wasBullishSignal = false;
_hasPrevSignal = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var open = candle.OpenPrice;
var bullish = close > open;
var bearish = close < open;
var bullishSignal = bullish && close > emaValue;
var bearishSignal = bearish && close < emaValue;
var crossedUp = bullishSignal && (!_hasPrevSignal || !_wasBullishSignal);
var crossedDown = bearishSignal && (!_hasPrevSignal || _wasBullishSignal);
if (crossedUp && Position <= 0)
BuyMarket();
else if (crossedDown && Position >= 0)
SellMarket();
if (bullishSignal || bearishSignal)
{
_wasBullishSignal = bullishSignal;
_hasPrevSignal = true;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class mission_impossible_power_two_open_strategy(Strategy):
def __init__(self):
super(mission_impossible_power_two_open_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._ema_period = self.Param("EmaPeriod", 50)
self._was_bullish_signal = False
self._has_prev_signal = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
def OnReseted(self):
super(mission_impossible_power_two_open_strategy, self).OnReseted()
self._was_bullish_signal = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(mission_impossible_power_two_open_strategy, self).OnStarted2(time)
self._was_bullish_signal = False
self._has_prev_signal = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
ema_val = float(ema_value)
bullish = close > open_price
bearish = close < open_price
bullish_signal = bullish and close > ema_val
bearish_signal = bearish and close < ema_val
crossed_up = bullish_signal and (not self._has_prev_signal or not self._was_bullish_signal)
crossed_down = bearish_signal and (not self._has_prev_signal or self._was_bullish_signal)
if crossed_up and self.Position <= 0:
self.BuyMarket()
elif crossed_down and self.Position >= 0:
self.SellMarket()
if bullish_signal or bearish_signal:
self._was_bullish_signal = bullish_signal
self._has_prev_signal = True
def CreateClone(self):
return mission_impossible_power_two_open_strategy()