SMA マルチヘッジ2戦略
この戦略は基準銘柄を取引しながら、相関する銘柄でヘッジを行います。トレンド方向は単純移動平均(SMA)によって決定されます。基準銘柄とヘッジ銘柄の相関が閾値を超えると、両銘柄を取引して市場中立なペアを形成します。
仕組み
- 設定可能な長さのSMAを使用して基準銘柄のトレンドを計算する。
- 価格とそのSMAとの差を使用して基準銘柄とヘッジ銘柄の相関を測定する。
- 相関が期待レベルに達した場合、両銘柄でポジションを開く。ヘッジ方向は設定に応じて基準銘柄に追従するか反対向きになる。
- 合計利益が目標値に達すると自動的にポジションが閉じられる。
パラメーター
SmaPeriod— トレンド検出に使用するSMAの期間。デフォルトは20。CorrelationPeriod— 相関評価に使用するサンプル数。デフォルトは20。ExpectedCorrelation— ヘッジを有効化するために必要な最小絶対相関。デフォルトは0.8。ProfitTarget— 通貨単位での全体の利益目標。デフォルトは30。CandleType— ローソク足サブスクリプションのデータタイプ。デフォルトは1分の時間軸。FollowBase— 真の場合、相関が正のときヘッジは同じ方向で取引する。
インジケーター
- SMA
- 相関(カスタム計算)
注意事項
これは元のMQL戦略の簡略版のポートです。ライブ取引前にリスクおよび資金管理を調整してください。
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>
/// SMA trend direction strategy.
/// </summary>
public class SmaMultiHedge2Strategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevEma1;
private decimal _prevEma2;
private int _count;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SmaMultiHedge2Strategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend period", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "Parameters");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevEma1 = 0;
_prevEma2 = 0;
_count = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType)
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished) return;
_count++;
if (_count < 3)
{
_prevEma2 = _prevEma1;
_prevEma1 = emaVal;
return;
}
var trend = 0;
if (_prevEma2 < _prevEma1 && _prevEma1 < emaVal)
trend = 1;
else if (_prevEma2 > _prevEma1 && _prevEma1 > emaVal)
trend = -1;
_prevEma2 = _prevEma1;
_prevEma1 = emaVal;
if (trend == 1 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (trend == -1 && 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
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class sma_multi_hedge2_strategy(Strategy):
def __init__(self):
super(sma_multi_hedge2_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA trend period", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "Parameters")
self._prev_ema1 = 0.0
self._prev_ema2 = 0.0
self._count = 0
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(sma_multi_hedge2_strategy, self).OnReseted()
self._prev_ema1 = 0.0
self._prev_ema2 = 0.0
self._count = 0
def OnStarted2(self, time):
super(sma_multi_hedge2_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
self.SubscribeCandles(self.candle_type) \
.Bind(ema, self.process_candle) \
.Start()
def process_candle(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
ema_val = float(ema_val)
self._count += 1
if self._count < 3:
self._prev_ema2 = self._prev_ema1
self._prev_ema1 = ema_val
return
trend = 0
if self._prev_ema2 < self._prev_ema1 and self._prev_ema1 < ema_val:
trend = 1
elif self._prev_ema2 > self._prev_ema1 and self._prev_ema1 > ema_val:
trend = -1
self._prev_ema2 = self._prev_ema1
self._prev_ema1 = ema_val
if trend == 1 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif trend == -1 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return sma_multi_hedge2_strategy()