Code not plotting - Function should be called on each calculation for consistency. It is recommended to extract the call from this scope" - pine-script-v5

I am getting this as an orange error - not sure what I have done wrong or whether this error is the reason that the code doesn't plot. I am brand new to Pine-script and any assistance would be invaluable. Many thanks in advance Alastair
//#version=5
indicator("PCY TEST4")
//Get User Inputs
fast_length = input(title="Fast Length", defval=12)
slow_length = input(title="Slow Length", defval=26)
src = input(title="Source", defval=close)
signal_length = input.int(title="Signal Smoothing", minval = 1, maxval = 50, defval = 9)
sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"])
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"])
//Variables
a = 0.33
PCY = 0.0
PCYi = 0.0
// Calculating
fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
minMacd=0.0
for i = 0 to (signal_length[1])
minMacd := ta.min(macd)
maxMacd=0.0
for i = 0 to (signal_length[1])
maxMacd := ta.max(macd)
//maxMacd = ta.min(macd)
//minMacd = ta.max(macd)
//signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
//hist = macd - signal
delta = maxMacd-(fast_ma - slow_ma)/(maxMacd -minMacd)
for i = 0 to (signal_length)
PCYi := a*((delta - PCYi[1])+PCYi[1])
PCYi
//Plotting
plot(PCYi)

I think it's because you're calculating the min/max in a for loop
Those functions should (not mandatory but strongly recommended) be calculated at every candle instead
for i = 0 to (signal_length[1])
minMacd := ta.min(macd)
maxMacd=0.0
for i = 0 to (signal_length[1])
maxMacd := ta.max(macd)
If you want to calculate the min/max over a X period of time, maybe use the ta.highest/ta.lowest functions instead :)
And of course, those 2 should be called at every candle (i.e. not in a if, for,... statement)

Related

Pine Script V5 - Not getting expected breakout entry price and entry in expected bar

I have a long entry buy condition where
Candle time frame is 15 minutes
Alert candle high is below lower band of bollinger bands.
entry when next candle crossover the alert candle high
This script gives entry oh high breakout + 0.01 but it does not give entry in the exact breakout candle and gives entry when price comes next time on expected entry price i.e. alert candle high + 0.01.
Requesting solution to get entry in breakout candle itself and at expected breakout price.
//#version=5
strategy("Bands Reversion", overlay=true, calc_on_every_tick=true)
//// Indicator Bollinger Bands
source = close
length = input.int(20, minval=1)
mult = input.float(1.5, minval=0.001, maxval=50)
direction = input.int(0, title = "Strategy Direction", minval=-1, maxval=1)
strategy.risk.allow_entry_in(direction == 0 ? strategy.direction.all : (direction < 0 ? strategy.direction.short : strategy.direction.long))
basis = ta.sma(source, length)
dev = mult * ta.stdev(source, length)
upper = basis + dev
lower = basis - dev
plot(basis, color = color.red)
plot(upper)
plot(lower)
/// Trade entry time and squareoff time
TradeTime = input(title="Trade Timings",defval="0930-1130")
SqoffTime = input(title="Squareoff Timings",defval="1530-1545")
Barsinsession(TradeTime) => time(timeframe.period,TradeTime) != 0
Insession = Barsinsession(TradeTime) ? 1 : 0
endofsession = Insession == 0 and Insession[1] == 1
Sqsession = Barsinsession(SqoffTime) ? 1 : 0
SqTime = Sqsession == 1 and Sqsession[1] == 0
//// Input control and conditions
buy_condition = high[1] < lower[1] and ta.crossover(high, high[1]) and Insession
short_condition = low[1] > upper[1] and ta.crossunder(low, low[1]) and Insession
buy_alert_high = ta.valuewhen(buy_condition, high[1],0)
buy_alert_low = ta.valuewhen(buy_condition, low[1],0)
short_alert_low = ta.valuewhen(short_condition, low[1],0)
short_alert_high = ta.valuewhen(short_condition, high[1],0)
buy_alert_high1 = ta.valuewhen(buy_condition, high,0)
plot(buy_alert_high, style = plot.style_circles)
plot(buy_alert_low, style = plot.style_circles, offset = -2)
plot(short_alert_low, style = plot.style_circles)
plot(short_alert_high, style = plot.style_circles)
sell = ta.crossunder(close, low) or SqTime //// or SqTime if for intraday exit
cover = ta.crossover(close,high) or SqTime //// or SqTime if for intraday exit
plotshape(buy_condition, style = shape.triangleup, location = location.belowbar, color = color.green, text = "BUY")
plotshape(short_condition, style = shape.triangledown, location = location.abovebar, color = color.red, text = "SHORT")
long_price = ta.valuewhen(buy_condition, (buy_alert_high + 0.01),0 )
longstop = buy_alert_low - 0.01
longtgt = basis
short_price = ta.valuewhen(short_condition,short_alert_low - 0.01,0) ////short_alert_low - (0.01 * 100 * syminfo.mintick) //// ta.valuewhen(short_condition,short_alert_low - 0.01,0)
shortstop = short_alert_high + 0.01
shorttgt = basis
strategy.entry("long",direction = strategy.long, when = buy_condition, limit = long_price, comment ="BUY")
strategy.close("long", when = sell, comment = "SELL")
strategy.exit("long", from_entry = "long", stop = longstop, limit = longtgt, comment = "TG/SL_EXIT")
strategy.entry("short",direction = strategy.short, when = short_condition,limit = short_price, comment ="SHORT")
strategy.close("short", when = cover, comment = "COVER")
strategy.exit("short", from_entry = "short", stop = shortstop, limit = shorttgt, comment = "TG/SL_EXIT")
plot(strategy.position_size > 0 ? longstop : na, style = plot.style_linebr, color = color.red)
plot(strategy.position_size > 0 ? longtgt : na, style = plot.style_linebr, color = color.green)
plot(strategy.position_size < 0 ? shortstop : na, style = plot.style_linebr, color = color.red)
plot(strategy.position_size < 0 ? shorttgt : na, style = plot.style_linebr, color = color.green)

Compare bool and float to determine plot (pine script v5)

You folks helped me with another part of this script and I'm making good progress. However, I'm stuck again.
I added a code to produce a dynamic overbought/oversold line on the indicator. That part works great. Now, I'm wanting to add a plotshape when conditions are met to signal long or short. Unfortunately, I can't figure out how to compare a bool variable and a float variable. The dynamic OB/OS lines are floats. The crossover lines are bool.
What I want is for the (green/long) shape to plot when a crossover happens below the dynamic oversold line and the (red/short) shape to plot when the crossunder happens above the dynamic overbought line.
I've tried all kinds of things (var, loop with "while" using sb value as a trigger). I either break the code or I get every crossover plotted. Here is what I have that is stable. I took all my junk that didn't work out:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HammerGeek
//#version=5
indicator('Impulse MACD [HammerGeek - LazyBear]', shorttitle='IMACD_HG_LB', overlay=false)
lengthMA = input(34)
lengthSignal = input(9)
//OverBought = input.float(0.1)
//OverSold = input.float(-0.1)
calc_smma(src, len) =>
smma = 0.0
sma_1 = ta.sma(src, len)
smma := na(smma[1]) ? sma_1 : (smma[1] * (len - 1) + src) / len
smma
calc_zlema(src, length) =>
ema1 = ta.ema(src, length)
ema2 = ta.ema(ema1, length)
d = ema1 - ema2
ema1 + d
src = hlc3
hi = calc_smma(high, lengthMA)
lo = calc_smma(low, lengthMA)
mi = calc_zlema(src, lengthMA)
md = mi > hi ? mi - hi : mi < lo ? mi - lo : 0
sb = ta.sma(md, lengthSignal)
sh = md - sb
mda = ta.sma(md, lengthSignal)
OverBoughtLine = ta.highest(sb * 0.5, lengthMA*100)
OverSoldLine = ta.lowest(sb * 0.5, lengthSignal*100)
shsbCrossOver = ta.crossover(md, sb)
shsbCrossUnder = ta.crossunder(md, sb)
//mdc = src > mi ? src > hi ? color.lime : color.green : src < lo ? color.red : color.orange
mdc = color.green
plot(0, color=color.new(color.gray, 0), linewidth=1, title='MidLine')
plot(md, color=mdc, linewidth=2, title='ImpulseMACD', style=plot.style_line)
plot(sh, color=color.rgb(122, 5, 168, 40), linewidth=2, title='ImpulseHisto', style=plot.style_area)
plot(sb, color=color.rgb(255, 255, 255, transp = 40), linewidth=2, title='ImpulseMACDCDSignal')
plot(OverBoughtLine, color=color.new(#f3e032, 0), linewidth=1, title = 'Overbought Line')
plot(OverSoldLine, color=color.new(color.yellow, 0), linewidth=1, title = 'Oversold Line')
plotshape(shsbCrossOver, "LONG", shape.triangleup, location.bottom, color.new(color.green, 0))
plotshape(shsbCrossUnder, "SHORT", shape.triangledown, location.top, color.new(#cd0808, 0))
//ebc = input(false, title='Enable bar colors')
//barcolor(ebc ? mdc : na)
You cannot compare a bool with a float. It doesn't make any sense and it is not legal in pinescript.
What I want is for the (green/long) shape to plot when a crossover
happens below the dynamic oversold line and the (red/short) shape to
plot when the crossunder happens above the dynamic overbought line.
You want to check if the values you use in that crossover is under your dynamic oversold line at the time of crossover.
OverSoldLine = ta.lowest(sb * 0.5, lengthSignal*100)
shsbCrossOver = ta.crossover(md, sb)
is_good = shsbCrossOver and (md < OverSoldLine) and (sb < OverSoldLine)

Error in output either line or envelope shows up

I have used 2 code on Tradingview by LUXALGO
Nadaraya-Watson Estimator
Nadaraya-Watson Envelope
When the code is converted to ver 5.0 and compiled together, no compilation error is shown but the output only reflects either the Estimator Line or Estimator Envelope. Need both outputs together.
To replicate the problem, first select either the Estimator Checkbox or Envelope Checkbox, when both the Estimator and Envelope checkboxes are selected, we get only the envelope and the Estimator line disappears. Need help in resolving this issue.
The code is as below:
I have updated the variables inorder to not mix up while merging 2 scripts
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//#version=5
indicator('Nadaraya-Watson Estimator & Envelope [LuxAlgo]', overlay=true,max_bars_back=1000,max_lines_count=500,max_labels_count=500)
grp_1 = "Estimator Settings"
show_est = input.bool(true, "Show Estimator", group = grp_1)
h_est = input(8.,'Bandwidth', group = grp_1)
src_est = input(close,'Source', group = grp_1)
disclaimer = input(false, 'Hide Disclaimer', group = grp_1)
//----
n_est = bar_index
var ln_est = array.new_line(0)
if barstate.isfirst
for i = 0 to 499
array.push(ln_est,line.new(na,na,na,na))
//----
float y2_est = na
float y1_est = na
float y1_d_est = na
//----
line l_est = na
label lb_est = na
if barstate.islast and show_est
for i_est = 0 to math.min(499,n_est-1)
sum_est = 0.
sumw_est = 0.
for j_est = 0 to math.min(499,n_est-1)
w_est = math.exp(-(math.pow(i_est-j_est,2)/(h_est*h_est*2)))
sum_est += src_est[j_est]*w_est
sumw_est += w_est
y2_est := sum_est/sumw_est
d_est = y2_est - y1_est
l_est := array.get(ln_est,i_est)
line.set_xy1(l_est,n_est-i_est+1,y1_est)
line.set_xy2(l_est,n_est-i_est,y2_est)
line.set_color(l_est,y2_est > y1_est ? #ff1100 : #39ff14)
line.set_width(l_est,2)
if d_est > 0 and y1_d_est < 0
label.new(n_est-i_est+1,src_est[i_est],'▲',color=#00000000,style=label.style_label_up,textcolor=#39ff14,textalign=text.align_center)
if d_est < 0 and y1_d_est > 0
label.new(n_est-i_est+1,src_est[i_est],'▼',color=#00000000,style=label.style_label_down,textcolor=#ff1100,textalign=text.align_center)
y1_est := y2_est
y1_d_est := d_est
//----
var tb_est = table.new(position.top_right, 1, 1
, bgcolor = color.silver)
if barstate.isfirst and not disclaimer
table.cell(tb_est, 0, 0, 'Nadaraya-Watson Estimator [LUX] Repaints'
, text_size = size.small
, text_color = #cc2f3c)
// // This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// // © LuxAlgo
// //#version=5
// indicator("Nadaraya-Watson Envelope [LuxAlgo]",overlay=true,max_bars_back=1000,max_lines_count=500,max_labels_count=500)
grp_2 = "Envelope Settings"
show_env = input.bool(false, "Show Envelope")
length_env = input.float(500,'Window Size',maxval=500,minval=0, group = grp_2)
h_env = input.float(8.,'Bandwidth', group = grp_2)
mult_env = input.float(3., group = grp_2)
src_env = input.source(close,'Source', group = grp_2)
up_col_env = input.color(#39ff14,'Colors',inline='col', group = grp_2)
dn_col_env = input.color(#ff1100,'',inline='col', group = grp_2)
// disclaimer = input(false, 'Hide Disclaimer')
//----
n_env = bar_index
var k_env = 2
var upper_env = array.new_line(0)
var lower_env = array.new_line(0)
lset(l,x1,y1,x2,y2,col)=>
line.set_xy1(l,x1,y1)
line.set_xy2(l,x2,y2)
line.set_color(l,col)
line.set_width(l,2)
if barstate.isfirst and show_env
for i = 0 to length_env/k_env-1
array.push(upper_env,line.new(na,na,na,na))
array.push(lower_env,line.new(na,na,na,na))
//----
line up_env = na
line dn_env = na
//----
cross_up_env = 0.
cross_dn_env = 0.
if barstate.islast and show_env
y_env = array.new_float(0)
sum_e_env = 0.
for i = 0 to length_env-1
sum_env = 0.
sumw_env = 0.
for j = 0 to length_env-1
w_env = math.exp(-(math.pow(i-j,2)/(h_env*h_env*2)))
sum_env += src_env[j]*w_env
sumw_env += w_env
y2_env = sum_env/sumw_env
sum_e_env += math.abs(src_env[i] - y2_env)
array.push(y_env,y2_env)
mae_env = sum_e_env/length_env*mult_env
for i = 1 to length_env-1
y2_env = array.get(y_env,i)
y1_env = array.get(y_env,i-1)
up_env := array.get(upper_env,i/k_env)
dn_env := array.get(lower_env,i/k_env)
lset(up_env,n_env-i+1,y1_env + mae_env,n_env-i,y2_env + mae_env,up_col_env)
lset(dn_env,n_env-i+1,y1_env - mae_env,n_env-i,y2_env - mae_env,dn_col_env)
if src_env[i] > y1_env + mae_env and src_env[i+1] < y1_env + mae_env
label.new(n_env-i,src_env[i],'▼',color=#00000000,style=label.style_label_down,textcolor=dn_col_env,textalign=text.align_center)
if src_env[i] < y1_env - mae_env and src_env[i+1] > y1_env - mae_env
label.new(n_env-i,src_env[i],'▲',color=#00000000,style=label.style_label_up,textcolor=up_col_env,textalign=text.align_center)
cross_up_env := array.get(y_env,0) + mae_env
cross_dn_env := array.get(y_env,0) - mae_env
alertcondition(ta.crossover(src_env,cross_up_env),'Down','Down')
alertcondition(ta.crossunder(src_env,cross_dn_env),'Up','Up')
// //----
// var tb = table.new(position.top_right, 1, 1
// , bgcolor = #35202b)
// if barstate.isfirst and not disclaimer
// table.cell(tb, 0, 0, 'Nadaraya-Watson Envelope [LUX] Repaints'
// , text_size = size.small
// , text_color = #cc2f3c)

Condition only run ONCE (instead on all bars)

On checking for condition gap(high-low) > 0.1%(which is met multiple times), the label only gets
rendered ONCE (instead of on relevant bars within 25 bar lookback).
Plz provide a solution.
CODE :
Historical Bars
//#version=5
indicator("PriceMomemtum",overlay = true,max_bars_back = 25)
gap = (math.abs(high - low)/low ) * 100
//var gap = (math.abs(high - low)/low ) * 100
if gap > 0.1
var lbl = label.new(x = bar_index,y = na , text = na ,text_font_family = font.family_default ,xloc = xloc.bar_index,yloc =yloc.abovebar,style = label.style_arrowdown ,textcolor = color.white,size =size.small,textalign = text.align_left,tooltip = na)
label.set_text(lbl,str.tostring(gap,"#.00")+"%")
label.set_xy(lbl,bar_index,high )
Realtime Bars
//#version=5
indicator("PriceMomemtum",overlay = true,max_bars_back = 25)
if barstate.isrealtime
gap = (math.abs(high - low)/low ) * 100
//var gap = (math.abs(high - low)/low ) * 100
if gap > 0.1
var lbl = label.new(x = bar_index,y = na , text = na ,text_font_family = font.family_default ,xloc = xloc.bar_index,yloc =yloc.abovebar,style = label.style_arrowdown ,textcolor = color.white,size =size.small,textalign = text.align_left,tooltip = na)
label.set_text(lbl,str.tostring(gap,"#.00")+"%")
label.set_xy(lbl,bar_index,high )
alert(str.tostring(time(syminfo.timezone)) + "(PriceMomentum)", alert.freq_once_per_bar)
Have you tried defining "lbl" variable without "var"?
result

Optimal dispatch of power generators

I want to write a matlab code that can optimally dispatch power generators to satisfy electric demand by considering profit too. I used below code that is in matlab website. https://ww2.mathworks.cn/help/optim/examples/optimal-dispatch-of-power-generators.html?requestedDomain=en
But in this code they are not considering the demand.
My target is , there are 20 power plants and I want to schedule this plants to satisfy demand. And the running power level can be any value in between the max and minimum power value of each power plant. High cost power plants should dispatch too.
name = 'generationcost.xlsx';
poolPrice = xlsread(name,'AD3:AD50'); % Revenue in dollars per MWh in interval
demand = xlsread(name,'AC3:AC52');
month = numel(demand);
e = xlsread(name,'W2:W4')'; %Cost for a unit of fuel
fuelPrice = repmat(e,1,1,2);
nPeriods = length(poolPrice);
nGens = 3;
genhigh = xlsread(name,'F2:F4');
genlow = xlsread(name,'Q2:Q4');
gen = [genlow(:),genhigh(:),]; %MW
fuel = [50,330;45,325;55,750]; % Fuel consumption for generator
startCost = [10000;10000;10000]; %Cost in dollars to start a generator after it has been off
y = optimvar('y',nPeriods,nGens,{'Low','High'},'Type','integer','LowerBound',0,'UpperBound',1);
z = optimvar('z',nPeriods,nGens,'Type','integer','LowerBound',0,'UpperBound',1);
powercons = y(:,:,'Low') + y(:,:,'High') <= 1;
yFuel = zeros(nPeriods,nGens,2);
yFuel(:,1,1) = fuel(1,1);
yFuel(:,1,2) = fuel(1,2);
yFuel(:,2,1) = fuel(2,1);
yFuel(:,2,2) = fuel(2,2);
yFuel(:,3,1) = fuel(3,1);
yFuel(:,3,2) = fuel(3,2);
fuelUsed = sum(reshape((sum(y.*yFuel)),[3 2])');
%fuelcons = fuelUsed <= totalFuel;
w = optimexpr(nPeriods,nGens);
idx = 1:(nPeriods-1);
w(idx,:) = y(idx+1,:,'Low') - y(idx,:,'Low') + y(idx+1,:,'High') -
y(idx,:,'High');
w(nPeriods,:) = y(1,:,'Low') - y(nPeriods,:,'Low') + y(1,:,'High') -
y(nPeriods,:,'High');
switchcons = w - z <= 0;
generatorlevel = zeros(size(yFuel));
generatorlevel(:,1,1) = gen(1,1);
generatorlevel(:,1,2) = gen(1,2);
generatorlevel(:,2,1) = gen(2,1);
generatorlevel(:,2,2) = gen(2,2);
generatorlevel(:,3,1) = gen(3,1);
generatorlevel(:,3,2) = gen(3,2);
revenue = optimexpr(size(y));
for ii = 1:nPeriods
revenue(ii,:,:) = poolPrice(ii)*y(ii,:,:).*generatorlevel(ii,:,:);
end
val = optimexpr(size(y));
demands = optimexpr(nPeriods,1);
id = 1:nPeriods;
val(id,:,:)= y(id,:,:).*generatorlevel(id,:,:);
demands(id,:)= sum(sum(val,3),2);
demandcons = demands-demand ;
fuelCost = sum(sum(fuelPrice.*sum(y.*yFuel)));
startingCost = z*startCost;
profit = sum(sum(sum(revenue))) - fuelCost - sum(startingCost);
dispatch = optimproblem('ObjectiveSense','maximize');
dispatch.Objective = profit;
dispatch.Constraints.powercons = powercons;
dispatch.Constraints.demandcons = demands - demand <= 0 ;
options = optimoptions('intlinprog','Display','final');
[dispatchsol,fval,exitflag,output] = solve(dispatch,'options',options);
subplot(5,1,1)
bar(dispatchsol.y(:,1,1)*gen(1,1)+dispatchsol.y(:,1,2)*gen(1,2),.5,'g')
xlim([.5,48.5])
ylabel('MW')
title('Generator 1 Optimal Schedule','FontWeight','bold')
subplot(5,1,2)
bar(dispatchsol.y(:,2,1)*gen(2,1)+dispatchsol.y(:,2,2)*gen(2,2),.5,'c')
title('Generator 2 Optimal Schedule','FontWeight','bold')
xlim([.5,48.5])
ylabel('MW')
subplot(5,1,3)
bar(dispatchsol.y(:,3,1)*gen(3,1)+dispatchsol.y(:,3,2)*gen(3,2),.5,'c')
title('Generator 3 Optimal Schedule','FontWeight','bold')
xlim([.5,48.5])
ylabel('MW')
subplot(5,1,4)
bar(demand,.5)
xlim([.5,48.5])
title('Daily Demand','FontWeight','bold')
xlabel('Period')
ylabel('MW')
starttimes = find(round(dispatchsol.z) == 1);
[theperiod,thegenerator] = ind2sub(size(dispatchsol.z),starttimes)
This code is not satisfying Demand. The output demand value is more lesser than the actual demand value. And also here only use 'High' or 'Low' power levels only. In between power values not using.