Delta RSI 策略
该策略基于 Delta RSI 指标,通过比较两个不同周期的 RSI:
- 快速 RSI 对价格变化反应敏感。
- 慢速 RSI 用于趋势过滤。
当出现 Up 信号后的下一根K线时,如果慢速 RSI 高于 Level 且快速 RSI 高于慢速 RSI,则开多。
当出现 Down 信号后的下一根K线时,如果慢速 RSI 低于 100 - Level 且快速 RSI 低于慢速 RSI,则开空。
可以分别启用或禁用多头和空头的开仓与平仓。
参数
FastPeriod、SlowPeriod、Level、BuyPosOpen、SellPosOpen、BuyPosClose、SellPosClose、CandleType。
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on Delta RSI indicator.
/// </summary>
public class DeltaRsiStrategy : Strategy
{
private readonly StrategyParam<int> _upState;
private readonly StrategyParam<int> _passState;
private readonly StrategyParam<int> _downState;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _level;
private readonly StrategyParam<bool> _buyPosOpen;
private readonly StrategyParam<bool> _sellPosOpen;
private readonly StrategyParam<bool> _buyPosClose;
private readonly StrategyParam<bool> _sellPosClose;
private readonly StrategyParam<DataType> _candleType;
private int _prevColor;
public int UpState
{
get => _upState.Value;
set => _upState.Value = value;
}
public int PassState
{
get => _passState.Value;
set => _passState.Value = value;
}
public int DownState
{
get => _downState.Value;
set => _downState.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public int Level
{
get => _level.Value;
set => _level.Value = value;
}
public bool BuyPosOpen
{
get => _buyPosOpen.Value;
set => _buyPosOpen.Value = value;
}
public bool SellPosOpen
{
get => _sellPosOpen.Value;
set => _sellPosOpen.Value = value;
}
public bool BuyPosClose
{
get => _buyPosClose.Value;
set => _buyPosClose.Value = value;
}
public bool SellPosClose
{
get => _sellPosClose.Value;
set => _sellPosClose.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public DeltaRsiStrategy()
{
_upState = Param(nameof(UpState), 0)
.SetDisplay("Up State", "Value representing bullish state", "Parameters");
_passState = Param(nameof(PassState), 1)
.SetDisplay("Neutral State", "Value representing neutral state", "Parameters");
_downState = Param(nameof(DownState), 2)
.SetDisplay("Down State", "Value representing bearish state", "Parameters");
_fastPeriod = Param(nameof(FastPeriod), 14)
.SetDisplay("Fast RSI Period", "Length of fast RSI", "Parameters");
_slowPeriod = Param(nameof(SlowPeriod), 50)
.SetDisplay("Slow RSI Period", "Length of slow RSI", "Parameters");
_level = Param(nameof(Level), 50)
.SetDisplay("Signal Level", "RSI threshold level", "Parameters");
_buyPosOpen = Param(nameof(BuyPosOpen), true)
.SetDisplay("Open Long", "Allow opening long positions", "Parameters");
_sellPosOpen = Param(nameof(SellPosOpen), true)
.SetDisplay("Open Short", "Allow opening short positions", "Parameters");
_buyPosClose = Param(nameof(BuyPosClose), true)
.SetDisplay("Close Long", "Allow closing long positions", "Parameters");
_sellPosClose = Param(nameof(SellPosClose), true)
.SetDisplay("Close Short", "Allow closing short positions", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_prevColor = PassState;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return new[] {(Security, CandleType)};
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevColor = PassState;
var rsiFast = new RelativeStrengthIndex
{
Length = FastPeriod
};
var rsiSlow = new RelativeStrengthIndex
{
Length = SlowPeriod
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsiFast, rsiSlow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsiFast);
DrawIndicator(area, rsiSlow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiFast, decimal rsiSlow)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var color = PassState;
if (rsiSlow > Level && rsiFast > rsiSlow)
color = UpState;
else if (rsiSlow < 100 - Level && rsiFast < rsiSlow)
color = DownState;
if (_prevColor == UpState && color != UpState)
{
if (SellPosClose && Position < 0)
BuyMarket();
if (BuyPosOpen && Position <= 0)
BuyMarket();
}
else if (_prevColor == DownState && color != DownState)
{
if (BuyPosClose && Position > 0)
SellMarket();
if (SellPosOpen && Position >= 0)
SellMarket();
}
_prevColor = color;
}
}
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
from StockSharp.Algo.Strategies import Strategy
UP_STATE = 0
PASS_STATE = 1
DOWN_STATE = 2
class delta_rsi_strategy(Strategy):
def __init__(self):
super(delta_rsi_strategy, self).__init__()
self._up_state = self.Param("UpState", 0) \
.SetDisplay("Up State", "Value representing bullish state", "Parameters")
self._pass_state = self.Param("PassState", 1) \
.SetDisplay("Neutral State", "Value representing neutral state", "Parameters")
self._down_state = self.Param("DownState", 2) \
.SetDisplay("Down State", "Value representing bearish state", "Parameters")
self._fast_period = self.Param("FastPeriod", 14) \
.SetDisplay("Fast RSI Period", "Length of fast RSI", "Parameters")
self._slow_period = self.Param("SlowPeriod", 50) \
.SetDisplay("Slow RSI Period", "Length of slow RSI", "Parameters")
self._level = self.Param("Level", 50) \
.SetDisplay("Signal Level", "RSI threshold level", "Parameters")
self._buy_pos_open = self.Param("BuyPosOpen", True) \
.SetDisplay("Open Long", "Allow opening long positions", "Parameters")
self._sell_pos_open = self.Param("SellPosOpen", True) \
.SetDisplay("Open Short", "Allow opening short positions", "Parameters")
self._buy_pos_close = self.Param("BuyPosClose", True) \
.SetDisplay("Close Long", "Allow closing long positions", "Parameters")
self._sell_pos_close = self.Param("SellPosClose", True) \
.SetDisplay("Close Short", "Allow closing short positions", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_color = 1
@property
def up_state(self):
return self._up_state.Value
@property
def pass_state(self):
return self._pass_state.Value
@property
def down_state(self):
return self._down_state.Value
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def level(self):
return self._level.Value
@property
def buy_pos_open(self):
return self._buy_pos_open.Value
@property
def sell_pos_open(self):
return self._sell_pos_open.Value
@property
def buy_pos_close(self):
return self._buy_pos_close.Value
@property
def sell_pos_close(self):
return self._sell_pos_close.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(delta_rsi_strategy, self).OnReseted()
self._prev_color = int(self.pass_state)
def OnStarted2(self, time):
super(delta_rsi_strategy, self).OnStarted2(time)
self._prev_color = int(self.pass_state)
rsi_fast = RelativeStrengthIndex()
rsi_fast.Length = int(self.fast_period)
rsi_slow = RelativeStrengthIndex()
rsi_slow.Length = int(self.slow_period)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi_fast, rsi_slow, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, rsi_fast)
self.DrawIndicator(area, rsi_slow)
self.DrawOwnTrades(area)
def process_candle(self, candle, rsi_fast, rsi_slow):
if candle.State != CandleStates.Finished:
return
rsi_fast = float(rsi_fast)
rsi_slow = float(rsi_slow)
lvl = float(self.level)
us = int(self.up_state)
ps = int(self.pass_state)
ds = int(self.down_state)
color = ps
if rsi_slow > lvl and rsi_fast > rsi_slow:
color = us
elif rsi_slow < 100 - lvl and rsi_fast < rsi_slow:
color = ds
if self._prev_color == us and color != us:
if self.sell_pos_close and self.Position < 0:
self.BuyMarket()
if self.buy_pos_open and self.Position <= 0:
self.BuyMarket()
elif self._prev_color == ds and color != ds:
if self.buy_pos_close and self.Position > 0:
self.SellMarket()
if self.sell_pos_open and self.Position >= 0:
self.SellMarket()
self._prev_color = color
def CreateClone(self):
return delta_rsi_strategy()