ホーム
/
戦略のサンプル
GitHub で見る
Martingale VI ハイブリッド戦略 (C#)
概要
Martingale VI Hybrid 戦略は、元のMetaTraderエキスパートアドバイザーをStockSharpの高レベルAPIに変換したものです。高速/低速移動平均フィルターとMACD確認を組み合わせ、マーティンゲール乗数を使用してポジションをスケールします。価格が最後のエントリーから固定のpip距離だけ逆行した場合にポジションを積み上げ、最新の注文で定義されたレベルにクラスター全体のテイクプロフィットを統一します。追加のグローバル出口には、金額での固定利益、開始資産に対する割合での利益、金額ベースのトレーリングストップが含まれます。
取引ロジック
シグナルフィルター – 高速・低速SMAの前回ロウソク足の値とMACDヒストグラムを使用します。高速SMAが低速SMAより上にあり、MACDメインラインがシグナルラインを下回っている場合にロングサイクルが始まります。高速SMAが低速SMAより下にあり、MACDメインラインがシグナルラインを上回っている場合にショートサイクルが始まります。
初期ポジション – 新しいサイクルが始まりポジションが開いていない場合、戦略はInitial Volumeでマーケット注文を送信します。
マーティンゲール追加 – ポジションが開いている間、戦略は最新のエントリー価格を監視します。価格がポジションに対してPip Step pip逆行した場合、前の注文ボリューム × Volume Multiplierのボリュームで別のマーケット注文を追加します。アクティブな注文数はMax Tradesで制限されます。制限に達しClose Max Ordersが有効な場合、ポジション全体が即座に決済されます。
共有テイクプロフィット – 各新規注文は、方向に応じてエントリー価格 ± Take Profit (pips)に共通テイクプロフィットレベルを更新します。ロウソク足の高値(ロングの場合)または安値(ショートの場合)がこのレベルに触れると、すべての注文がまとめて決済されます。
グローバル出口 – フローティング利益を継続的に評価します:
Use Money TPが有効で利益がMoney TPに達した場合、ポジションが決済されます。
Use Percent TPが有効で利益が初期ポートフォリオ価値のPercent TPパーセントに達した場合、ポジションが決済されます。
Enable Trailingがアクティブな場合、利益がTrailing Activationを超えると金額ベースのトレーリングストップが適用されます。利益がピークからTrailing Drawdown下落した場合にポジションが決済されます。
パラメーター
パラメーター
説明
Candle Type
インジケーター更新に使用するプライマリロウソク足シリーズ。
Fast MA, Slow MA
トレンドフィルターを定義する単純移動平均の期間。
MACD Fast, MACD Slow, MACD Signal
確認に使用するMACDインジケーターのパラメーター。
Initial Volume
マーティンゲールサイクルにおける最初の注文のボリューム。
Volume Multiplier
各追加時に前の注文ボリュームに適用する乗数。
Max Trades
マーティンゲールシーケンスにおける同時注文の最大数。
Take Profit (pips)
各注文のテイクプロフィット距離;最新の注文が共有テイクプロフィット価格を定義します。
Pip Step
現在のサイクルに対する価格の逆行量が次の追加をトリガーする値。
Use Money TP, Money TP
口座通貨での利益目標を有効化し設定します。
Use Percent TP, Percent TP
初期ポートフォリオ価値に対するパーセンテージとして利益目標を有効化し設定します。
Enable Trailing, Trailing Activation, Trailing Drawdown
累積利益を保護する現金ベーストレーリングストップのパラメーター。
Close Max Orders
有効な場合、マーティンゲール注文制限に達した時点でポジション全体が決済されます。
リスク管理
戦略は絶対値とパーセンテージベースの両方の利益目標をサポートし、早期に利益を確保します。
金額ベースのトレーリングストップにより、収益性の高い期間の後にポジションが設定したドローダウンを超えて逆行することを防ぎます。
マーティンゲールステップの総数を制限することでポジションの無限の増加を防ぎます;Close Max Ordersを有効にすると、シーケンスが設定した制限に達した際に緊急出口が強制されます。
実装メモ
戦略はMACDにBindExで結合したインジケーターと移動平均の手動処理を使用したStockSharp高レベルSubscribeCandles APIを使用します。
pip サイズは、5桁および3桁の価格設定のサポートを含む、銘柄の価格ステップから導出されます。
利益計算はSecurity.PriceStep、Security.StepPrice、およびPositionAvgPriceに依存し、必要なメタデータを提供する銘柄との互換性を確保します。
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Martingale VI Hybrid strategy (simplified).
/// Uses SMA crossover for entries.
/// </summary>
public class MartingaleViHybridStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public MartingaleViHybridStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast SMA", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow SMA", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
decimal prevFast = 0, prevSlow = 0;
bool hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevFast = fastValue;
prevSlow = slowValue;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevFast = fastValue;
prevSlow = slowValue;
return;
}
if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
BuyMarket();
else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
SellMarket();
prevFast = fastValue;
prevSlow = slowValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
}
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 martingale_vi_hybrid_strategy(Strategy):
def __init__(self):
super(martingale_vi_hybrid_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candles", "General")
self._fast_period = self.Param("FastPeriod", 8) \
.SetDisplay("Fast Period", "Fast SMA", "Indicators")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow Period", "Slow SMA", "Indicators")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(martingale_vi_hybrid_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(martingale_vi_hybrid_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if not self._has_prev:
self._prev_fast = fv
self._prev_slow = sv
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fv > sv and self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fv < sv and self.Position >= 0:
self.SellMarket()
self._prev_fast = fv
self._prev_slow = sv
def CreateClone(self):
return martingale_vi_hybrid_strategy()