Start
/
Strategie-Beispiele
Auf GitHub ansehen
AO Divergenz-Strategie
Die Strategie sucht nach bullischen und bärischen Divergenzen zwischen dem Awesome Oscillator (AO) und dem Preis. Eine bullische Divergenz tritt auf, wenn der Preis ein niedrigeres Tief bildet, während der AO ein höheres Tief bildet. Eine bärische Divergenz erscheint, wenn der Preis ein höheres Hoch bildet, während der AO ein niedrigeres Hoch bildet.
Wird eine bullische Divergenz erkannt, eröffnet die Strategie eine Long-Position. Eine bärische Divergenz löst eine Short-Position aus. Positionen werden bei entgegengesetzten Signalen umgekehrt.
Details
Einstiegskriterien : Bullische oder bärische AO-Divergenz mit dem Preis.
Long/Short : Beide.
Ausstiegskriterien : Entgegengesetztes Divergenzsignal.
Stops : Nein.
Standardwerte :
CandleType = 5 Minuten
FastLength = 5
SlowLength = 34
Lookback = 5
UseEma = false
Filter :
Kategorie: Indikator
Richtung: Beide
Indikatoren: Awesome Oscillator
Stops: Nein
Komplexität: Mittel
Zeitrahmen: Intraday
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Ja
Risikolevel: Mittel
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>
/// AO Divergence strategy.
/// Buys when AO crosses above zero, sells when AO crosses below zero.
/// Uses EMA as trend filter.
/// </summary>
public class AoDivergenceStrategy : Strategy
{
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _cooldownBars;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevAo;
private int _barIndex;
private int _lastTradeBar;
/// <summary>
/// EMA trend filter period.
/// </summary>
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public AoDivergenceStrategy()
{
_emaLength = Param(nameof(EmaLength), 40)
.SetDisplay("EMA Length", "EMA trend filter period", "Indicator");
_cooldownBars = Param(nameof(CooldownBars), 380)
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).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();
_prevAo = 0;
_barIndex = 0;
_lastTradeBar = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaLength };
var ao = new AwesomeOscillator();
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ao, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal aoValue)
{
if (candle.State != CandleStates.Finished)
return;
_barIndex++;
var cooldownOk = _barIndex - _lastTradeBar > CooldownBars;
// AO zero line crossover with EMA trend
var aoCrossUp = _prevAo <= 0 && aoValue > 0;
var aoCrossDown = _prevAo >= 0 && aoValue < 0;
if (aoCrossUp && candle.ClosePrice > emaValue && Position <= 0 && cooldownOk)
{
BuyMarket();
_lastTradeBar = _barIndex;
}
else if (aoCrossDown && candle.ClosePrice < emaValue && Position >= 0 && cooldownOk)
{
SellMarket();
_lastTradeBar = _barIndex;
}
_prevAo = aoValue;
}
}
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 CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, AwesomeOscillator
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class ao_divergence_strategy(Strategy):
"""
AO Divergence strategy.
Buys when AO crosses above zero with EMA uptrend, sells when AO crosses below zero with downtrend.
"""
def __init__(self):
super(ao_divergence_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 40) \
.SetDisplay("EMA Length", "EMA trend filter period", "Indicator")
self._cooldown_bars = self.Param("CooldownBars", 380) \
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading")
self._candle_type = self.Param("CandleType", tf(1)) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_ao = 0.0
self._bar_index = 0
self._last_trade_bar = 0
@property
def EmaLength(self): return self._ema_length.Value
@EmaLength.setter
def EmaLength(self, v): self._ema_length.Value = v
@property
def CooldownBars(self): return self._cooldown_bars.Value
@CooldownBars.setter
def CooldownBars(self, v): self._cooldown_bars.Value = v
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
def OnReseted(self):
super(ao_divergence_strategy, self).OnReseted()
self._prev_ao = 0.0
self._bar_index = 0
self._last_trade_bar = 0
def OnStarted2(self, time):
super(ao_divergence_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
ao = AwesomeOscillator()
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, ao, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_value, ao_value):
if candle.State != CandleStates.Finished:
return
self._bar_index += 1
cooldown_ok = self._bar_index - self._last_trade_bar > self.CooldownBars
ao_cross_up = self._prev_ao <= 0 and ao_value > 0
ao_cross_down = self._prev_ao >= 0 and ao_value < 0
if ao_cross_up and float(candle.ClosePrice) > ema_value and self.Position <= 0 and cooldown_ok:
self.BuyMarket()
self._last_trade_bar = self._bar_index
elif ao_cross_down and float(candle.ClosePrice) < ema_value and self.Position >= 0 and cooldown_ok:
self.SellMarket()
self._last_trade_bar = self._bar_index
self._prev_ao = ao_value
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return ao_divergence_strategy()