Start
/
Strategie-Beispiele
Auf GitHub ansehen
CandlesticksBW-Strategie
Diese Strategie repliziert den Bill Williams CandlesticksBW-Ansatz. Jede Kerze wird anhand des Momentums des Awesome Oscillator (AO) und des Accelerator Oscillator (AC) eingefärbt. Die Strategie öffnet oder schließt Positionen basierend auf Übergängen zwischen bullischen und bearischen Farben.
Funktionsweise
Berechnet AO als Differenz zwischen 5- und 34-Perioden-SMAs des Medianpreises.
Berechnet AC als AO minus 5-Perioden-SMA des AO.
Jede Kerze wird in sechs Farben eingeteilt, abhängig vom AO/AC-Wachstum und der Kerzenrichtung.
Ein bullisches Setup tritt auf, wenn die vorletzte Kerze bullisch ist (Farbe 0 oder 1). Wenn die Farbe der letzten Kerze über 1 liegt, wird eine Long-Position eröffnet und Short-Positionen werden geschlossen.
Ein bearisches Setup tritt auf, wenn die vorletzte Kerze bearisch ist (Farbe 4 oder 5). Wenn die Farbe der letzten Kerze unter 4 liegt, wird eine Short-Position eröffnet und Long-Positionen werden geschlossen.
Stops und Ziele werden über StartProtection angewendet.
Parameter
CandleType – Kerzen-Zeitrahmen.
SignalBar – Versatz-Balken für die Signalauswertung.
StopLoss – Stop-Loss-Distanz in Punkten.
TakeProfit – Take-Profit-Distanz in Punkten.
BuyPosOpen – Long-Positionen öffnen erlauben.
SellPosOpen – Short-Positionen öffnen erlauben.
BuyPosClose – Long-Positionen schließen erlauben.
SellPosClose – Short-Positionen schließen erlauben.
Indikatoren
Awesome Oscillator (aus SMAs abgeleitet).
Accelerator Oscillator.
Handelsregeln
Long-Einstieg: vorletzte Kerzenfarbe <2 und letzte Farbe >1.
Short-Einstieg: vorletzte Kerzenfarbe >3 und letzte Farbe <4.
Long-Ausstieg: bei Short-Einstiegsbedingung wenn Position >0.
Short-Ausstieg: bei Long-Einstiegsbedingung wenn Position <0.
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>
/// CandlesticksBW strategy based on Bill Williams' color classification of candles.
/// Uses Awesome and Accelerator oscillators to detect momentum shifts.
/// </summary>
public class CandlesticksBwStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private SimpleMovingAverage _aoFast;
private SimpleMovingAverage _aoSlow;
private SimpleMovingAverage _acMa;
private decimal _prevAo;
private decimal _prevAc;
private bool _hasPrev;
private int _prevColor = -1;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public CandlesticksBwStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame for analysis", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnReseted()
{
base.OnReseted();
_aoFast = null;
_aoSlow = null;
_acMa = null;
_prevAo = 0;
_prevAc = 0;
_hasPrev = false;
_prevColor = -1;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevAo = 0;
_prevAc = 0;
_hasPrev = false;
_prevColor = -1;
_aoFast = new SimpleMovingAverage { Length = 5 };
_aoSlow = new SimpleMovingAverage { Length = 34 };
_acMa = new SimpleMovingAverage { Length = 5 };
Indicators.Add(_aoFast);
Indicators.Add(_aoSlow);
Indicators.Add(_acMa);
var sma = new SimpleMovingAverage { Length = 1 };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal _unused)
{
if (candle.State != CandleStates.Finished)
return;
var hl2 = (candle.HighPrice + candle.LowPrice) / 2m;
var t = candle.CloseTime;
var aoFastResult = _aoFast.Process(hl2, t, true);
var aoSlowResult = _aoSlow.Process(hl2, t, true);
if (!_aoFast.IsFormed || !_aoSlow.IsFormed)
return;
var ao = aoFastResult.GetValue<decimal>() - aoSlowResult.GetValue<decimal>();
var acMaResult = _acMa.Process(ao, t, true);
if (!_acMa.IsFormed)
return;
var ac = ao - acMaResult.GetValue<decimal>();
// Bill Williams candle color classification:
// 0 = green (bullish candle + AO up + AC up)
// 1 = fade (bearish candle + AO up + AC up)
// 2 = squat green (bullish, mixed)
// 3 = squat red (bearish, mixed)
// 4 = fake (bullish candle + AO down + AC down)
// 5 = red (bearish candle + AO down + AC down)
int color;
if (_hasPrev && ao >= _prevAo && ac >= _prevAc)
color = candle.OpenPrice <= candle.ClosePrice ? 0 : 1;
else if (_hasPrev && ao <= _prevAo && ac <= _prevAc)
color = candle.OpenPrice >= candle.ClosePrice ? 5 : 4;
else
color = candle.OpenPrice <= candle.ClosePrice ? 2 : 3;
_prevAo = ao;
_prevAc = ac;
_hasPrev = true;
if (!IsFormedAndOnline())
{
_prevColor = color;
return;
}
if (_prevColor < 0)
{
_prevColor = color;
return;
}
// Bullish signal: prev was up momentum (0 or 1), current transitions
if (_prevColor < 2 && color > 1 && Position <= 0)
BuyMarket();
// Bearish signal: prev was down momentum (4 or 5), current transitions
else if (_prevColor > 3 && color < 4 && Position >= 0)
SellMarket();
_prevColor = color;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class candlesticks_bw_strategy(Strategy):
def __init__(self):
super(candlesticks_bw_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Time frame for analysis", "General")
self._ao_fast = None
self._ao_slow = None
self._ac_ma = None
self._prev_ao = 0.0
self._prev_ac = 0.0
self._has_prev = False
self._prev_color = -1
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(candlesticks_bw_strategy, self).OnReseted()
self._ao_fast = None
self._ao_slow = None
self._ac_ma = None
self._prev_ao = 0.0
self._prev_ac = 0.0
self._has_prev = False
self._prev_color = -1
def OnStarted2(self, time):
super(candlesticks_bw_strategy, self).OnStarted2(time)
self._prev_ao = 0.0
self._prev_ac = 0.0
self._has_prev = False
self._prev_color = -1
self._ao_fast = SimpleMovingAverage()
self._ao_fast.Length = 5
self._ao_slow = SimpleMovingAverage()
self._ao_slow.Length = 34
self._ac_ma = SimpleMovingAverage()
self._ac_ma.Length = 5
self.Indicators.Add(self._ao_fast)
self.Indicators.Add(self._ao_slow)
self.Indicators.Add(self._ac_ma)
sma = SimpleMovingAverage()
sma.Length = 1
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, _unused):
if candle.State != CandleStates.Finished:
return
hl2 = (float(candle.HighPrice) + float(candle.LowPrice)) / 2.0
t = candle.CloseTime
ao_fast_result = process_float(self._ao_fast, hl2, t, True)
ao_slow_result = process_float(self._ao_slow, hl2, t, True)
if not self._ao_fast.IsFormed or not self._ao_slow.IsFormed:
return
ao = float(ao_fast_result) - float(ao_slow_result)
ac_ma_result = process_float(self._ac_ma, ao, t, True)
if not self._ac_ma.IsFormed:
return
ac = ao - float(ac_ma_result)
open_price = float(candle.OpenPrice)
close_price = float(candle.ClosePrice)
if self._has_prev and ao >= self._prev_ao and ac >= self._prev_ac:
color = 0 if open_price <= close_price else 1
elif self._has_prev and ao <= self._prev_ao and ac <= self._prev_ac:
color = 5 if open_price >= close_price else 4
else:
color = 2 if open_price <= close_price else 3
self._prev_ao = ao
self._prev_ac = ac
self._has_prev = True
if not self.IsFormedAndOnline():
self._prev_color = color
return
if self._prev_color < 0:
self._prev_color = color
return
if self._prev_color < 2 and color > 1 and self.Position <= 0:
self.BuyMarket()
elif self._prev_color > 3 and color < 4 and self.Position >= 0:
self.SellMarket()
self._prev_color = color
def CreateClone(self):
return candlesticks_bw_strategy()