AUD/USD Scalping Strategy
This strategy scalps AUD/USD on short timeframes using a combination of EMA trend filter, Bollinger Bands and RSI. The fast and slow EMAs define trend direction. Long trades are opened in uptrends when price touches the lower Bollinger Band and RSI is above the oversold threshold. Shorts are taken in downtrends when price reaches the upper band and RSI is below the overbought level. Fixed take profit and stop loss manage risk.
Details
- Entry Criteria:
- Long: Fast EMA above slow EMA, price at or below lower Bollinger Band, RSI above oversold level.
- Short: Fast EMA below slow EMA, price at or above upper Bollinger Band, RSI below overbought level.
- Long/Short: Both sides.
- Exit Criteria: Stop loss or take profit.
- Stops: Fixed stop loss and take profit.
- Default Values:
EmaShort= 13EmaLong= 26RsiPeriod= 4RsiOverbought= 70RsiOversold= 30BbLength= 20BbMultiplier= 2.0TakeProfit= 0.0005StopLoss= 0.0004
- Filters:
- Category: Scalping
- Direction: Both
- Indicators: EMA, Bollinger Bands, RSI
- Stops: Fixed
- Complexity: Low
- Timeframe: 1 minute
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Medium
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 EMA crossover with RSI filter.
/// Buys when fast EMA crosses above slow EMA and RSI exits oversold.
/// Sells when fast EMA crosses below slow EMA and RSI exits overbought.
/// </summary>
public class AudUsdScalpingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaShort;
private readonly StrategyParam<int> _emaLong;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _cooldownBars;
private decimal _prevFastEma;
private decimal _prevSlowEma;
private int _barIndex;
private int _lastTradeBar;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Fast EMA period.
/// </summary>
public int EmaShort
{
get => _emaShort.Value;
set => _emaShort.Value = value;
}
/// <summary>
/// Slow EMA period.
/// </summary>
public int EmaLong
{
get => _emaLong.Value;
set => _emaLong.Value = value;
}
/// <summary>
/// RSI calculation period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public AudUsdScalpingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_emaShort = Param(nameof(EmaShort), 13)
.SetGreaterThanZero()
.SetDisplay("Short EMA", "Fast EMA period", "Indicators");
_emaLong = Param(nameof(EmaLong), 26)
.SetGreaterThanZero()
.SetDisplay("Long EMA", "Slow EMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI calculation period", "Indicators");
_cooldownBars = Param(nameof(CooldownBars), 350)
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFastEma = 0;
_prevSlowEma = 0;
_barIndex = 0;
_lastTradeBar = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var emaFast = new ExponentialMovingAverage { Length = EmaShort };
var emaSlow = new ExponentialMovingAverage { Length = EmaLong };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(emaFast, emaSlow, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, emaFast);
DrawIndicator(area, emaSlow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
_barIndex++;
var cooldownOk = _barIndex - _lastTradeBar > CooldownBars;
// EMA crossover with RSI filter
var crossUp = _prevFastEma > 0 && _prevFastEma <= _prevSlowEma && fastValue > slowValue;
var crossDown = _prevFastEma > 0 && _prevFastEma >= _prevSlowEma && fastValue < slowValue;
if (crossUp && rsiValue < 60 && Position <= 0 && cooldownOk)
{
BuyMarket();
_lastTradeBar = _barIndex;
}
else if (crossDown && rsiValue > 40 && Position >= 0 && cooldownOk)
{
SellMarket();
_lastTradeBar = _barIndex;
}
_prevFastEma = fastValue;
_prevSlowEma = slowValue;
}
}
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, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class aud_usd_scalping_strategy(Strategy):
"""
Scalping strategy using EMA crossover with RSI filter.
Buys when fast EMA crosses above slow EMA and RSI exits oversold.
Sells when fast EMA crosses below slow EMA and RSI exits overbought.
"""
def __init__(self):
super(aud_usd_scalping_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(1)) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._ema_short = self.Param("EmaShort", 13) \
.SetGreaterThanZero() \
.SetDisplay("Short EMA", "Fast EMA period", "Indicators")
self._ema_long = self.Param("EmaLong", 26) \
.SetGreaterThanZero() \
.SetDisplay("Long EMA", "Slow EMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("RSI Period", "RSI calculation period", "Indicators")
self._cooldown_bars = self.Param("CooldownBars", 350) \
.SetDisplay("Cooldown Bars", "Bars between trades", "Trading")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._bar_index = 0
self._last_trade_bar = 0
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
@property
def EmaShort(self): return self._ema_short.Value
@EmaShort.setter
def EmaShort(self, v): self._ema_short.Value = v
@property
def EmaLong(self): return self._ema_long.Value
@EmaLong.setter
def EmaLong(self, v): self._ema_long.Value = v
@property
def RsiPeriod(self): return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, v): self._rsi_period.Value = v
@property
def CooldownBars(self): return self._cooldown_bars.Value
@CooldownBars.setter
def CooldownBars(self, v): self._cooldown_bars.Value = v
def OnReseted(self):
super(aud_usd_scalping_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._bar_index = 0
self._last_trade_bar = 0
def OnStarted2(self, time):
super(aud_usd_scalping_strategy, self).OnStarted2(time)
ema_fast = ExponentialMovingAverage()
ema_fast.Length = self.EmaShort
ema_slow = ExponentialMovingAverage()
ema_slow.Length = self.EmaLong
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema_fast, ema_slow, rsi, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema_fast)
self.DrawIndicator(area, ema_slow)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, fast_value, slow_value, rsi_value):
if candle.State != CandleStates.Finished:
return
self._bar_index += 1
cooldown_ok = self._bar_index - self._last_trade_bar > self.CooldownBars
cross_up = self._prev_fast > 0 and self._prev_fast <= self._prev_slow and fast_value > slow_value
cross_down = self._prev_fast > 0 and self._prev_fast >= self._prev_slow and fast_value < slow_value
if cross_up and rsi_value < 60 and self.Position <= 0 and cooldown_ok:
self.BuyMarket()
self._last_trade_bar = self._bar_index
elif cross_down and rsi_value > 40 and self.Position >= 0 and cooldown_ok:
self.SellMarket()
self._last_trade_bar = self._bar_index
self._prev_fast = fast_value
self._prev_slow = slow_value
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return aud_usd_scalping_strategy()