AUD/USD 剥头皮策略
该策略在短周期内对 AUD/USD 进行剥头皮交易,结合 EMA 趋势过滤、布林带和 RSI。快慢 EMA 用于确定趋势方向。当处于上升趋势时,价格触及布林带下轨且 RSI 高于超卖水平则做多;当处于下降趋势时,价格触及上轨且 RSI 低于超买水平则做空。固定的止盈和止损用于控制风险。
细节
- 入场条件:
- 多头:快 EMA 高于慢 EMA,价格位于布林带下轨附近,RSI 高于超卖水平。
- 空头:快 EMA 低于慢 EMA,价格位于布林带上轨附近,RSI 低于超买水平。
- 方向:双向。
- 出场条件:止损或止盈。
- 止损:固定的止损和止盈。
- 默认参数:
EmaShort= 13EmaLong= 26RsiPeriod= 4RsiOverbought= 70RsiOversold= 30BbLength= 20BbMultiplier= 2.0TakeProfit= 0.0005StopLoss= 0.0004
- 过滤器:
- 类型:剥头皮
- 方向:双向
- 指标:EMA、布林带、RSI
- 止损:固定
- 复杂度:低
- 时间框架:1 分钟
- 季节性:否
- 神经网络:否
- 背离:否
- 风险等级:中等
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()