GitHub で見る
Exp ColorX2MA X2戦略
この戦略はStockSharp向けにデュアル時間軸エキスパート「Exp_ColorX2MA_X2」を再現します。2つのColorX2MAフィルターを重ねています:上位時間軸のトレンドマップと下位時間軸のエントリートリガーです。両方のColorX2MA値は、2つの設定可能な移動平均を連鎖させて構築され、現在の傾きに応じて色付けされます。トレーディングの判断は、下位時間軸の色が上位時間軸のトレンド方向に変化したときに実行されます。
実装は元の適用価格オプションと最も一般的なスムージングモード(SMA、EMA、SMMA、LWMA、Jurik)をサポートします。JurikインジケーターがPhaseプロパティを公開している場合、設定されたフェーズ値で更新されます。
トレーディングルール
- ロングエントリー
- 上位時間軸のColorX2MA色が強気(trend direction > 0)。
- 下位時間軸のColorX2MA色が前のバーの強気から最後の完成バーで中立または弱気に変化した(
Clr[1] == 1 かつ Clr[0] != 1)。
- ロングトレードが有効。
- ショートエントリー
- 上位時間軸のColorX2MA色が弱気(trend direction < 0)。
- 下位時間軸のColorX2MA色が前のバーの弱気から最後の完成バーで中立または強気に変化した(
Clr[1] == 2 かつ Clr[0] != 2)。
- ショートトレードが有効。
- ロングエグジット
- 下位時間軸で弱気の色が現れ(
Clr[1] == 2)二次ロング決済許可が有効、または上位時間軸のトレンドが弱気に転換し一次ロング決済許可が有効の場合。
- ショートエグジット
- 下位時間軸で強気の色が現れ(
Clr[1] == 1)二次ショート決済許可が有効、または上位時間軸のトレンドが強気に転換し一次ショート決済許可が有効の場合。
- ストップ
- オプションのストップロスとテイクプロフィットの距離はポイントで指定されます(インストゥルメントの価格ステップで乗算)。完成した各シグナルキャンドルで、キャンドルの極値と平均ポジション価格を比較して評価されます。
デフォルト値
- トレンド時間軸: 6時間足。
- シグナル時間軸: 30分足。
- トレンドスムージング: SMA(12)→Jurik(5, フェーズ15)。
- シグナルスムージング: SMA(12)→Jurik(5, フェーズ15)。
- 適用価格: 終値。
- シグナルシフト: 両時間軸で1バー。
- 許可: ロング/ショートのエントリーとエグジットが有効。
- ストップロス: 1000ポイント(価格ステップを使用して変換)。
- テイクプロフィット: 2000ポイント(価格ステップを使用して変換)。
フィルターと注記
- 方向: 許可フラグで制御され、ロングとショートの両方を取引。
- 時間軸: デュアル時間軸(HTFでトレンド、LTFでエントリー)。
- インジケーター: 設定可能なスムージング方法を持つ2段階ColorX2MA。
- スムージングサポート:
Sma、Ema、Smma、Lwma、Jurik。元のライブラリの他のモードは実装されていません。
- 適用価格: TrendFollowとDemarkの価格を含む全12の元の式。
- ストップ: オプションの固定距離ストップロスとテイクプロフィット。
- 複雑さ: 2つの時間軸とカラーバッファーを同期するため中級。
- 適合市場: ColorX2MAインジケーターが好まれるFX、指数、または暗号資産のトレンドフォロー設定。
使用上のヒント
- 頻繁なホイップソーを避けるため、上位時間軸をシグナル時間軸より大幅に大きく保つこと。
- シグナルシフトパラメーター(
SignalSignalBar)を縮めると反応が速くなり、増やすとより平滑化される。
- インストゥルメントが
PriceStepを提供しない場合、ストップ/テイク距離は価格単位で直接解釈される。
- Jurikスムージングにはライセンス付きのStockSharpインジケーターパッケージが必要です。利用できない場合、戦略は他のスムージングオプションで引き続き実行されます。
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>
/// ColorX2MA X2 strategy (simplified). Uses dual EMA smoothing to detect trend color transitions.
/// Buys when the smoothed MA turns up, sells when it turns down.
/// </summary>
public class ExpColorX2MaX2Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
public ExpColorX2MaX2Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_fastLength = Param(nameof(FastLength), 12)
.SetGreaterThanZero()
.SetDisplay("Fast Length", "Fast EMA period", "Indicators");
_slowLength = Param(nameof(SlowLength), 26)
.SetGreaterThanZero()
.SetDisplay("Slow Length", "Slow EMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastEma = new ExponentialMovingAverage { Length = FastLength };
var slowEma = new ExponentialMovingAverage { Length = SlowLength };
decimal prevFast = 0, prevSlow = 0;
var hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, (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;
}
// Fast crosses above slow
if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
BuyMarket();
// Fast crosses below slow
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, fastEma);
DrawIndicator(area, slowEma);
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 exp_color_x2_ma_x2_strategy(Strategy):
def __init__(self):
super(exp_color_x2_ma_x2_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candles", "General")
self._fast_length = self.Param("FastLength", 12) \
.SetDisplay("Fast Length", "Fast EMA period", "Indicators")
self._slow_length = self.Param("SlowLength", 26) \
.SetDisplay("Slow Length", "Slow EMA period", "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 FastLength(self):
return self._fast_length.Value
@property
def SlowLength(self):
return self._slow_length.Value
def OnReseted(self):
super(exp_color_x2_ma_x2_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(exp_color_x2_ma_x2_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self.FastLength
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self.SlowLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast_ema, slow_ema, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
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 exp_color_x2_ma_x2_strategy()