AUD/USD スキャルピング戦略
EMAトレンドフィルター、Bollinger Bands、RSIを組み合わせて短い時間軸でAUD/USDをスキャルピングする戦略。高速・低速のEMAがトレンド方向を定義します。上昇トレンド時に価格がBollinger Bandの下部バンドに触れRSIが売られすぎ閾値を上回った場合にロングエントリーします。下降トレンド時に価格が上部バンドに達しRSIが買われすぎレベルを下回った場合にショートエントリーします。固定のテイクプロフィットとストップロスでリスクを管理します。
詳細
- エントリー条件:
- ロング: 高速EMAが低速EMAを上回り、価格がBollinger Bandの下部バンド以下、RSIが売られすぎレベルを上回る。
- ショート: 高速EMAが低速EMAを下回り、価格がBollinger Bandの上部バンド以上、RSIが買われすぎレベルを下回る。
- ロング/ショート: 両サイド。
- エグジット条件: ストップロスまたはテイクプロフィット。
- ストップ: 固定ストップロスとテイクプロフィット。
- デフォルト値:
EmaShort= 13EmaLong= 26RsiPeriod= 4RsiOverbought= 70RsiOversold= 30BbLength= 20BbMultiplier= 2.0TakeProfit= 0.0005StopLoss= 0.0004
- フィルター:
- カテゴリ: スキャルピング
- 方向: 両方
- インジケーター: EMA, Bollinger Bands, 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>
/// AUD/USD scalping strategy.
/// In an uptrend (fast EMA above slow EMA) a candle touching the lower Bollinger Band with RSI above RsiOversold goes long; in a
/// downtrend a candle touching the upper band with RSI below RsiOverbought goes short, reversing an opposite position. Fixed
/// price distances TakeProfit and StopLoss close the position.
/// </summary>
public class AudUsdScalpingStrategy : Strategy
{
private readonly StrategyParam<int> _emaShort;
private readonly StrategyParam<int> _emaLong;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiOverbought;
private readonly StrategyParam<decimal> _rsiOversold;
private readonly StrategyParam<int> _bbLength;
private readonly StrategyParam<decimal> _bbMultiplier;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<DataType> _candleType;
/// <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 period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// RSI level shorts must stay below.
/// </summary>
public decimal RsiOverbought
{
get => _rsiOverbought.Value;
set => _rsiOverbought.Value = value;
}
/// <summary>
/// RSI level longs must stay above.
/// </summary>
public decimal RsiOversold
{
get => _rsiOversold.Value;
set => _rsiOversold.Value = value;
}
/// <summary>
/// Bollinger Bands period.
/// </summary>
public int BbLength
{
get => _bbLength.Value;
set => _bbLength.Value = value;
}
/// <summary>
/// Bollinger Bands width multiplier.
/// </summary>
public decimal BbMultiplier
{
get => _bbMultiplier.Value;
set => _bbMultiplier.Value = value;
}
/// <summary>
/// Take-profit distance in price.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Stop-loss distance in price.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public AudUsdScalpingStrategy()
{
_emaShort = Param(nameof(EmaShort), 13)
.SetGreaterThanZero()
.SetDisplay("EMA Short", "Fast EMA period", "Trend");
_emaLong = Param(nameof(EmaLong), 26)
.SetGreaterThanZero()
.SetDisplay("EMA Long", "Slow EMA period", "Trend");
_rsiPeriod = Param(nameof(RsiPeriod), 4)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "RSI");
_rsiOverbought = Param(nameof(RsiOverbought), 70m)
.SetDisplay("RSI Overbought", "RSI level shorts must stay below", "RSI");
_rsiOversold = Param(nameof(RsiOversold), 30m)
.SetDisplay("RSI Oversold", "RSI level longs must stay above", "RSI");
_bbLength = Param(nameof(BbLength), 20)
.SetGreaterThanZero()
.SetDisplay("BB Length", "Bollinger Bands period", "Bollinger");
_bbMultiplier = Param(nameof(BbMultiplier), 2.0m)
.SetGreaterThanZero()
.SetDisplay("BB Multiplier", "Bollinger Bands width multiplier", "Bollinger");
_takeProfit = Param(nameof(TakeProfit), 0.0005m)
.SetNotNegative()
.SetDisplay("Take Profit", "Take-profit distance in price", "Risk");
_stopLoss = Param(nameof(StopLoss), 0.0004m)
.SetNotNegative()
.SetDisplay("Stop Loss", "Stop-loss distance in price", "Risk");
_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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
var emaShort = new ExponentialMovingAverage { Length = EmaShort };
var emaLong = new ExponentialMovingAverage { Length = EmaLong };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var bollinger = new BollingerBands { Length = BbLength, Width = BbMultiplier };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(emaShort, emaLong, rsi, bollinger, ProcessCandle)
.Start();
StartProtection(
TakeProfit > 0m ? new Unit(TakeProfit, UnitTypes.Absolute) : new Unit(),
StopLoss > 0m ? new Unit(StopLoss, UnitTypes.Absolute) : new Unit(),
useMarketOrders: true);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, emaShort);
DrawIndicator(area, emaLong);
DrawIndicator(area, bollinger);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
DrawIndicator(oscillators, rsi);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue emaShortValue, IIndicatorValue emaLongValue, IIndicatorValue rsiValue, IIndicatorValue bollingerValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!emaShortValue.IsFormed || !emaLongValue.IsFormed || !rsiValue.IsFormed || !bollingerValue.IsFormed)
return;
if (bollingerValue is not BollingerBandsValue { UpBand: decimal upper, LowBand: decimal lower })
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var fast = emaShortValue.ToDecimal();
var slow = emaLongValue.ToDecimal();
var rsi = rsiValue.ToDecimal();
if (fast > slow && candle.LowPrice <= lower && rsi > RsiOversold && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (fast < slow && candle.HighPrice >= upper && rsi < RsiOverbought && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import ExponentialMovingAverage, RelativeStrengthIndex, BollingerBands
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class aud_usd_scalping_strategy(Strategy):
"""
AUD/USD scalping strategy.
In an uptrend (fast EMA above slow EMA) a candle touching the lower Bollinger Band with RSI above RsiOversold goes long; in a
downtrend a candle touching the upper band with RSI below RsiOverbought goes short, reversing an opposite position. Fixed
price distances TakeProfit and StopLoss close the position.
"""
def __init__(self):
super(aud_usd_scalping_strategy, self).__init__()
self._ema_short = self.Param("EmaShort", 13) \
.SetGreaterThanZero() \
.SetDisplay("EMA Short", "Fast EMA period", "Trend")
self._ema_long = self.Param("EmaLong", 26) \
.SetGreaterThanZero() \
.SetDisplay("EMA Long", "Slow EMA period", "Trend")
self._rsi_period = self.Param("RsiPeriod", 4) \
.SetGreaterThanZero() \
.SetDisplay("RSI Period", "RSI period", "RSI")
self._rsi_overbought = self.Param("RsiOverbought", 70.0) \
.SetDisplay("RSI Overbought", "RSI level shorts must stay below", "RSI")
self._rsi_oversold = self.Param("RsiOversold", 30.0) \
.SetDisplay("RSI Oversold", "RSI level longs must stay above", "RSI")
self._bb_length = self.Param("BbLength", 20) \
.SetGreaterThanZero() \
.SetDisplay("BB Length", "Bollinger Bands period", "Bollinger")
self._bb_multiplier = self.Param("BbMultiplier", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("BB Multiplier", "Bollinger Bands width multiplier", "Bollinger")
self._take_profit = self.Param("TakeProfit", 0.0005) \
.SetNotNegative() \
.SetDisplay("Take Profit", "Take-profit distance in price", "Risk")
self._stop_loss = self.Param("StopLoss", 0.0004) \
.SetNotNegative() \
.SetDisplay("Stop Loss", "Stop-loss distance in price", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def CandleType(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.CandleType)]
def OnStarted2(self, time):
super(aud_usd_scalping_strategy, self).OnStarted2(time)
ema_short = ExponentialMovingAverage()
ema_short.Length = self._ema_short.Value
ema_long = ExponentialMovingAverage()
ema_long.Length = self._ema_long.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
bollinger = BollingerBands()
bollinger.Length = self._bb_length.Value
bollinger.Width = Decimal(self._bb_multiplier.Value)
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(ema_short, ema_long, rsi, bollinger, self._process_candle).Start()
take = float(self._take_profit.Value)
stop = float(self._stop_loss.Value)
self.StartProtection(
Unit(Decimal(take), UnitTypes.Absolute) if take > 0 else Unit(),
Unit(Decimal(stop), UnitTypes.Absolute) if stop > 0 else Unit(),
useMarketOrders=True)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema_short)
self.DrawIndicator(area, ema_long)
self.DrawIndicator(area, bollinger)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
def _process_candle(self, candle, ema_short_value, ema_long_value, rsi_value, bollinger_value):
if candle.State != CandleStates.Finished:
return
if not ema_short_value.IsFormed or not ema_long_value.IsFormed or not rsi_value.IsFormed or not bollinger_value.IsFormed:
return
if bollinger_value.UpBand is None or bollinger_value.LowBand is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
upper = float(bollinger_value.UpBand)
lower = float(bollinger_value.LowBand)
fast = float(to_decimal(ema_short_value))
slow = float(to_decimal(ema_long_value))
rsi = float(to_decimal(rsi_value))
if fast > slow and float(candle.LowPrice) <= lower and rsi > float(self._rsi_oversold.Value) and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif fast < slow and float(candle.HighPrice) >= upper and rsi < float(self._rsi_overbought.Value) and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return aud_usd_scalping_strategy()