Diese Strategie ist ein vereinfachter StockSharp-Port des MetaTrader-Experten i-CAiChannel System Digit.
Der Algorithmus überwacht einen Volatilitätskanal, der aus einem gleitenden Durchschnitt und einer Standardabweichung (Bollinger Bänder) aufgebaut ist.
Wenn eine Kerze außerhalb des Kanals schließt und die nächste Kerze wieder zurückkehrt, handelt die Strategie in Richtung des Wiedereintritts.
Parameter
Length – Periode des gleitenden Durchschnitts.
Width – Standardabweichungsmultiplikator.
Candle Type – Zeitrahmen für die Verarbeitung.
Handelslogik
Kerzen des gewählten Zeitrahmens abonnieren.
Bollinger Bänder mit den angegebenen Parametern berechnen.
Wenn die vorherige Kerze über dem oberen Band schloss und die aktuelle Kerze wieder innerhalb schließt, Long gehen.
Wenn die vorherige Kerze unter dem unteren Band schloss und die aktuelle Kerze wieder innerhalb schließt, Short gehen.
Die Position wird umgekehrt, wenn das entgegengesetzte Signal auftritt.
Alle Signale werden nur auf abgeschlossenen Kerzen generiert.
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>
/// CAiChannel System Digit strategy using Bollinger Bands.
/// Buys when price returns inside from above the upper band.
/// Sells when price returns inside from below the lower band.
/// </summary>
public class CaiChannelSystemDigitStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<decimal> _width;
private readonly StrategyParam<DataType> _candle;
private bool _prevUp;
private bool _prevDown;
public int Length { get => _length.Value; set => _length.Value = value; }
public decimal Width { get => _width.Value; set => _width.Value = value; }
public DataType CandleType { get => _candle.Value; set => _candle.Value = value; }
public CaiChannelSystemDigitStrategy()
{
_length = Param(nameof(Length), 12).SetGreaterThanZero();
_width = Param(nameof(Width), 2m).SetGreaterThanZero();
_candle = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame());
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevUp = false;
_prevDown = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevUp = false;
_prevDown = false;
var bb = new BollingerBands { Length = Length, Width = Width };
var sub = SubscribeCandles(CandleType);
sub.BindEx(bb, Process).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, sub);
DrawIndicator(area, bb);
DrawOwnTrades(area);
}
}
private void Process(ICandleMessage candle, IIndicatorValue bbVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (bbVal is not IBollingerBandsValue bb || bb.UpBand is not decimal up || bb.LowBand is not decimal down)
return;
if (_prevUp && candle.ClosePrice <= up && Position <= 0)
BuyMarket();
else if (_prevDown && candle.ClosePrice >= down && Position >= 0)
SellMarket();
_prevUp = candle.ClosePrice > up;
_prevDown = candle.ClosePrice < down;
}
}
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 BollingerBands
from StockSharp.Algo.Strategies import Strategy
class cai_channel_system_digit_strategy(Strategy):
def __init__(self):
super(cai_channel_system_digit_strategy, self).__init__()
self._length = self.Param("Length", 12) \
.SetDisplay("Length", "BB period", "Indicator")
self._width = self.Param("Width", 2.0) \
.SetDisplay("Width", "BB width", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_up = False
self._prev_down = False
@property
def length(self):
return self._length.Value
@property
def width(self):
return self._width.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(cai_channel_system_digit_strategy, self).OnReseted()
self._prev_up = False
self._prev_down = False
def OnStarted2(self, time):
super(cai_channel_system_digit_strategy, self).OnStarted2(time)
self._prev_up = False
self._prev_down = False
bb = BollingerBands()
bb.Length = self.length
bb.Width = self.width
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(bb, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, bb)
self.DrawOwnTrades(area)
def process_candle(self, candle, bb_val):
if candle.State != CandleStates.Finished:
return
up = bb_val.UpBand
down = bb_val.LowBand
if up is None or down is None:
return
up = float(up)
down = float(down)
close_price = float(candle.ClosePrice)
if self._prev_up and close_price <= up and self.Position <= 0:
self.BuyMarket()
elif self._prev_down and close_price >= down and self.Position >= 0:
self.SellMarket()
self._prev_up = close_price > up
self._prev_down = close_price < down
def CreateClone(self):
return cai_channel_system_digit_strategy()