三线突破策略
该策略利用 Three Line Break 指标来捕捉趋势反转。 指标将当前的最高价和最低价与前 N 根已完成蜡烛的最高点和最低点进行比较。 在下跌趋势中向上突破最近高点表示新一轮上升趋势并开多单;在上升趋势中跌破最近低点则开空单。 每当出现相反信号时,仓位会反向。
细节
- 入场条件:
- 多头:
Downtrend变为Uptrend - 空头:
Uptrend变为Downtrend
- 多头:
- 多/空:双向
- 出场条件:相反信号(反手)
- 止损:无
- 默认值:
LinesBreak= 3CandleType= TimeSpan.FromHours(12).TimeFrame()
- 筛选:
- 分类:趋势跟随
- 方向:双向
- 指标:Highest, Lowest(Three Line Break 逻辑)
- 止损:无
- 复杂度:基础
- 时间框架:波段
- 季节性:无
- 神经网络:无
- 背离:无
- 风险等级:中等
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 the Three Line Break pattern.
/// Detects trend reversals when price breaks above/below recent N-bar high/low.
/// </summary>
public class ThreeLineBreakStrategy : Strategy
{
private readonly StrategyParam<int> _linesBreak;
private readonly StrategyParam<DataType> _candleType;
private Lowest _lowest;
private decimal _prevHigh;
private decimal _prevLow;
private bool _trendUp = true;
public int LinesBreak { get => _linesBreak.Value; set => _linesBreak.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ThreeLineBreakStrategy()
{
_linesBreak = Param(nameof(LinesBreak), 3)
.SetGreaterThanZero()
.SetDisplay("Lines Break", "Number of lines for trend detection", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for analysis", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_lowest = null;
_prevHigh = 0;
_prevLow = 0;
_trendUp = true;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var highest = new Highest { Length = LinesBreak };
_lowest = new Lowest { Length = LinesBreak };
Indicators.Add(_lowest);
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(highest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue highValue)
{
if (candle.State != CandleStates.Finished)
return;
var lowValue = _lowest.Process(highValue);
if (!highValue.IsFormed || !lowValue.IsFormed)
return;
var currentHigh = highValue.GetValue<decimal>();
var currentLow = lowValue.GetValue<decimal>();
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevHigh = currentHigh;
_prevLow = currentLow;
return;
}
if (_prevHigh == 0 || _prevLow == 0)
{
_prevHigh = currentHigh;
_prevLow = currentLow;
return;
}
var trendUp = _trendUp;
if (trendUp && candle.LowPrice < _prevLow)
trendUp = false;
else if (!trendUp && candle.HighPrice > _prevHigh)
trendUp = true;
if (trendUp != _trendUp)
{
if (trendUp && Position <= 0)
BuyMarket();
else if (!trendUp && Position >= 0)
SellMarket();
}
_trendUp = trendUp;
_prevHigh = currentHigh;
_prevLow = currentLow;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class three_line_break_strategy(Strategy):
def __init__(self):
super(three_line_break_strategy, self).__init__()
self._lines_break = self.Param("LinesBreak", 3) \
.SetDisplay("Lines Break", "Number of lines for trend detection", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for analysis", "General")
self._lowest = None
self._prev_high = 0.0
self._prev_low = 0.0
self._trend_up = True
@property
def lines_break(self):
return self._lines_break.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(three_line_break_strategy, self).OnReseted()
self._lowest = None
self._prev_high = 0.0
self._prev_low = 0.0
self._trend_up = True
def OnStarted2(self, time):
super(three_line_break_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self.lines_break
self._lowest = Lowest()
self._lowest.Length = self.lines_break
self.Indicators.Add(self._lowest)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(highest, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawOwnTrades(area)
def process_candle(self, candle, high_value):
if candle.State != CandleStates.Finished:
return
low_value = self._lowest.Process(high_value)
if not high_value.IsFormed or not low_value.IsFormed:
return
current_high = float(high_value)
current_low = float(low_value)
if self._prev_high == 0.0 or self._prev_low == 0.0:
self._prev_high = current_high
self._prev_low = current_low
return
trend_up = self._trend_up
if trend_up and float(candle.LowPrice) < self._prev_low:
trend_up = False
elif not trend_up and float(candle.HighPrice) > self._prev_high:
trend_up = True
if trend_up != self._trend_up:
if trend_up and self.Position <= 0:
self.BuyMarket()
elif not trend_up and self.Position >= 0:
self.SellMarket()
self._trend_up = trend_up
self._prev_high = current_high
self._prev_low = current_low
def CreateClone(self):
return three_line_break_strategy()