I am trying to implement a 2 period RSI based strategy backtest in Pine Script. The idea is simple
Objective
The problem
So apparently pine script defaults to taking a long/short position on open of the next candle. But despite placing a market order by specifying the limit attribute the long position is entered at opening price of the next candle.
A few more details
Timeframe - 1Day
Ticker link - https://in.tradingview.com/chart/GDSsFCKq/# (Ticker - SBILIFE (NSE INDIA))
I am not sure what I am doing wrong here. Please help.
Code
//@version=4
strategy("2RSI Strategy by Larry Connor", overlay=true)
rsi_length = input(title="RSI Length", defval=2)
buying_rsi_value = input(title="Buy at RSI Value", defval=5)
selling_rsi_value = input(title="Sell at RSI Value", defval= 40)
price = close
rsi = rsi(price, rsi_length)
buy = crossunder(rsi, buying_rsi_value)
sell = crossover(rsi, selling_rsi_value)
date = tostring(dayofmonth) + '-' + tostring(month) + '-' + tostring(year)
disable_date_ranges = input(title="Disable Date Ranges", defval=true)
start_date = input(title="Start Date", type=input.time, defval=timestamp("19 Oct 2020
00:00 +0530"))
end_date = input(title="End Date", type=input.time, defval=timestamp("18 Oct 2021
00:00 +0530"))
in_date_range = time >= start_date and time < end_date
ema_len = input(200, minval=1, title="EMA Length")
ema_src = input(close, title="EMA Source")
ema_200 = ema(ema_src, ema_len)
entry_condition= buy and ema_200 < price
exit_condition = sell or entry_condition[10]
previous_day_close = close[1]
two_percent_of_prev_day_close = previous_day_close * 0.02
entry_price = previous_day_close - two_percent_of_prev_day_close
// plotchar(entry_condition, "debug", "", location.bottom)
capital_invested = input(title="Invested capital", defval=100000)
initial_capital = strategy.initial_capital
capital_to_be_invested = capital_invested
if(na(capital_invested) or capital_invested == 0)
capital_to_be_invested = initial_capital
if (not na(rsi) and (in_date_range or disable_date_ranges))
strategy.entry("buy", when=entry_condition and low < entry_price, limit=
entry_price, long= true, qty = capital_to_be_invested/entry_price, comment="Long")
if (exit_condition)
strategy.close("buy", true)
To confront this issue is to understand the processing of historical data, which is used in back testing. Historical data is 4 data points per candle (OHLC). Calculations for indicators are made using closing price typically, as well as we don’t have enough information about intra-bar price travel to make assumptions where or when an alert took place. Thus, we must rely on the closing condition for a given candle to establish variable states on the historical bar. In real time, we are confronted with similar issues only that we must wait for close to confirm a signal, or we suffer the affects of repainting. As such, the 2 data types (historical and real time) become aligned as one procedure - a candle close is a confirmed and actionable signal. To establish a closing price a candle would exhaust its last tick for the period. This means that our next actionable sale is the next sale available, which occurs in the first ticks of the bar following. This is why open prices are used in backtesting following a state change of a given variable. If a candle is closed how would we execute an order? As mentioned above, we could forgo this in real time, but to do so is to separate 2 differentiated behaviours of a strategy, which effectively makes the strategy unique, and not one we tested on historical data. Just a few of many caveats of strategy building :)
Cheers!