Intra Bullish Strategy - Profit Ping v4.0 策略
仅做多系统,使用EMA金叉并由MACD柱状图和RSI强度确认。
细节
- 入场条件:
- 短期EMA上穿长期EMA
- MACD柱状图 > 0
- RSI > 50
- 收盘价高于开盘价
- 出场条件:
- 短期EMA下穿长期EMA
- MACD柱状图 < 0
- RSI < 50
- 收盘价低于开盘价
- 指标:
- 指数移动平均
- MACD
- RSI
- 止损:无。
- 默认值:
ShortEmaLength= 7LongEmaLength= 14RsiLength= 14MacdFastPeriod= 12MacdSlowPeriod= 26MacdSignalPeriod= 9
- 过滤器:
- 趋势跟随
- 单一时间框架
- 指标:EMA、MACD、RSI
- 止损:无
- 复杂度:低
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>
/// Intra Bullish Strategy - Profit Ping v4.0.
/// Long only. A long opens when the short EMA crosses above the long EMA on a candle where the MACD histogram is positive, RSI is above 50
/// and the candle closes above its open. The position closes when the short EMA crosses below the long EMA with a negative histogram,
/// RSI below 50 and a candle closing below its open. There are no stops.
/// </summary>
public class IntraBullishProfitPingV40Strategy : Strategy
{
private readonly StrategyParam<int> _shortEmaLength;
private readonly StrategyParam<int> _longEmaLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<int> _macdFast;
private readonly StrategyParam<int> _macdSlow;
private readonly StrategyParam<int> _macdSignal;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevShort;
private decimal? _prevLong;
/// <summary>
/// Short EMA length.
/// </summary>
public int ShortEmaLength
{
get => _shortEmaLength.Value;
set => _shortEmaLength.Value = value;
}
/// <summary>
/// Long EMA length.
/// </summary>
public int LongEmaLength
{
get => _longEmaLength.Value;
set => _longEmaLength.Value = value;
}
/// <summary>
/// RSI length.
/// </summary>
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
/// <summary>
/// MACD fast period.
/// </summary>
public int MacdFastPeriod
{
get => _macdFast.Value;
set => _macdFast.Value = value;
}
/// <summary>
/// MACD slow period.
/// </summary>
public int MacdSlowPeriod
{
get => _macdSlow.Value;
set => _macdSlow.Value = value;
}
/// <summary>
/// MACD signal period.
/// </summary>
public int MacdSignalPeriod
{
get => _macdSignal.Value;
set => _macdSignal.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public IntraBullishProfitPingV40Strategy()
{
_shortEmaLength = Param(nameof(ShortEmaLength), 7)
.SetGreaterThanZero()
.SetDisplay("Short EMA", "Short EMA length", "EMA");
_longEmaLength = Param(nameof(LongEmaLength), 14)
.SetGreaterThanZero()
.SetDisplay("Long EMA", "Long EMA length", "EMA");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "RSI");
_macdFast = Param(nameof(MacdFastPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("MACD Fast", "MACD fast period", "MACD");
_macdSlow = Param(nameof(MacdSlowPeriod), 26)
.SetGreaterThanZero()
.SetDisplay("MACD Slow", "MACD slow period", "MACD");
_macdSignal = Param(nameof(MacdSignalPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("MACD Signal", "MACD signal period", "MACD");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(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 OnReseted()
{
base.OnReseted();
_prevShort = null;
_prevLong = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevShort = null;
_prevLong = null;
var emaShort = new ExponentialMovingAverage { Length = ShortEmaLength };
var emaLong = new ExponentialMovingAverage { Length = LongEmaLength };
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var macd = new MovingAverageConvergenceDivergenceSignal
{
Macd = { ShortMa = { Length = MacdFastPeriod }, LongMa = { Length = MacdSlowPeriod } },
SignalMa = { Length = MacdSignalPeriod }
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(emaShort, emaLong, rsi, macd, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, emaShort);
DrawIndicator(area, emaLong);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, rsi);
DrawIndicator(oscillators, macd);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue emaShortValue, IIndicatorValue emaLongValue, IIndicatorValue rsiValue, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!emaShortValue.IsFormed || !emaLongValue.IsFormed)
return;
var emaShort = emaShortValue.GetValue<decimal>();
var emaLong = emaLongValue.GetValue<decimal>();
var prevShort = _prevShort;
var prevLong = _prevLong;
_prevShort = emaShort;
_prevLong = emaLong;
if (prevShort is not decimal ps || prevLong is not decimal pl)
return;
if (!rsiValue.IsFormed || !macdValue.IsFormed || macdValue is not MovingAverageConvergenceDivergenceSignalValue { Macd: decimal macd, Signal: decimal signal })
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var rsi = rsiValue.GetValue<decimal>();
var histogram = macd - signal;
var crossUp = ps <= pl && emaShort > emaLong;
var crossDown = ps >= pl && emaShort < emaLong;
if (Position <= 0 && crossUp && histogram > 0 && rsi > 50m && candle.ClosePrice > candle.OpenPrice)
BuyMarket(Volume + Math.Abs(Position));
else if (Position > 0 && crossDown && histogram < 0 && rsi < 50m && candle.ClosePrice < candle.OpenPrice)
SellMarket(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
from StockSharp.Algo.Indicators import ExponentialMovingAverage, RelativeStrengthIndex, MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
class intra_bullish_profit_ping_v4_0_strategy(Strategy):
"""
Intra Bullish Strategy - Profit Ping v4.0.
Long only. A long opens when the short EMA crosses above the long EMA on a candle where the MACD histogram is positive, RSI is above 50
and the candle closes above its open. The position closes when the short EMA crosses below the long EMA with a negative histogram,
RSI below 50 and a candle closing below its open. There are no stops.
"""
def __init__(self):
super(intra_bullish_profit_ping_v4_0_strategy, self).__init__()
self._short_ema_length = self.Param("ShortEmaLength", 7).SetGreaterThanZero().SetDisplay("Short EMA", "Short EMA length", "EMA")
self._long_ema_length = self.Param("LongEmaLength", 14).SetGreaterThanZero().SetDisplay("Long EMA", "Long EMA length", "EMA")
self._rsi_length = self.Param("RsiLength", 14).SetGreaterThanZero().SetDisplay("RSI Length", "RSI period", "RSI")
self._macd_fast = self.Param("MacdFastPeriod", 12).SetGreaterThanZero().SetDisplay("MACD Fast", "MACD fast period", "MACD")
self._macd_slow = self.Param("MacdSlowPeriod", 26).SetGreaterThanZero().SetDisplay("MACD Slow", "MACD slow period", "MACD")
self._macd_signal = self.Param("MacdSignalPeriod", 9).SetGreaterThanZero().SetDisplay("MACD Signal", "MACD signal period", "MACD")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_short = None
self._prev_long = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(intra_bullish_profit_ping_v4_0_strategy, self).OnReseted()
self._prev_short = None
self._prev_long = None
def OnStarted2(self, time):
super(intra_bullish_profit_ping_v4_0_strategy, self).OnStarted2(time)
self._prev_short = None
self._prev_long = None
ema_short = ExponentialMovingAverage()
ema_short.Length = self._short_ema_length.Value
ema_long = ExponentialMovingAverage()
ema_long.Length = self._long_ema_length.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_length.Value
macd = MovingAverageConvergenceDivergenceSignal()
macd.Macd.ShortMa.Length = self._macd_fast.Value
macd.Macd.LongMa.Length = self._macd_slow.Value
macd.SignalMa.Length = self._macd_signal.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(ema_short, ema_long, rsi, macd, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema_short)
self.DrawIndicator(area, ema_long)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
self.DrawIndicator(oscillators, macd)
def _process_candle(self, candle, ema_short_value, ema_long_value, rsi_value, macd_value):
if candle.State != CandleStates.Finished:
return
if not ema_short_value.IsFormed or not ema_long_value.IsFormed:
return
ema_short = ema_short_value.GetValue[Decimal](None)
ema_long = ema_long_value.GetValue[Decimal](None)
prev_short = self._prev_short
prev_long = self._prev_long
self._prev_short = ema_short
self._prev_long = ema_long
if prev_short is None or prev_long is None:
return
if not rsi_value.IsFormed or not macd_value.IsFormed or macd_value.Macd is None or macd_value.Signal is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
rsi = rsi_value.GetValue[Decimal](None)
histogram = macd_value.Macd - macd_value.Signal
cross_up = prev_short <= prev_long and ema_short > ema_long
cross_down = prev_short >= prev_long and ema_short < ema_long
if self.Position <= 0 and cross_up and histogram > 0 and rsi > 50 and candle.ClosePrice > candle.OpenPrice:
self.BuyMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and cross_down and histogram < 0 and rsi < 50 and candle.ClosePrice < candle.OpenPrice:
self.SellMarket(self.Position)
def CreateClone(self):
return intra_bullish_profit_ping_v4_0_strategy()