strategy.position_avg_price returns "NaN" on alert when triggered in Pinescript - view

My code on trading view pine script is returning me "NaN" for strategy.position_avg_price when alert is triggered.
It works when I back test it. However when I test it live, it is giving me "NaN" value.
Alert message with "NaN" message
I am trying to place a stop loss using strategy.position_avg_price mins or plus nLoss
However, strategy.position_avg_price keeps returning me "NaN" when alert is triggered after I enter the trade.
This is how I define my stop-loss value
//Define stop loss levels for long position
long_stop_level := strategy.position_avg_price - nLoss//close-nLoss
This is how I enter a trade.
//Enters long trade
if entry_long
alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize)
alert(alert_string, alert.freq_once_per_bar_close)
I expect strategy.position_avg_price to return the correct value just as I had backtested it.
This is how my alert setting is.
Alert setting on tradingview
I am willing to pay a small amount for the correct solution.
Sharing my entire code here so that u guys can backtest it yourself. Run this on 1 minute chart and set alert:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//#version=5
strategy('Testing Alert for NaN error', overlay=true, currency=currency.USD, initial_capital=10000, slippage=15)
//==============================================================================
//==============================================================================
//BACKTEST DATE RANGE - Select Dates
//==============================================================================
//Input for date window
startDay = input.int(defval=9, title='Start Day', minval=1, maxval=31)
startMonth = input.int(defval=1, title='Start Month', minval=1, maxval=12)
startYear = input.int(defval=2023, title='Start Year', minval=1970)
endDay = input.int(defval=1, title='End Day', minval=1, maxval=31)
endMonth = input.int(defval=1, title='End Month', minval=1, maxval=12)
endYear = input.int(defval=2025, title='End Year', minval=1970)
//Submit date window
startDate = timestamp(startYear, startMonth, startDay, 00, 00, 00) // backtest start date
endDate = timestamp(endYear, endMonth, endDay, 23, 59, 59) // backtest end date
dateRange() => // specify where date range is true
time >= startDate and time <= endDate ? true : false
//==============================================================================
//==============================================================================
//MONEY MANAGEMENT - ATR (Take profit at 1.0 ATR and Stop Loss at 1.5 ATR)
//==============================================================================
//Enter intial capital and percentage risk inputs
percentRisk = input.float(title='Risk Per Trade', defval=0.1, minval=0.001, maxval=0.1)
//Enter ATR inputs
atrLength = input(title='atr' , defval=10)
atrMulti_Profit = input(title='Atr Profit Multiple', defval=1.0)
atrMulti_Loss = input(title='Atr Loss Multiple', defval=20)
//ATR function
truncate(number, decimals) =>
factor = math.pow(10, decimals)
int(number * factor) / factor
atr = truncate(ta.atr(atrLength), 5)
//Get position size
posSize = math.round(strategy.initial_capital * percentRisk / (atrMulti_Loss * atr))*0.01
//==============================================================================
//==============================================================================
//INDICATOR 1 - Trigger (C1 - Confirmation 1)
//==============================================================================
//Donchian Channel
basePeriods = input.int(5, minval=1, title='Base Line Length')
donchian(len) =>
math.avg(ta.lowest(len), ta.highest(len))
IchimokubaseLine = donchian(basePeriods)
plot(IchimokubaseLine, color=color.new(color.white, 0), title='Ichimoku baseline')
Ind_1_L = close > IchimokubaseLine[1]
Ind_1_S = close < IchimokubaseLine[1]
//==============================================================================
//==============================================================================
//ENTRY CONDITIONS - Submit Orders
//==============================================================================
//Asks user if want to include Long/Short trigger condition
ShortSignal = input(false, 'Tick to include Short Trades?')
//Long and short strategy conditions
entry_long = strategy.position_size <= 0 and dateRange() and Ind_1_L
entry_short = strategy.position_size >= 0 and dateRange() and Ind_1_S and ShortSignal
plotshape(entry_long, color=color.new(color.lime, 0), style=shape.arrowup, location=location.belowbar, text='Buy')
plotshape(entry_short, color=color.new(color.red, 0), style=shape.arrowdown, location=location.abovebar, text='Sell')
//Store ATR and Price upon entry of trade.
entry_atr = float(0.0) //set float
entry_atr := strategy.position_size == 0 or entry_long or entry_short ? atr : entry_atr[1]
alertcondition(close >= open, title='Alert on Green Bar', message='Green Bar!')
//Submit long and short orders based on entry conditions
if entry_long
strategy.entry(id='Long Entry 1', direction=strategy.long, qty=posSize, when=dateRange())
if entry_short
strategy.entry(id='Short Entry 1', direction=strategy.short, qty=posSize, when=dateRange())
//==============================================================================
//==============================================================================
//TAKE PROFIT & STOP LOSS VALUES
//==============================================================================
//Calculate stop loss and take profit distance (in price)
nLoss = entry_atr * atrMulti_Loss
//Find long take profit and stop loss levels
long_stop_level = float(0.0) //set float
long_stop_level := strategy.position_avg_price - nLoss//close-nLoss
//Find short take profit and stop loss levels
short_stop_level = float(0.0) //set float
short_stop_level := strategy.position_avg_price + nLoss//close+nLoss
plotchar(strategy.position_avg_price , 'Strategy Position Avg_Price', '', location=location.top)
plotchar(strategy.position_avg_price[1] , 'Strategy Position Avg_Price[1]', '', location=location.top)
plotchar(strategy.opentrades , 'Strategy Open Trade', '', location=location.top)
//Plot stop loss and profit level on graph; hide levels when no trade
plot(strategy.position_size <= 0 or entry_long or entry_short ? na : long_stop_level, color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size >= 0 or entry_long or entry_short ? na : short_stop_level, color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2)
//==============================================================================
//==============================================================================
//==============================================================================
//ALERT CONDITIONS - For Autotrading (pineconnector)
//==============================================================================
// PineConnector Settings
pc_id = input.string(title='License ID', defval='6608763584725', group='PineConnector Settings', tooltip='This is your PineConnector license ID')
pc_prefix = input.string(title='MetaTrader Prefix', defval='', group='PineConnector Settings', tooltip='This is your broker\'s MetaTrader symbol prefix')
pc_suffix = input.string(title='MetaTrader Suffix', defval='', group='PineConnector Settings', tooltip='This is your broker\'s MetaTrader symbol suffix')
pc_limit = input.bool(title='Use Limit Order?', defval=true, group='PineConnector Settings', tooltip='If true a limit order will be used, if false a market order will be used')
//pc_spread = input(title="Spread (Broker comm)", defval=1, type=input.float, group="PineConnector Settings", tooltip="This is your broker's spread where they earn commissions")
// Generate PineConnector alert string
plotchar(long_stop_level, 'Long_Stop_Level', '', location=location.top)
plotchar(short_stop_level, 'Short_Stop_Level', '', location=location.top)
plotchar(Ind_1_S, 'Donchain Short', '', location=location.top)
plotchar(Ind_1_L, 'Donchain Long', '', location=location.top)
//pc_entry_alert(direction, price, sl, tp) =>
//pc_id + "," + direction + "," + symbol + "," + price + "sl=" + tostring(sl) + ",tp=" + tostring(tp) + ",risk=" + tostring(posSize)
//pc_id + "," + direction + "," + symbol + "," + price + "sl=" + tostring(sl) + "risk=" + tostring(pc_risk)
//sl_inp = ta.sma(close,5)
//stop_level = (strategy.position_avg_price == "NaN") ? (close * (1 - sl_inp)) : (strategy.position_avg_price * (1 - sl_inp))
var symbol = pc_prefix + syminfo.ticker + pc_suffix
//Close short position once Ind_1_L is triggered
if Ind_1_L and strategy.position_size<0
alert_stringCloseShort = pc_id + ',' + 'closeshort' + ',' + symbol
alert(alert_stringCloseShort, alert.freq_once_per_bar_close)
//Enters long trade
if entry_long
alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize)
alert(alert_string, alert.freq_once_per_bar_close)
//Close Long position once Ind_1_S is triggered
if Ind_1_S and strategy.position_size>0
alert_stringCloseLong = pc_id + ',' + 'closelong' + ',' + symbol
alert(alert_stringCloseLong, alert.freq_once_per_bar_close)
//Enters short trade
if entry_short
alert_string = pc_id + ',' + 'sell' + ',' + symbol + ',' + 'sl=' + str.tostring(short_stop_level) + ',' + 'risk=' + str.tostring(posSize)
alert(alert_string, alert.freq_once_per_bar_close)
//==============================================================================
//EXIT CONDITIONS - Submit Orders
//==============================================================================
//Submit exit orders on static profit and loss (Exits based on the stoploss set)
strategy.exit('TP/SL 1', 'Long Entry 1', stop=long_stop_level, limit=na)
strategy.exit('TP/SL 1', 'Short Entry 1', stop=short_stop_level, limit=na)
strategy.exit('TP/SL 2', 'Long Entry 2', stop=long_stop_level, limit=na)
strategy.exit('TP/SL 2', 'Short Entry 2', stop=short_stop_level, limit=na)
//Submit exit orders on exit indicator - Exit 1 & 2 (Exits based on our indicator)
strategy.close(id='Long Entry 1', comment='Exit 1 L1', when=Ind_1_S and dateRange())
strategy.close(id='Short Entry 1', comment='Exit 1 S1', when=Ind_1_L and dateRange())
//==============================================================================

The reason of the error is simple. When you call strategy.entry the position will not immediatelly opened. The script engine just send entry order and the position will be opened on next script update. Only on this update there are strategy.position_avg_price will be not NaN.
You can try to use different condition for issue the alert:
//Enters long trade
if strategy.position_size[1] <= 0 and strategy.position_size > 0
alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize)
strategy.entry(id='Long Entry 1', direction=strategy.long, qty=posSize, when=dateRange(), alert_message = alert_string)

Related

anyone help i not able to trigger buy and sell alert in plotting trendline

plotting the two trend lines
need buy and sell alert or strategy buy or strategy sell, if candle closes above trend line buy and if candle closes below trendline sell
color_high1 = slope_high1 * time<0 ? color.red : na
color_low1 = slope_low1 * time>0 ? color.lime : na
plot(tlmod ? high_point1 : na, color=color_high1, offset=-l1/2, linewidth=2)
plot(tlmod ? low_point1 : na, color=color_low1, offset=-l1/2, linewidth=2)
if crossover(close,high_point1 )
strategy.entry('My Long Entry Id', strategy.long)
alert(tostring(LicenseID)+',buy,' + syminfo.ticker + ',sl=' + tostring(high_point1) + ',risk=' + tostring(riskvalue),alert.freq_all)
if crossunder(close,low_point1)
strategy.entry('My Short Entry Id', strategy.short)
alert(tostring(LicenseID)+',sell,' + syminfo.ticker + ',sl=' + tostring(low_point1) + ',risk=' + tostring(riskvalue),alert.freq_all)

Laravel 7: How to add numeric value with date?

I'm calculating the difference between two dates. I want to make addition/subtraction a numeric/decimal value with the date.
Example:
Start = 2022-06-28
end = 2022-06-29
total= (start - 0.5) - ( end - 0)
= 1.5
or
total= (start - 0) - ( end - 0)
= 2
or
total= (start - 0.5) - ( end - 0.5)
= 1
Code:
$second_half = $request->session_1; // value = 0.5
$first_half = $request->session_2; // value = 0.5
$start = Carbon::parse($request->start_date); // value (YYYY-MM-DD) = 2022-06-28
$end = Carbon::parse($request->end_date); // value (YYYY-MM-DD) = 2022-06-29
$total_days = $end->diff($start); // this result can be decimal like 1.5
Actually, I want to divide the full day into two-part. First half and second half. So when I calculating the difference between two dates it should calculate the full day by (first half + second half). If I select 2022-06-28 first half and 2022-06-29 second half, it will count 2 days. If I select 2022-06-28 first half and 2022-06-29 first half, it will count 1.5 days.
I hope my concept is clear to you. How can I make this calculation?
Can you test please the followind code?
$startDate = '2022-06-28';
$endDate = '2022-06-29';
$second_half = 0.5;
$first_half = 0.5;
$start = \Carbon\Carbon::parse($startDate);
$end = \Carbon\Carbon::parse($endDate);
$total_days = (float) $end->diff($start)->days;
if($first_half) {
$total_days += $first_half;
}
if ($second_half) {
$total_days += $second_half;
}
$total_days = preg_replace('/\\.$/','.0',rtrim($total_days,'0'));
// dd($total_days);
$second_half = $request->session_1; // value = 0.5
$first_half = $request->session_2; // value = 0.5
$start = Carbon::parse($request->start_date . ($first_half ? ' 12:00' : ' 00:00'));
$end = $second_half
? Carbon::parse($request->end_date . ' 12:00')
: Carbon::parse($request->end_date)->addDay();
$total_days = $end->floatDiffInDays($start);

Tradingview Pine-Script: How to plot only the last x periods

I'd like to plot an indicator only for the last x periods.
How do I do that?
If I could do time operations (substract x * period from plotStartDate), maybe I could use this code:
period = timeframe.ismonthly or timeframe.isweekly ? "12M" : "M"
plotStartDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow), 00, 00)
isPlotDate = time >= plotStartDate
plot(isPlotDate ? mydata : na, color=mydata != mydata[1]:na, style=plot.style_line, linewidth=2)
Version 1
Not sure this is what you're looking for. It uses plot()'s show_last= parameter to restrict the number of last bars plotted after your isPlotDate constraint has been satisfied:
//#version=4
study("", "", true)
xPeriods = input(10)
plotStartDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow), 00, 00)
isPlotDate = time >= plotStartDate
plot(isPlotDate ? close : na, show_last = xPeriods)
Version 2
//#version=4
study("Plot starting n months back", "", true)
monthsBack = input(3, minval = 0)
monthsExtra = monthsBack % 12
monthsExcedent = month(timenow) - monthsExtra
yearsBack = floor(monthsBack / 12) + (monthsExcedent <= 0 ? 1 : 0)
targetMonth = monthsExcedent <= 0 ? 12 + monthsExcedent : monthsExcedent
targetYearMonth = year == year(timenow) - yearsBack and month == targetMonth
beginMonth = not targetYearMonth[1] and targetYearMonth
var float valueToPlot = na
if beginMonth
valueToPlot := high
plot(valueToPlot)
bgcolor(beginMonth ? color.green : na)
Version 3
Simpler:
//#version=4
study("Plot starting n months back", "", true)
monthsBack = input(3, minval = 0)
targetDate = time >= timestamp(year(timenow), month(timenow) - monthsBack, 1, 0, 0, 0)
beginMonth = not targetDate[1] and targetDate
var float valueToPlot = na
if beginMonth
valueToPlot := high
plot(valueToPlot)
bgcolor(beginMonth ? color.green : na)
Version 4
At v4 you can set the variable show_last in the plot() function.
In "PineScript language reference manual" says:
show_last (input integer) If set, defines the number of bars (from the
last bar back to the past) to plot on chart.
https://www.tradingview.com/pine-script-reference/#fun_plot

How to parse a time in years in QBasic

How to parse a time (month/date/year) in Microsoft QBasic, needed for testing.
s = 'PT1H28M26S'
I would like to get:
num_mins = 88
You can parse such a time string with the code below, but the real question is:
Who still uses QBasic in 2015!?
CLS
s$ = "PT1H28M26S"
' find the key characters in string
posP = INSTR(s$, "PT")
posH = INSTR(s$, "H")
posM = INSTR(s$, "M")
posS = INSTR(s$, "S")
' if one of values is zero, multiplying all will be zero
IF ((posP * posH * posM * posS) = 0) THEN
' one or more key characters are missing
nummins = -1
numsecs = -1
ELSE
' get values as string
sHour$ = MID$(s$, posP + 2, (posH - posP - 2))
sMin$ = MID$(s$, posH + 1, (posM - posH - 1))
sSec$ = MID$(s$, posM + 1, (posS - posM - 1))
' string to integer, so we can calculate
iHour = VAL(sHour$)
iMin = VAL(sMin$)
iSec = VAL(sSec$)
' calculate totals
nummins = (iHour * 60) + iMin
numsecs = (iHour * 60 * 60) + (iMin * 60) + iSec
END IF
' display results
PRINT "Number of minutes: "; nummins
PRINT "Number of seconds: "; numsecs
PRINT "QBasic in 2015! w00t?!"
Simpler way to grab minutes from string in qbasic
REM Simpler way to grab minutes from string in qbasic
S$ = "PT1H28M26S"
S$ = MID$(S$, 3) ' 1H28M26S
V = INSTR(S$, "H") ' position
H = VAL(LEFT$(S$, V - 1)) ' hours
S$ = MID$(S$, V + 1) ' 28M26S
V = INSTR(S$, "M") ' position
M = VAL(LEFT$(S$, V - 1)) ' minutes
PRINT "num_mins ="; H * 60 + M

Can someone help me vectorize / speed up this Matlab Loop?

correlation = zeros(length(s1), 1);
sizeNum = 0;
for i = 1 : length(s1) - windowSize - delta
s1Dat = s1(i : i + windowSize);
s2Dat = s2(i + delta : i + delta + windowSize);
if length(find(isnan(s1Dat))) == 0 && length(find(isnan(s2Dat))) == 0
if(var(s1Dat) ~= 0 || var(s2Dat) ~= 0)
sizeNum = sizeNum + 1;
correlation(i) = abs(corr(s1Dat, s2Dat)) ^ 2;
end
end
end
What's happening here:
Run through every values in s1. For every value, get a slice for s1
till s1 + windowSize.
Do the same for s2, only get the slice after an intermediate delta.
If there are no NaN's in any of the two slices and they aren't flat,
then get the correlaton between them and add that to the
correlation matrix.
This is not an answer, I am trying to understand what is being asked.
Take some data:
N = 1e4;
s1 = cumsum(randn(N, 1)); s2 = cumsum(randn(N, 1));
s1(randi(N, 50, 1)) = NaN; s2(randi(N, 50, 1)) = NaN;
windowSize = 200; delta = 100;
Compute correlations:
tic
corr_s = zeros(N - windowSize - delta, 1);
for i = 1:(N - windowSize - delta)
s1Dat = s1(i:(i + windowSize));
s2Dat = s2((i + delta):(i + delta + windowSize));
corr_s(i) = corr(s1Dat, s2Dat);
end
inds = isnan(corr_s);
corr_s(inds) = 0;
corr_s = corr_s .^ 2; % square of correlation coefficient??? Why?
sizeNum = sum(~inds);
toc
This is what you want to do, right? A moving window correlation function? This is a very interesting question indeed …

Resources