CCI ボラティリティフィルター戦略
CCI Volatility Filter 戦略は、CCI とボラティリティフィルターを中心に構築されています。
テストでは年間平均リターン約 58% を示しています。株式市場で最もよく機能します。
インジケーターがイントラデイ (5m) データ上のフィルタリングされたエントリーを確認したときにシグナルが発動します。これにより、この手法はアクティブトレーダーに適しています。
ストップは ATR の倍数と CciPeriod、AtrPeriod などの要素に依存します。リスクとリワードのバランスをとるためにこれらのデフォルト値を調整してください。
詳細
- エントリー条件: インジケーター条件については実装を参照してください。
- ロング/ショート: 両方。
- エグジット条件: 反対のシグナルまたはストップロジック。
- ストップ: はい、インジケーターベースの計算を使用。
- デフォルト値:
CciPeriod = 20AtrPeriod = 14CciOversold = -100mCciOverbought = 100mCandleType = TimeSpan.FromMinutes(5).TimeFrame()
- フィルター:
- カテゴリ: トレンドフォロー
- 方向: 両方
- インジケーター: 複数
- ストップ: はい
- 複雑さ: 中級
- 時間軸: イントラデイ (5m)
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Strategy based on CCI with an ATR-based volatility filter.
/// </summary>
public class CciWithVolatilityFilterStrategy : Strategy
{
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _cciOversold;
private readonly StrategyParam<decimal> _cciOverbought;
private readonly StrategyParam<int> _signalCooldownBars;
private readonly StrategyParam<DataType> _candleType;
private CommodityChannelIndex _cci;
private AverageTrueRange _atr;
private SimpleMovingAverage _atrSma;
private int _cooldownRemaining;
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public decimal CciOversold { get => _cciOversold.Value; set => _cciOversold.Value = value; }
public decimal CciOverbought { get => _cciOverbought.Value; set => _cciOverbought.Value = value; }
public int SignalCooldownBars { get => _signalCooldownBars.Value; set => _signalCooldownBars.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CciWithVolatilityFilterStrategy()
{
_cciPeriod = Param(nameof(CciPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "Period for CCI calculation", "Indicators");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "Period for ATR calculation", "Indicators");
_cciOversold = Param(nameof(CciOversold), -100m)
.SetDisplay("CCI Oversold", "CCI oversold level", "Indicators");
_cciOverbought = Param(nameof(CciOverbought), 100m)
.SetDisplay("CCI Overbought", "CCI overbought level", "Indicators");
_signalCooldownBars = Param(nameof(SignalCooldownBars), 24)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between entries", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cci = null;
_atr = null;
_atrSma = null;
_cooldownRemaining = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_cci = new CommodityChannelIndex { Length = CciPeriod };
_atr = new AverageTrueRange { Length = AtrPeriod };
_atrSma = new SMA { Length = AtrPeriod };
_cooldownRemaining = 0;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent)
);
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (_cooldownRemaining > 0)
_cooldownRemaining--;
var cciValue = _cci.Process(candle);
var atrValue = _atr.Process(candle);
if (!cciValue.IsFormed || !atrValue.IsFormed)
return;
var atrAverage = _atrSma.Process(new DecimalIndicatorValue(_atrSma, atrValue.ToDecimal(), candle.ServerTime) { IsFinal = true });
if (!atrAverage.IsFormed)
return;
var cci = cciValue.ToDecimal();
var atr = atrValue.ToDecimal();
var averageAtr = atrAverage.ToDecimal();
var isTradableVolatility = averageAtr <= 0m || atr <= averageAtr * 10m;
if (_cooldownRemaining > 0 || !isTradableVolatility)
return;
if (Position == 0 && cci <= CciOversold)
{
BuyMarket();
_cooldownRemaining = SignalCooldownBars;
}
else if (Position == 0 && cci >= CciOverbought)
{
SellMarket();
_cooldownRemaining = SignalCooldownBars;
}
}
}
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, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import CommodityChannelIndex, AverageTrueRange, SimpleMovingAverage, CandleIndicatorValue
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class cci_with_volatility_filter_strategy(Strategy):
"""
Strategy based on CCI with an ATR-based volatility filter.
"""
def __init__(self):
super(cci_with_volatility_filter_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("CCI Period", "Period for CCI calculation", "Indicators")
self._atr_period = self.Param("AtrPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("ATR Period", "Period for ATR calculation", "Indicators")
self._cci_oversold = self.Param("CciOversold", -100.0) \
.SetDisplay("CCI Oversold", "CCI oversold level", "Indicators")
self._cci_overbought = self.Param("CciOverbought", 100.0) \
.SetDisplay("CCI Overbought", "CCI overbought level", "Indicators")
self._signal_cooldown_bars = self.Param("SignalCooldownBars", 24) \
.SetGreaterThanZero() \
.SetDisplay("Signal Cooldown", "Bars to wait between entries", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._cooldown_remaining = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(cci_with_volatility_filter_strategy, self).OnReseted()
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(cci_with_volatility_filter_strategy, self).OnStarted2(time)
self._cci = CommodityChannelIndex()
self._cci.Length = int(self._cci_period.Value)
self._atr = AverageTrueRange()
self._atr.Length = int(self._atr_period.Value)
self._atr_sma = SimpleMovingAverage()
self._atr_sma.Length = int(self._atr_period.Value)
self._cooldown_remaining = 0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
self.StartProtection(
Unit(2, UnitTypes.Percent),
Unit(1, UnitTypes.Percent)
)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
cci_result = self._cci.Process(CandleIndicatorValue(self._cci, candle))
atr_result = self._atr.Process(CandleIndicatorValue(self._atr, candle))
if not cci_result.IsFormed or not atr_result.IsFormed:
return
atr_val = float(atr_result)
atr_avg_result = process_float(self._atr_sma, Decimal(atr_val), candle.ServerTime, True)
if not atr_avg_result.IsFormed:
return
cci_val = float(cci_result)
average_atr = float(atr_avg_result)
is_tradable_volatility = average_atr <= 0.0 or atr_val <= average_atr * 10.0
if self._cooldown_remaining > 0 or not is_tradable_volatility:
return
oversold = float(self._cci_oversold.Value)
overbought = float(self._cci_overbought.Value)
cd = int(self._signal_cooldown_bars.Value)
if self.Position == 0 and cci_val <= oversold:
self.BuyMarket()
self._cooldown_remaining = cd
elif self.Position == 0 and cci_val >= overbought:
self.SellMarket()
self._cooldown_remaining = cd
def CreateClone(self):
return cci_with_volatility_filter_strategy()