机器学习 SuperTrend 止盈止损
基于 SuperTrend 指标,并设置跟踪止盈与止损的策略。
止盈与止损随 SuperTrend 线移动,尝试抓住趋势同时在动能减弱时锁定利润。
详情
- 入场条件: 价格穿越 SuperTrend 线。
- 多空方向: 双向。
- 退出条件: 相反信号或触发跟踪止盈/止损。
- 止损: 是,依据 SuperTrend 跟踪。
- 默认值:
AtrPeriod= 4AtrFactor= 2.94mStopLossMultiplier= 0.0025mTakeProfitMultiplier= 0.022mCandleType= TimeSpan.FromMinutes(5)
- 过滤器:
- 类型: 趋势
- 方向: 双向
- 指标: ATR, SuperTrend
- 止损: 是
- 复杂度: 中等
- 时间框架: 日内 (5m)
- 季节性: 无
- 神经网络: 无
- 背离: 无
- 风险等级: 中等
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>
/// SuperTrend strategy with trailing take profit and stop loss.
/// </summary>
public class MachineLearningSuperTrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _atrPeriod;
private readonly StrategyParam<decimal> _atrFactor;
private readonly StrategyParam<decimal> _stopLossMultiplier;
private readonly StrategyParam<decimal> _takeProfitMultiplier;
private readonly StrategyParam<int> _cooldownBars;
private SuperTrend _superTrend;
private int _prevDirection;
private decimal _stopLoss;
private decimal _takeProfit;
private int _barsFromSignal;
/// <summary>
/// Candle type for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// ATR period for SuperTrend calculation.
/// </summary>
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
/// <summary>
/// ATR multiplier for SuperTrend.
/// </summary>
public decimal AtrFactor
{
get => _atrFactor.Value;
set => _atrFactor.Value = value;
}
/// <summary>
/// Stop loss multiplier relative to SuperTrend value.
/// </summary>
public decimal StopLossMultiplier
{
get => _stopLossMultiplier.Value;
set => _stopLossMultiplier.Value = value;
}
/// <summary>
/// Take profit multiplier relative to SuperTrend value.
/// </summary>
public decimal TakeProfitMultiplier
{
get => _takeProfitMultiplier.Value;
set => _takeProfitMultiplier.Value = value;
}
/// <summary>
/// Minimum bars between trade actions.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Initialize strategy parameters.
/// </summary>
public MachineLearningSuperTrendStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(10).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_atrPeriod = Param(nameof(AtrPeriod), 4)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR length for SuperTrend", "SuperTrend")
.SetOptimize(3, 20, 1);
_atrFactor = Param(nameof(AtrFactor), 2.94m)
.SetRange(0.5m, 10m)
.SetDisplay("Multiplier", "ATR multiplier for SuperTrend", "SuperTrend")
.SetOptimize(1m, 5m, 0.5m);
_stopLossMultiplier = Param(nameof(StopLossMultiplier), 0.01m)
.SetRange(0m, 0.05m)
.SetDisplay("Stop Loss Mult", "Percentage from SuperTrend", "Risk Management");
_takeProfitMultiplier = Param(nameof(TakeProfitMultiplier), 0.03m)
.SetRange(0m, 0.1m)
.SetDisplay("Take Profit Mult", "Percentage from SuperTrend", "Risk Management");
_cooldownBars = Param(nameof(CooldownBars), 8)
.SetGreaterThanZero()
.SetDisplay("Cooldown Bars", "Bars between trade actions", "Risk Management");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_superTrend = null;
_prevDirection = 0;
_stopLoss = 0;
_takeProfit = 0;
_barsFromSignal = CooldownBars;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_barsFromSignal = CooldownBars;
_superTrend = new SuperTrend
{
Length = AtrPeriod,
Multiplier = AtrFactor
};
var dummyEma1 = new ExponentialMovingAverage { Length = 10 };
var dummyEma2 = new ExponentialMovingAverage { Length = 20 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(dummyEma1, dummyEma2, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _superTrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal d1, decimal d2)
{
if (candle.State != CandleStates.Finished)
return;
var stResult = _superTrend.Process(new CandleIndicatorValue(_superTrend, candle));
if (!_superTrend.IsFormed || stResult.IsEmpty)
return;
var superTrendValue = stResult.GetValue<decimal>();
var direction = candle.ClosePrice > superTrendValue ? 1 : -1;
var directionChanged = _prevDirection != 0 && direction != _prevDirection;
_barsFromSignal++;
var canTradeNow = _barsFromSignal >= CooldownBars;
_stopLoss = direction == 1
? superTrendValue - superTrendValue * StopLossMultiplier
: superTrendValue + superTrendValue * StopLossMultiplier;
_takeProfit = direction == 1
? superTrendValue + superTrendValue * TakeProfitMultiplier
: superTrendValue - superTrendValue * TakeProfitMultiplier;
if (canTradeNow && directionChanged)
{
if (direction == 1 && Position <= 0)
BuyMarket();
else if (direction == -1 && Position >= 0)
SellMarket();
_barsFromSignal = 0;
}
if (canTradeNow && Position > 0)
{
if (candle.ClosePrice <= _stopLoss || candle.ClosePrice >= _takeProfit)
{
SellMarket();
_barsFromSignal = 0;
}
}
else if (canTradeNow && Position < 0)
{
if (candle.ClosePrice >= _stopLoss || candle.ClosePrice <= _takeProfit)
{
BuyMarket();
_barsFromSignal = 0;
}
}
_prevDirection = direction;
}
}
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 SuperTrend, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class machine_learning_super_trend_strategy(Strategy):
"""
SuperTrend strategy with trailing take profit and stop loss.
"""
def __init__(self):
super(machine_learning_super_trend_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 4).SetDisplay("ATR Period", "ATR length for SuperTrend", "SuperTrend")
self._atr_factor = self.Param("AtrFactor", 2.94).SetDisplay("Multiplier", "ATR multiplier", "SuperTrend")
self._stop_loss_mult = self.Param("StopLossMultiplier", 0.01).SetDisplay("Stop Loss Mult", "Pct from SuperTrend", "Risk")
self._take_profit_mult = self.Param("TakeProfitMultiplier", 0.03).SetDisplay("Take Profit Mult", "Pct from SuperTrend", "Risk")
self._cooldown_bars = self.Param("CooldownBars", 8).SetDisplay("Cooldown", "Bars between trades", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(10))).SetDisplay("Candle Type", "Candles", "General")
self._super_trend = None
self._prev_direction = 0
self._stop_loss = 0.0
self._take_profit = 0.0
self._bars_from_signal = 8
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(machine_learning_super_trend_strategy, self).OnReseted()
self._super_trend = None
self._prev_direction = 0
self._stop_loss = 0.0
self._take_profit = 0.0
self._bars_from_signal = self._cooldown_bars.Value
def OnStarted2(self, time):
super(machine_learning_super_trend_strategy, self).OnStarted2(time)
self._bars_from_signal = self._cooldown_bars.Value
self._super_trend = SuperTrend()
self._super_trend.Length = self._atr_period.Value
self._super_trend.Multiplier = self._atr_factor.Value
dummy1 = ExponentialMovingAverage()
dummy1.Length = 10
dummy2 = ExponentialMovingAverage()
dummy2.Length = 20
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(dummy1, dummy2, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, self._super_trend)
self.DrawOwnTrades(area)
def _process_candle(self, candle, d1, d2):
if candle.State != CandleStates.Finished:
return
from StockSharp.Algo.Indicators import CandleIndicatorValue
st_result = self._super_trend.Process(CandleIndicatorValue(self._super_trend, candle))
if not self._super_trend.IsFormed or st_result.IsEmpty:
return
st_val = float(st_result)
close = float(candle.ClosePrice)
direction = 1 if close > st_val else -1
direction_changed = self._prev_direction != 0 and direction != self._prev_direction
self._bars_from_signal += 1
can_trade = self._bars_from_signal >= self._cooldown_bars.Value
sl_m = float(self._stop_loss_mult.Value)
tp_m = float(self._take_profit_mult.Value)
self._stop_loss = st_val - st_val * sl_m if direction == 1 else st_val + st_val * sl_m
self._take_profit = st_val + st_val * tp_m if direction == 1 else st_val - st_val * tp_m
if can_trade and direction_changed:
if direction == 1 and self.Position <= 0:
self.BuyMarket()
elif direction == -1 and self.Position >= 0:
self.SellMarket()
self._bars_from_signal = 0
if can_trade and self.Position > 0:
if close <= self._stop_loss or close >= self._take_profit:
self.SellMarket()
self._bars_from_signal = 0
elif can_trade and self.Position < 0:
if close >= self._stop_loss or close <= self._take_profit:
self.BuyMarket()
self._bars_from_signal = 0
self._prev_direction = direction
def CreateClone(self):
return machine_learning_super_trend_strategy()