This strategy triggers market orders when price crosses predefined horizontal levels. The user specifies separate levels for long and short entries and risk parameters in pips. After opening a position the strategy tracks stop loss, take profit and optional trailing stop.
The system suits discretionary setups where entry levels are known in advance. It works on any instrument and timeframe because it relies only on price levels.
Details
Entry Criteria:
Long: Close price crosses above BuyPrice.
Short: Close price crosses below SellPrice.
Long/Short: Both sides.
Exit Criteria:
Stop-loss at StopLossPips.
Take-profit at TakeProfitPips.
Trailing stop if TrailingStopPips > 0.
Stops: Yes, in pips.
Default Values:
BuyPrice = 0 (disabled)
SellPrice = 0 (disabled)
TakeProfitPips = 30
StopLossPips = 20
TrailingStopPips = 0
CandleType = TimeSpan.FromMinutes(1)
Filters:
Category: Manual
Direction: Both
Indicators: None
Stops: Yes
Complexity: Basic
Timeframe: Any
Seasonality: No
Neural Networks: No
Divergence: No
Risk Level: Medium
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>
/// Line order strategy using SMA as dynamic support/resistance levels.
/// </summary>
public class MyLineOrderStrategy : Strategy
{
private readonly StrategyParam<int> _smaLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevSma;
private bool _hasPrev;
public int SmaLength { get => _smaLength.Value; set => _smaLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MyLineOrderStrategy()
{
_smaLength = Param(nameof(SmaLength), 14)
.SetGreaterThanZero()
.SetDisplay("SMA", "SMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevSma = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sma)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevClose = close;
_prevSma = sma;
_hasPrev = true;
return;
}
// Cross above SMA
if (_prevClose <= _prevSma && close > sma)
{
if (Position < 0) BuyMarket();
if (Position <= 0) BuyMarket();
}
// Cross below SMA
else if (_prevClose >= _prevSma && close < sma)
{
if (Position > 0) SellMarket();
if (Position >= 0) SellMarket();
}
_prevClose = close;
_prevSma = sma;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class my_line_order_strategy(Strategy):
def __init__(self):
super(my_line_order_strategy, self).__init__()
self._sma_length = self.Param("SmaLength", 14) \
.SetDisplay("SMA", "SMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_close = 0.0
self._prev_sma = 0.0
self._has_prev = False
@property
def sma_length(self):
return self._sma_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(my_line_order_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_sma = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(my_line_order_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = self.sma_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, sma):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
if not self._has_prev:
self._prev_close = close
self._prev_sma = sma
self._has_prev = True
return
# Cross above SMA
if self._prev_close <= self._prev_sma and close > sma:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
# Cross below SMA
elif self._prev_close >= self._prev_sma and close < sma:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_sma = sma
def CreateClone(self):
return my_line_order_strategy()