GitHub で見る

Bulls & Bears Power 平均戦略

概要

  • MQL/22016にあるMetaTrader 5エキスパートMySystem.mq5のポート。
  • ローソク足の高値/安値とEMAから計算されたElder Bulls PowerとBears Powerの値を平均することでモメンタムリバーサルを検出します。
  • 平均がまだゼロ以下にありながら増加する場合(弱気圧力が薄れている)にロング、平均がまだゼロ以上にありながら減少する場合(強気圧力が薄れている)にショートに参入します。
  • 一度に1つのオープンポジションのために設計され、ストップロスとテイクプロフィットはオプションでピップで表現されます。

インジケーターのロジック

コンポーネント 説明
Exponential Moving Average(EMA) ローソク足のクローズ価格に適用されます。MaPeriodパラメーターが平滑化ウィンドウを制御します(デフォルト5)。
Bulls Power(派生) High - EMAとして計算されます。EMAに対する強気の強さを測定します。
Bears Power(派生) Low - EMAとして計算されます。EMAに対する弱気の強さを測定します。
平均パワー (Bulls Power + Bears Power) / 2。この合成オシレーターはモメンタムの変化を検出するために前の値と比較されます。

戦略は最後の2つの完成したローソク足を評価します。新しいトレードはバー内のノイズを避けるためにローソク足が完全に完成した場合にのみ評価されます。

エントリールール

  1. EMAが完全に形成されるまで待ちます(つまり、少なくともMaPeriod個のローソク足を処理した)。
  2. その高値/安値とEMA値を使用して、ちょうどクローズしたローソク足のBulls PowerとBears Powerを計算します。
  3. 両方の力を平均して現在のオシレーター読み取り値を取得します。
  4. 前の平均と比較します:
    • ロングセットアップ: 前の平均<現在の平均 かつ現在の平均< 0。既存のポジションがなければロングに参入します。
    • ショートセットアップ: 前の平均>現在の平均 かつ現在の平均> 0。フラットならショートに参入します。
  5. トレードに入ったら、オプションの保護注文または手動管理に頼ります。アルゴリズムはストップロス/テイクプロフィット以外のエグジットシグナルを生成しません。

リスク管理

  • StopLossPips: ピップ単位のオプションの絶対ストップ距離(0でストップを無効化)。インストゥルメントのPriceStepを使用して変換されます。
  • TakeProfitPips: ピップ単位のオプションの絶対利益目標(0で目標を無効化)。
  • 保護注文はマーケット実行でStartProtectionを通じてポジションが開かれるとすぐに登録されます。

パラメーター

名前 デフォルト 説明
OrderVolume 0.1 マーケットエントリーの注文サイズ。
StopLossPips 15 ピップ単位のストップロス距離。0に設定すると無効化。
TakeProfitPips 95 ピップ単位のテイクプロフィット距離。0に設定すると無効化。
MaPeriod 5 Bulls/Bears Power計算に使用されるEMAの長さ。
CandleType 1時間の時間軸 すべての計算に使用されるローソク足シリーズ(データフィードに合わせて変更)。

使用上の注意

  1. 戦略をインストゥルメントに付属し、CandleTypeが意図した時間軸と一致することを確認します。
  2. ブローカーの要件に合わせてOrderVolumeStopLossPipsTakeProfitPipsを調整します。
  3. 戦略を実行します。ローソク足を自動的に購読し、EMAを更新し、適格なシグナルでマーケット注文を発行します。
  4. 一度に1つのポジションのみ存在できます。トレードがアクティブな場合、保護注文がポジションをクローズするか手動でクローズされるまで新しいシグナルは無視されます。
  5. 元のMQLバージョンがInpBarCurrent = 1を使用していたため、このポートは常に完全にクローズしたローソク足で動作し、連続する値を比較します。バー内の再計算は行われません。

元のMQLエキスパートとの違い

  • 手動バッファアクセスではなくローソク足購読とインジケーターバインディングを持つStockSharpハイレベルStrategy APIを使用します。
  • 手動の桁調整ではなくPriceStepからピップを自動的に導出します。
  • 元のコメントアウトされた注文管理をスキップし、組み込みのポジション保護に依存します。
  • ポジションが存在する間シグナルを無視することでソースの単一ポジション制約を維持します。

テストの推奨事項

  • Bulls/Bears計算の精度を確保するために高値/安値の価格を含む履歴データで意図したシンボル/時間軸でバックテストします。
  • ライブ実行前にブローカーのティックサイズとボリュームステップで保護注文の動作を検証します。
  • インストゥルメントのボラティリティに感度を適応させるために異なるMaPeriod値を実験します。
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>
/// Bulls Bears Power Average strategy. Uses EMA with bulls/bears power crossover.
/// </summary>
public class BullsBearsPowerAverageStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;
	private decimal? _prevPower;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }

	public BullsBearsPowerAverageStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_emaPeriod = Param(nameof(EmaPeriod), 13).SetGreaterThanZero().SetDisplay("EMA Period", "EMA lookback for power calc", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevPower = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevPower = null;
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal emaVal)
	{
		if (candle.State != CandleStates.Finished) return;
		var bullsPower = candle.HighPrice - emaVal;
		var bearsPower = candle.LowPrice - emaVal;
		var avgPower = (bullsPower + bearsPower) / 2m;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevPower = avgPower; return; }
		if (_prevPower == null) { _prevPower = avgPower; return; }
		if (_prevPower.Value < 0m && avgPower >= 0m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevPower.Value > 0m && avgPower <= 0m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevPower = avgPower;
	}
}