Pavan CPR Strategy
Trades long when price crosses above the day's Top Central Pivot Range after previously closing below it. Stop is placed at the pivot level and take profit at a fixed distance.
Details
- Entry Criteria: Previous close below top CPR and current close above it.
- Long/Short: Long only.
- Exit Criteria: Take profit or stop at pivot.
- Stops: Yes.
- Default Values:
TakeProfitTarget= 50CandleType= TimeSpan.FromMinutes(1)
- Filters:
- Category: Breakout
- Direction: Long
- Indicators: Pivot
- Stops: Yes
- Complexity: Basic
- Timeframe: Intraday
- 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>
/// Trades when price crosses above the top Central Pivot Range level.
/// Places take profit at a fixed target and stop loss at the pivot level.
/// </summary>
public class PavanCprStrategy : Strategy
{
private readonly StrategyParam<decimal> _takeProfitTarget;
private readonly StrategyParam<DataType> _candleType;
private decimal _todayPivot;
private decimal _todayTop;
private decimal _lastClose;
private decimal _takeProfitPrice;
private decimal _stopLossPrice;
private decimal _prevSessionHigh;
private decimal _prevSessionLow;
private decimal _prevSessionClose;
private DateTimeOffset _currentDay;
/// <summary>
/// Take profit distance in price points.
/// </summary>
public decimal TakeProfitTarget
{
get => _takeProfitTarget.Value;
set => _takeProfitTarget.Value = value;
}
/// <summary>
/// Candle type used for trading.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes parameters.
/// </summary>
public PavanCprStrategy()
{
_takeProfitTarget = Param(nameof(TakeProfitTarget), 50m)
.SetGreaterThanZero()
.SetDisplay("Take Profit", "Take profit distance in price points", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candles for entry logic", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_todayPivot = 0m;
_todayTop = 0m;
_lastClose = 0m;
_takeProfitPrice = 0m;
_stopLossPrice = 0m;
_prevSessionHigh = 0m;
_prevSessionLow = 0m;
_prevSessionClose = 0m;
_currentDay = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sessionHigh = 0m;
var sessionLow = 0m;
var sessionClose = 0m;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(candle =>
{
if (candle.State != CandleStates.Finished)
return;
var day = candle.OpenTime.Date;
if (_currentDay != day)
{
if (sessionHigh > 0)
{
_prevSessionHigh = sessionHigh;
_prevSessionLow = sessionLow;
_prevSessionClose = sessionClose;
var pivot = (_prevSessionHigh + _prevSessionLow + _prevSessionClose) / 3m;
var top = (_prevSessionHigh + _prevSessionLow) / 2m;
_todayPivot = pivot;
_todayTop = top;
}
sessionHigh = candle.HighPrice;
sessionLow = candle.LowPrice;
_currentDay = day;
}
else
{
sessionHigh = Math.Max(sessionHigh, candle.HighPrice);
sessionLow = Math.Min(sessionLow, candle.LowPrice);
}
sessionClose = candle.ClosePrice;
if (_todayTop == 0m)
{
_lastClose = candle.ClosePrice;
return;
}
if (Position == 0 && _lastClose > 0 && _lastClose < _todayTop && candle.ClosePrice > _todayTop)
{
BuyMarket();
_takeProfitPrice = candle.ClosePrice + TakeProfitTarget;
_stopLossPrice = _todayPivot;
}
else if (Position > 0 && _stopLossPrice > 0)
{
if (candle.LowPrice <= _stopLossPrice || candle.HighPrice >= _takeProfitPrice)
{
SellMarket();
_stopLossPrice = 0m;
_takeProfitPrice = 0m;
}
}
else if (Position < 0)
{
BuyMarket();
}
_lastClose = candle.ClosePrice;
}).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class pavan_cpr_strategy(Strategy):
def __init__(self):
super(pavan_cpr_strategy, self).__init__()
self._take_profit_target = self.Param("TakeProfitTarget", 50.0) \
.SetGreaterThanZero()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._today_pivot = 0.0
self._today_top = 0.0
self._last_close = 0.0
self._take_profit_price = 0.0
self._stop_loss_price = 0.0
self._session_high = 0.0
self._session_low = 0.0
self._session_close = 0.0
self._current_day = None
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(pavan_cpr_strategy, self).OnReseted()
self._today_pivot = 0.0
self._today_top = 0.0
self._last_close = 0.0
self._take_profit_price = 0.0
self._stop_loss_price = 0.0
self._session_high = 0.0
self._session_low = 0.0
self._session_close = 0.0
self._current_day = None
def OnStarted2(self, time):
super(pavan_cpr_strategy, self).OnStarted2(time)
self._today_pivot = 0.0
self._today_top = 0.0
self._last_close = 0.0
self._take_profit_price = 0.0
self._stop_loss_price = 0.0
self._session_high = 0.0
self._session_low = 0.0
self._session_close = 0.0
self._current_day = None
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.OnProcess).Start()
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
day = candle.OpenTime.Date
if self._current_day is None or self._current_day != day:
if self._session_high > 0:
pivot = (self._session_high + self._session_low + self._session_close) / 3.0
top = (self._session_high + self._session_low) / 2.0
self._today_pivot = pivot
self._today_top = top
self._session_high = high
self._session_low = low
self._current_day = day
else:
self._session_high = max(self._session_high, high)
self._session_low = min(self._session_low, low)
self._session_close = close
if self._today_top == 0.0:
self._last_close = close
return
if self.Position == 0 and self._last_close > 0 and self._last_close < self._today_top and close > self._today_top:
self.BuyMarket()
tp = float(self._take_profit_target.Value)
self._take_profit_price = close + tp
self._stop_loss_price = self._today_pivot
elif self.Position > 0 and self._stop_loss_price > 0:
if low <= self._stop_loss_price or high >= self._take_profit_price:
self.SellMarket()
self._stop_loss_price = 0.0
self._take_profit_price = 0.0
elif self.Position < 0:
self.BuyMarket()
self._last_close = close
def CreateClone(self):
return pavan_cpr_strategy()