MA CCI Strategie
Strategie, die Moving Average und den CCI-Indikator kombiniert. Kauft, wenn der Preis über dem MA liegt und der CCI überverkauft ist. Verkauft, wenn der Preis unter dem MA liegt und der CCI überkauft ist.
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 49%. Am besten geeignet für den Kryptomarkt.
Ein Moving Average gibt die Trendrichtung vor, während der CCI nach Abweichungen von diesem Durchschnitt sucht. Einstiege erfolgen bei CCI-Extremwerten in Richtung des MA.
Ideal für Swing-Trader, die bei Rücksetzern einsteigen. ATR-Stops schützen vor plötzlichen Kursausschlägen.
Details
- Einstiegskriterien:
- Long:
Close > MA && CCI < OversoldLevel - Short:
Close < MA && CCI > OverboughtLevel
- Long:
- Long/Short: Beide
- Ausstiegskriterien:
- CCI kehrt zur Nulllinie zurück
- Stops: Prozentbasiert mit
StopLossPercent - Standardwerte:
MaPeriod= 20CciPeriod= 20OverboughtLevel= 100mOversoldLevel= -100mStopLossPercent= 2.0mCandleType= TimeSpan.FromMinutes(5).TimeFrame()
- Filter:
- Kategorie: Mean Reversion
- Richtung: Beide
- Indikatoren: Moving Average, CCI
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Mittelfristig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- 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>
/// Strategy combining Moving Average and CCI indicators.
/// Buys when price is above MA and CCI is oversold.
/// Sells when price is below MA and CCI is overbought.
/// </summary>
public class MaCciStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<decimal> _oversoldLevel;
private readonly StrategyParam<int> _cooldownBars;
private decimal _cciValue;
private int _cooldown;
/// <summary>
/// Candle type for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// MA period.
/// </summary>
public int MaPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
/// <summary>
/// CCI period.
/// </summary>
public int CciPeriod
{
get => _cciPeriod.Value;
set => _cciPeriod.Value = value;
}
/// <summary>
/// CCI overbought level.
/// </summary>
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
/// <summary>
/// CCI oversold level.
/// </summary>
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Initialize strategy.
/// </summary>
public MaCciStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_maPeriod = Param(nameof(MaPeriod), 20)
.SetRange(10, 50)
.SetDisplay("MA Period", "Period for Moving Average", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 20)
.SetRange(10, 30)
.SetDisplay("CCI Period", "Period for CCI calculation", "Indicators");
_overboughtLevel = Param(nameof(OverboughtLevel), 100m)
.SetDisplay("Overbought Level", "CCI level considered overbought", "Trading Levels");
_oversoldLevel = Param(nameof(OversoldLevel), -100m)
.SetDisplay("Oversold Level", "CCI level considered oversold", "Trading Levels");
_cooldownBars = Param(nameof(CooldownBars), 100)
.SetDisplay("Cooldown Bars", "Bars between trades", "General")
.SetRange(5, 500);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cciValue = 0;
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = MaPeriod };
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
// CCI takes candle input - use BindEx as side handler
subscription.BindEx(cci, OnCci);
// EMA for main logic
subscription
.Bind(ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
var cciArea = CreateChartArea();
if (cciArea != null)
DrawIndicator(cciArea, cci);
}
}
private void OnCci(ICandleMessage candle, IIndicatorValue value)
{
if (!value.IsEmpty)
_cciValue = value.ToDecimal();
}
private void ProcessCandle(ICandleMessage candle, decimal maValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (_cooldown > 0)
{
_cooldown--;
return;
}
// Buy: price above MA + CCI oversold
if (close > maValue && _cciValue < OversoldLevel && Position == 0)
{
BuyMarket();
_cooldown = CooldownBars;
}
// Sell: price below MA + CCI overbought
else if (close < maValue && _cciValue > OverboughtLevel && Position == 0)
{
SellMarket();
_cooldown = CooldownBars;
}
// Exit long: price crosses below MA
if (Position > 0 && close < maValue)
{
SellMarket();
_cooldown = CooldownBars;
}
// Exit short: price crosses above MA
else if (Position < 0 && close > maValue)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
}
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 ExponentialMovingAverage, CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class ma_cci_strategy(Strategy):
"""
Strategy combining Moving Average and CCI indicators.
"""
def __init__(self):
super(ma_cci_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._ma_period = self.Param("MaPeriod", 20) \
.SetRange(10, 50) \
.SetDisplay("MA Period", "Period for Moving Average", "Indicators")
self._cci_period = self.Param("CciPeriod", 20) \
.SetRange(10, 30) \
.SetDisplay("CCI Period", "Period for CCI calculation", "Indicators")
self._overbought_level = self.Param("OverboughtLevel", 100.0) \
.SetDisplay("Overbought Level", "CCI level considered overbought", "Trading Levels")
self._oversold_level = self.Param("OversoldLevel", -100.0) \
.SetDisplay("Oversold Level", "CCI level considered oversold", "Trading Levels")
self._cooldown_bars = self.Param("CooldownBars", 100) \
.SetDisplay("Cooldown Bars", "Bars between trades", "General") \
.SetRange(5, 500)
self._cci_value = 0.0
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(ma_cci_strategy, self).OnStarted2(time)
self._cci_value = 0.0
self._cooldown = 0
ema = ExponentialMovingAverage()
ema.Length = self._ma_period.Value
cci = CommodityChannelIndex()
cci.Length = self._cci_period.Value
subscription = self.SubscribeCandles(self.candle_type)
# CCI takes candle input - use BindEx as side handler
subscription.BindEx(cci, self.OnCci)
subscription.Bind(ema, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
cci_area = self.CreateChartArea()
if cci_area is not None:
self.DrawIndicator(cci_area, cci)
def OnCci(self, candle, value):
if not value.IsEmpty:
self._cci_value = float(value)
def ProcessCandle(self, candle, ma_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
mv = float(ma_value)
if self._cooldown > 0:
self._cooldown -= 1
return
cd = self._cooldown_bars.Value
ob = self._overbought_level.Value
os_level = self._oversold_level.Value
# Buy: price above MA + CCI oversold
if close > mv and self._cci_value < os_level and self.Position == 0:
self.BuyMarket()
self._cooldown = cd
elif close < mv and self._cci_value > ob and self.Position == 0:
self.SellMarket()
self._cooldown = cd
# Exit long: price crosses below MA
if self.Position > 0 and close < mv:
self.SellMarket()
self._cooldown = cd
elif self.Position < 0 and close > mv:
self.BuyMarket()
self._cooldown = cd
def OnReseted(self):
super(ma_cci_strategy, self).OnReseted()
self._cci_value = 0.0
self._cooldown = 0
def CreateClone(self):
return ma_cci_strategy()