Scalping-EA-Strategie
Ein einfaches Scalping-System, das ständig zwei Pending Orders aufrecht erhält: ein Buy Stop oberhalb des Marktes und ein Sell Stop darunter. Wenn der Marktpreis einer Order zu nahe kommt oder sich zu weit entfernt, wird die Order ersetzt, um einen festen Abstand vom aktuellen Preis zu wahren. Ausgeführte Orders verwenden feste Take-Profit- und Stop-Loss-Abstände.
Die Strategie stützt sich nicht auf Indikatoren und reagiert ausschließlich auf Tick-Preisänderungen.
Details
- Einstiegskriterien:
- Buy Stop 100 Punkte über dem Preis und Sell Stop 100 Punkte darunter platzieren.
- Orders werden ersetzt, wenn der Abstand zum Preis zu klein oder zu groß wird.
- Long/Short: Beide.
- Ausstiegskriterien:
- Jede Order trägt festen Take Profit und Stop Loss.
- Stops: Ja, fester Abstand.
- Filter: Keine.
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>
/// Scalping strategy using RSI overbought/oversold with EMA trend filter.
/// Buys on RSI oversold in uptrend, sells on RSI overbought in downtrend.
/// </summary>
public class ScalpingEAStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _entryPrice;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int AtrPeriod { get => _atrPeriod.Value; set => _atrPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ScalpingEAStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 7)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR period for stops", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var atr = new StandardDeviation { Length = AtrPeriod };
SubscribeCandles(CandleType)
.Bind(rsi, ema, atr, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi, decimal ema, decimal atr)
{
if (candle.State != CandleStates.Finished) return;
if (atr <= 0) return;
var close = candle.ClosePrice;
// Buy: RSI oversold
if (rsi < 35 && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_entryPrice = close;
}
// Sell: RSI overbought
else if (rsi > 65 && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_entryPrice = close;
}
// Exit long: price crosses below EMA or stop loss
else if (Position > 0)
{
if (close < ema || (_entryPrice > 0 && close <= _entryPrice - atr * 2))
{
SellMarket();
_entryPrice = 0;
}
}
// Exit short: price crosses above EMA or stop loss
else if (Position < 0)
{
if (close > ema || (_entryPrice > 0 && close >= _entryPrice + atr * 2))
{
BuyMarket();
_entryPrice = 0;
}
}
}
}
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 RelativeStrengthIndex, ExponentialMovingAverage, StandardDeviation
from StockSharp.Algo.Strategies import Strategy
class scalping_ea_strategy(Strategy):
def __init__(self):
super(scalping_ea_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 7).SetGreaterThanZero().SetDisplay("RSI Period", "RSI period", "Indicators")
self._ema_period = self.Param("EmaPeriod", 20).SetGreaterThanZero().SetDisplay("EMA Period", "EMA trend filter period", "Indicators")
self._atr_period = self.Param("AtrPeriod", 14).SetGreaterThanZero().SetDisplay("ATR Period", "ATR period for stops", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Type of candles", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(scalping_ea_strategy, self).OnReseted()
self._entry_price = 0
def OnStarted2(self, time):
super(scalping_ea_strategy, self).OnStarted2(time)
self._entry_price = 0
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
atr = StandardDeviation()
atr.Length = self._atr_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(rsi, ema, atr, self.OnProcess).Start()
def OnProcess(self, candle, rsi_val, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
if atr_val <= 0:
return
close = float(candle.ClosePrice)
# Buy: RSI oversold
if rsi_val < 35 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._entry_price = close
# Sell: RSI overbought
elif rsi_val > 65 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._entry_price = close
# Exit long: price below EMA or stop loss
elif self.Position > 0:
if close < ema_val or (self._entry_price > 0 and close <= self._entry_price - atr_val * 2):
self.SellMarket()
self._entry_price = 0
# Exit short: price above EMA or stop loss
elif self.Position < 0:
if close > ema_val or (self._entry_price > 0 and close >= self._entry_price + atr_val * 2):
self.BuyMarket()
self._entry_price = 0
def CreateClone(self):
return scalping_ea_strategy()