Estratégia Digital CCI Woodies
Esta estratégia opera no cruzamento de dois indicadores CCI (Índice de Canal de Commodities). Um CCI rápido reage rapidamente às mudanças de preço, enquanto um CCI lento suaviza o ruído do mercado. Os sinais são gerados quando a linha rápida cruza a lenta.
Detalhes
- Critérios de entrada:
- Comprado: o CCI rápido cruza acima do CCI lento.
- Vendido: o CCI rápido cruza abaixo do CCI lento.
- Comprado/Vendido: Ambos.
- Critérios de saída:
- As posições compradas são fechadas quando o CCI rápido cruza abaixo do CCI lento.
- As posições vendidas são fechadas quando o CCI rápido cruza acima do CCI lento.
- Stops: Não.
- Valores padrão:
CandleType= velas de 6 horasFastLength= 14SlowLength= 6BuyOpen= trueSellOpen= trueBuyClose= trueSellClose= true
- Filtros:
- Categoria: Seguidor de tendência
- Direção: Ambos
- Indicadores: CCI
- Stops: Não
- Complexidade: Baixo
- Período: Qualquer
- Sazonalidade: Não
- Redes neurais: Não
- Divergência: Não
- Nível de risco: Médio
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on crossover of fast and slow CCI indicators.
/// </summary>
public class DigitalCciWoodiesStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<bool> _buyOpen;
private readonly StrategyParam<bool> _sellOpen;
private readonly StrategyParam<bool> _buyClose;
private readonly StrategyParam<bool> _sellClose;
private decimal _prevFast;
private decimal _prevSlow;
private bool _isFirst = true;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Fast CCI length.
/// </summary>
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
/// <summary>
/// Slow CCI length.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <summary>
/// Allow long entries.
/// </summary>
public bool BuyOpen
{
get => _buyOpen.Value;
set => _buyOpen.Value = value;
}
/// <summary>
/// Allow short entries.
/// </summary>
public bool SellOpen
{
get => _sellOpen.Value;
set => _sellOpen.Value = value;
}
/// <summary>
/// Allow closing long positions.
/// </summary>
public bool BuyClose
{
get => _buyClose.Value;
set => _buyClose.Value = value;
}
/// <summary>
/// Allow closing short positions.
/// </summary>
public bool SellClose
{
get => _sellClose.Value;
set => _sellClose.Value = value;
}
/// <summary>
/// Initializes the strategy parameters.
/// </summary>
public DigitalCciWoodiesStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for candles", "General");
_fastLength = Param(nameof(FastLength), 14)
.SetGreaterThanZero()
.SetDisplay("Fast CCI Length", "Length of the fast CCI", "Indicators")
.SetOptimize(5, 30, 1);
_slowLength = Param(nameof(SlowLength), 6)
.SetGreaterThanZero()
.SetDisplay("Slow CCI Length", "Length of the slow CCI", "Indicators")
.SetOptimize(3, 20, 1);
_buyOpen = Param(nameof(BuyOpen), true)
.SetDisplay("Buy Open", "Allow long entries", "Trading");
_sellOpen = Param(nameof(SellOpen), true)
.SetDisplay("Sell Open", "Allow short entries", "Trading");
_buyClose = Param(nameof(BuyClose), true)
.SetDisplay("Buy Close", "Allow closing longs", "Trading");
_sellClose = Param(nameof(SellClose), true)
.SetDisplay("Sell Close", "Allow closing shorts", "Trading");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_isFirst = true;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastCci = new CommodityChannelIndex { Length = FastLength };
var slowCci = new CommodityChannelIndex { Length = SlowLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastCci, slowCci, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
var indicatorArea = CreateChartArea();
if (indicatorArea != null)
{
DrawIndicator(indicatorArea, fastCci);
DrawIndicator(indicatorArea, slowCci);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
// Skip unfinished candles
if (candle.State != CandleStates.Finished)
return;
// Ensure trading is allowed
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_isFirst)
{
_prevFast = fast;
_prevSlow = slow;
_isFirst = false;
return;
}
var crossUp = _prevFast <= _prevSlow && fast > slow;
var crossDown = _prevFast >= _prevSlow && fast < slow;
if (crossUp)
{
if (Position < 0 && SellClose)
BuyMarket();
if (BuyOpen && Position <= 0)
BuyMarket();
}
else if (crossDown)
{
if (Position > 0 && BuyClose)
SellMarket();
if (SellOpen && Position >= 0)
SellMarket();
}
else
{
if (fast > slow && SellClose && Position < 0)
BuyMarket();
if (fast < slow && BuyClose && Position > 0)
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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
from StockSharp.Algo.Strategies import Strategy
class digital_cci_woodies_strategy(Strategy):
def __init__(self):
super(digital_cci_woodies_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for candles", "General")
self._fast_length = self.Param("FastLength", 14) \
.SetDisplay("Fast CCI Length", "Length of the fast CCI", "Indicators")
self._slow_length = self.Param("SlowLength", 6) \
.SetDisplay("Slow CCI Length", "Length of the slow CCI", "Indicators")
self._buy_open = self.Param("BuyOpen", True) \
.SetDisplay("Buy Open", "Allow long entries", "Trading")
self._sell_open = self.Param("SellOpen", True) \
.SetDisplay("Sell Open", "Allow short entries", "Trading")
self._buy_close = self.Param("BuyClose", True) \
.SetDisplay("Buy Close", "Allow closing longs", "Trading")
self._sell_close = self.Param("SellClose", True) \
.SetDisplay("Sell Close", "Allow closing shorts", "Trading")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._is_first = True
@property
def candle_type(self):
return self._candle_type.Value
@property
def fast_length(self):
return self._fast_length.Value
@property
def slow_length(self):
return self._slow_length.Value
@property
def buy_open(self):
return self._buy_open.Value
@property
def sell_open(self):
return self._sell_open.Value
@property
def buy_close(self):
return self._buy_close.Value
@property
def sell_close(self):
return self._sell_close.Value
def OnReseted(self):
super(digital_cci_woodies_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._is_first = True
def OnStarted2(self, time):
super(digital_cci_woodies_strategy, self).OnStarted2(time)
fast_cci = CommodityChannelIndex()
fast_cci.Length = self.fast_length
slow_cci = CommodityChannelIndex()
slow_cci.Length = self.slow_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_cci, slow_cci, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
indicator_area = self.CreateChartArea()
if indicator_area is not None:
self.DrawIndicator(indicator_area, fast_cci)
self.DrawIndicator(indicator_area, slow_cci)
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast)
slow_val = float(slow)
if self._is_first:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._is_first = False
return
cross_up = self._prev_fast <= self._prev_slow and fast_val > slow_val
cross_down = self._prev_fast >= self._prev_slow and fast_val < slow_val
if cross_up:
if self.Position < 0 and self.sell_close:
self.BuyMarket()
if self.buy_open and self.Position <= 0:
self.BuyMarket()
elif cross_down:
if self.Position > 0 and self.buy_close:
self.SellMarket()
if self.sell_open and self.Position >= 0:
self.SellMarket()
else:
if fast_val > slow_val and self.sell_close and self.Position < 0:
self.BuyMarket()
if fast_val < slow_val and self.buy_close and self.Position > 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return digital_cci_woodies_strategy()