GitHub で見る
ヘラクレス戦略
Hercules 戦略は、MetaTrader エキスパート Hercules v1.3 (Majors) の StockSharp 移植です。高速/低速移動平均クロスオーバーとマルチタイムフレーム確認フィルターを組み合わせ、シグナルごとに 2 つの独立した利益目標を実行します。
取引ロジック
- シグナルアーム – ローソク足のクローズ時に高速の EMA (デフォルトは 1 期間) を計算し、ローソク足のオープン時に低速の SMA (72 期間) を計算します。最後または最後から 2 番目のバーで発生したクロスオーバーを検出します。クロスオーバー価格は両方の移動平均で平均され、トリガーレベルは
TriggerPips 上 (ロングの場合) または下 (ショートの場合) に配置されます。
- 実行ウィンドウ – クロスオーバーが検出されると、セットアップは 2 つのバー全体にわたって有効のままになります。現在の終値がこのウィンドウ内のトリガー価格を超えた場合にのみ、注文の発行が許可されます。
- フィルター –
- H1 RSI (デフォルトの長さ 10、通常の価格入力) はロングの場合は
RsiUpper より大きく、ショートの場合は RsiLower より小さい必要があります。
- 現在の終値は、取引時間枠で
LookbackMinutes 個のローソク足で収集された最近の高値/安値を破る必要があります。
- 日次エンベロープ (SMA 24、±
DailyEnvelopeDeviation%) では、価格が取引方向のバンドの外側で終了する必要があります。
- H4 エンベロープ (SMA 96 ±
H4EnvelopeDeviation%) は、2 番目のより高いタイムフレームの確認を追加します。
- リスク管理 – ストップロスは、ローソク足 4 本前のバーの高値/安値に設定されます。出来高は固定(
OrderVolume)することも、現在のポートフォリオ値の RiskPercent から再計算することもできます。
- 取引管理 – 各シグナルにより、同じ量の 2 つの成行注文がオープンされます。 1 つ目は
TakeProfitFirstPips で清算され、2 つ目は TakeProfitSecondPips で清算されます。末尾のストップを TrailingStopPips にすると、両方の注文が保護されます。ストップまたは両方のターゲットが完了すると、ストラテジーは BlackoutHours のブラックアウト期間に入り、その間は新しい取引は行われません。
パラメーター
| パラメータ |
説明 |
OrderVolume |
資金管理調整前の各成行注文の出来高。 |
UseMoneyManagement |
有効にすると、ポートフォリオの RiskPercent と現在の停止距離から体積が再計算されます。 |
RiskPercent |
設定ごとのリスクに対するポートフォリオの価値の割合。 |
TriggerPips |
エントリーを許可するために超える必要があるクロスオーバー価格からの距離。 |
TrailingStopPips |
組み合わせたポジションに適用されるピップ単位のトレーリングストップ距離。 |
TakeProfitFirstPips |
最初の部分的なテイクプロフィットのピップ距離。 |
TakeProfitSecondPips |
2 番目の部分的なテイクプロフィットのピップ距離。 |
FastPeriod |
高速 EMA トリガー ラインの長さ。 |
SlowPeriod |
遅い SMA ベースラインの長さ。 |
RsiPeriod |
RSI 確認フィルターの長さ。 |
RsiUpper / RsiLower |
RSI のしきい値によりロングおよびショートの取引が可能になります。 |
LookbackMinutes |
最近の高/低ブレイクアウト フィルターを計算するために使用されるウィンドウ (分単位)。 |
BlackoutHours |
実行後に新しいセットアップを受け入れるまでに数時間の一時停止が必要です。 |
DailyEnvelopePeriod / DailyEnvelopeDeviation |
日次エンベロープフィルターのパラメーター。 |
H4EnvelopePeriod / H4EnvelopeDeviation |
H4 エンベロープ フィルターのパラメーター。 |
CandleType |
取引執行に使用される主な時間枠。 |
RsiTimeFrame |
RSI インジケーターをフィードするタイムフレーム。 |
DailyTimeFrame |
毎日のエンベロープ計算をフィードする時間枠。 |
H4TimeFrame |
H4 エンベロープ計算をフィードするタイムフレーム。 |
ファイル
CS/HerculesStrategy.cs – Hercules 戦略の C# 実装。
README.md – この文書。
README_ru.md – ロシア語の説明。
README_zh.md – 中国語の説明。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class HerculesStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi; private bool _hasPrev;
private int _cooldown;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public HerculesStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14).SetDisplay("RSI Period", "RSI lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
if (!_hasPrev) { _prevRsi = rsi; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevRsi = rsi;
return;
}
if (_prevRsi <= 30 && rsi > 30 && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 2;
}
else if (_prevRsi >= 70 && rsi < 70 && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 2;
}
_prevRsi = rsi;
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class hercules_strategy(Strategy):
def __init__(self):
super(hercules_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14).SetDisplay("RSI Period", "RSI lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_rsi = 0.0; self._has_prev = False; self._cooldown = 0
@property
def rsi_period(self): return self._rsi_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(hercules_strategy, self).OnReseted()
self._prev_rsi = 0.0; self._has_prev = False; self._cooldown = 0
def OnStarted2(self, time):
super(hercules_strategy, self).OnStarted2(time)
self._has_prev = False; self._cooldown = 0
rsi = RelativeStrengthIndex(); rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, self.process_candle).Start()
def process_candle(self, candle, rsi):
if candle.State != CandleStates.Finished: return
if not self.IsFormedAndOnlineAndAllowTrading(): return
rsi_val = float(rsi)
if not self._has_prev:
self._prev_rsi = rsi_val; self._has_prev = True; return
if self._cooldown > 0:
self._cooldown -= 1; self._prev_rsi = rsi_val; return
if self._prev_rsi <= 30 and rsi_val > 30 and self.Position <= 0:
volume = self.Volume + abs(self.Position)
self.BuyMarket(volume); self._cooldown = 2
elif self._prev_rsi >= 70 and rsi_val < 70 and self.Position >= 0:
volume = self.Volume + abs(self.Position)
self.SellMarket(volume); self._cooldown = 2
self._prev_rsi = rsi_val
def CreateClone(self): return hercules_strategy()