GitHub で見る
ブロンズパン戦略
この戦略は、MetaTrader 4 エキスパート アドバイザー「Bronzew_pan」の StockSharp 移植です。完成したローソク足で単一の商品を取引し、独自の DayImpuls オシレーターと Williams %R および商品チャネル指数 (CCI) を組み合わせて、勢いの反転を検出します。
仕組み
- 構成されたローソク足タイプをサブスクライブし、同じ期間で DayImpuls、Williams %R、および CCI を実行します。
- 元のヘッジ動作をエミュレートするために、長期エクスポージャーと短期エクスポージャーを独立して会計処理します。
- 変動利益が
ProfitTarget に達するか、LossTarget を下回ると、すべてのポジションをクローズします。
- DayImpuls が
DayImpulsShortLevel を上回って下落し、Williams %R が WilliamsLevelUp を上回り、CCI が CciLevel を超えた場合にショートが始まります。
- DayImpuls が
DayImpulsLongLevel を下回って上昇し、Williams %R が WilliamsLevelDown を下回り、CCI が -CciLevel 未満の場合にロングが始まります。
- 変動損益が
PredBand の範囲を超えた場合、戦略は LotMultiplier を乗算した大きな平均注文を送信して方向を反転し、MetaTrader からの緊急回復ロジックを反映します。
- 個々のストップロスとテイクプロフィットの値は、価格に変換されたピップ距離を使用してロングバスケットとショートバスケットで監視されます。
- アカウント残高が
MinimumBalance を下回っている場合、またはロング バスケットとショート バスケットの両方がアクティブな場合、新しい取引は開始されません。
パラメーター
| 名前 |
説明 |
デフォルト |
TradeVolume |
エントリの基本ボリューム。 |
0.1 |
LongStopLossPips |
ロングバスケットのストップロス距離 (ピップ単位)。 |
0 |
ShortStopLossPips |
ショートバスケットのストップロス距離 (ピップ単位)。 |
0 |
LongTakeProfitPips |
ロングバスケットのテイクプロフィット距離(ピップ単位)。 |
0 |
ShortTakeProfitPips |
ショートバスケットのテイクプロフィット距離(ピップ単位)。 |
0 |
IndicatorPeriod |
DayImpuls、Williams %R および CCI で使用される長さ。 |
14 |
CciLevel |
買われ過ぎ/売られ過ぎを確認する絶対的な CCI しきい値。 |
150 |
WilliamsLevelUp |
Williams ショートパンツには %R レベルが必要です。 |
-15 |
WilliamsLevelDown |
ロングには Williams %R レベルが必要です。 |
-85 |
DayImpulsShortLevel |
短いエントリーを可能にする DayImpuls レベル。 |
50 |
DayImpulsLongLevel |
長いエントリを可能にする DayImpuls レベル。 |
-50 |
ProfitTarget |
すべてのポジションを決済する変動利益。 |
500 |
LossTarget |
すべてのポジションをクローズする浮動損失。 |
-2000 |
PredBand |
平均反転をトリガーするために使用される利益バンド。 |
100 |
LotMultiplier |
反転中にベースボリュームに適用される乗数。 |
30 |
MinimumBalance |
取引を続けるために必要な最低限の口座残高。 |
3000 |
CandleType |
キャンドルのサブスクリプションに使用される時間枠。 |
15m |
注意事項
- DayImpuls オシレーターは、ポイントで表現されたローソク体を平滑化するオリジナルのダブル EMA を複製します。
- ストップロスとテイクプロフィットの値はオプションです。
0 を設定すると、それぞれの保護側が無効になります。
- この戦略は完成したローソク足に依存し、不完全なバーを無視します。
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>
/// Bronze Pan strategy - CCI with momentum confirmation.
/// Buys when CCI crosses above positive level and momentum is positive.
/// Sells when CCI crosses below negative level and momentum is negative.
/// </summary>
public class BronzePanStrategy : Strategy
{
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _cciLevel;
private readonly StrategyParam<int> _momentumPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevCci;
private bool _hasPrev;
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BronzePanStrategy()
{
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetDisplay("CCI Period", "CCI lookback", "Indicators");
_cciLevel = Param(nameof(CciLevel), 100m)
.SetDisplay("CCI Level", "CCI threshold level", "Levels");
_momentumPeriod = Param(nameof(MomentumPeriod), 14)
.SetDisplay("Momentum Period", "Momentum lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevCci = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var mom = new Momentum { Length = MomentumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(cci, mom, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cci, decimal mom)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevCci = cci;
_hasPrev = true;
return;
}
if (_prevCci <= CciLevel && cci > CciLevel && mom > 0 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevCci >= -CciLevel && cci < -CciLevel && mom < 0 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevCci = cci;
}
}
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 CommodityChannelIndex, Momentum
from StockSharp.Algo.Strategies import Strategy
class bronze_pan_strategy(Strategy):
def __init__(self):
super(bronze_pan_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 14).SetDisplay("CCI Period", "CCI lookback", "Indicators")
self._cci_level = self.Param("CciLevel", 100.0).SetDisplay("CCI Level", "CCI threshold level", "Levels")
self._momentum_period = self.Param("MomentumPeriod", 14).SetDisplay("Momentum Period", "Momentum lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_cci = 0.0; self._has_prev = False
@property
def cci_period(self): return self._cci_period.Value
@property
def cci_level(self): return self._cci_level.Value
@property
def momentum_period(self): return self._momentum_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(bronze_pan_strategy, self).OnReseted()
self._prev_cci = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(bronze_pan_strategy, self).OnStarted2(time)
self._has_prev = False
cci = CommodityChannelIndex()
cci.Length = self.cci_period
mom = Momentum()
mom.Length = self.momentum_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(cci, mom, self.process_candle).Start()
def process_candle(self, candle, cci, mom):
if candle.State != CandleStates.Finished: return
cci_val = float(cci); mom_val = float(mom)
if not self._has_prev:
self._prev_cci = cci_val; self._has_prev = True; return
if self._prev_cci <= self.cci_level and cci_val > self.cci_level and mom_val > 0 and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_cci >= -self.cci_level and cci_val < -self.cci_level and mom_val < 0 and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_cci = cci_val
def CreateClone(self): return bronze_pan_strategy()