Search code examples
pine-scriptpine-script-v5tradingview-api

Calculate values and draw lines based on fixed timeframe - PineScript v5


I draw some lines that should be calculated on a fixed timeframe(for example "1D"). My code is as below:

//@version=5
indicator(title="testing-pressure and support", overlay=true)

//中心价和 K 线振幅
float mid_price = (high + low) / 2
float diff      = high - low 

//support price
float support1  = mid_price - 0.618 * diff
float support2  = mid_price - 1 * diff

//压力位
float pressure1 = mid_price + 0.618 * diff
float pressure2 = mid_price + 1 * diff

//是否显示支撑位和压力位
show_support = input.bool(title="显示支撑位", defval=true) 
show_pressure = input.bool(title="显示压力位", defval=true) 
show_mid_price = input.bool(title="显示中心价", defval=true) 

//固定一个时间周期
timeframe = input.timeframe(defval="D", title="固定时间周期")
float d_support1 = request.security(syminfo.tickerid, timeframe, support1)
float d_support2 = request.security(syminfo.tickerid, timeframe, support2)
float d_pressure1 = request.security(syminfo.tickerid, timeframe, pressure1)
float d_pressure2 = request.security(syminfo.tickerid, timeframe, pressure2)
float d_mid_price = request.security(syminfo.tickerid, timeframe, mid_price)
bool d_barstate =  request.security(syminfo.tickerid, timeframe, barstate.islast)

//绘制支撑位和压力位
line_length = input.int(defval=10, title="支撑/压力线的长度")

if d_barstate
    line.new(bar_index-1, d_support1[1], bar_index+line_length,d_support1[1], color = show_support ? color.green : na, width=1)
    label.new(bar_index+line_length, d_support1[1], text=str.tostring(d_support1[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
    
    line.new(bar_index-1, d_support2[1], bar_index+line_length,d_support2[1], color = show_support ? color.green : na, width=1)
    label.new(bar_index+line_length, d_support2[1], text=str.tostring(support2[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
  

    line.new(bar_index-1, d_pressure1[1], bar_index+line_length, d_pressure1[1], color = show_support ? color.red : na, width=1)
    label.new(bar_index+line_length, d_pressure1[1], text=str.tostring(pressure1[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
    
    line.new(bar_index-1, d_pressure2[1], bar_index+line_length, d_pressure2[1], color = show_support ? color.red : na, width=1)
    label.new(bar_index+line_length, d_pressure2[1], text=str.tostring(d_pressure2[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
    

    line.new(bar_index-1, d_mid_price[1], bar_index+line_length, d_mid_price[1], color = show_mid_price ? color.yellow : na, width = 1)
    label.new(bar_index+line_length, d_mid_price[1], text=str.tostring(mid_price[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)

when the chart is in 1D timeframe, the indicator is showing like this: enter image description here

then I switch it to 4H, it is like this: enter image description here

it seems that the lines keep changing while chart timeframe changes, but I want them to be static.


Solution

  • You can use the input property to specify a time frame and use it throughout your script:

    dtf = input("D", title = "Time Frame")
    

    Substitute what you want into "D" to update the chart with that time frame (ex. "W" for weekly). With this, you could create a very simple script that labels the previous days high on your chart:

    //@version=5
    indicator("previous day high", overlay=true)
    
    dtf = input("D", title = "TimeFrame")
    
    // checks if its a new bar in the selected dtf timeframe
    is_new_bar(t) => 
        ta.change(time(t)) != 0
    
    getDailyHigh() =>
        request.security(syminfo.tickerid, dtf, high[1])
    
    var float dailyHigh = na
    if is_new_bar(dtf)
        dailyHigh := getDailyHigh()
    
    // places label
    if barstate.islast
        label.new(bar_index, dailyHigh, text = str.tostring(dailyHigh), style = label.style_label_down, color = color.blue, textcolor = color.white, yloc = yloc.price)
    

    This chart looks as follows:

    The chart above isnt wildly useful, but it is a simple example on the road to accomplish what you want. We will use the same logic, including the daily low, to calculate all the values in your chart.

    Now, grabbing the daily high and daily low as above, and plotting values derived from them:

    //@version=5
    indicator(title="testing-pressure and support", overlay=true)
    
    dtf = input("D", title = "TimeFrame")
     
    // checks if its a new bar in the selected dtf timeframe
    is_new_bar(t) => 
        ta.change(time(t)) != 0
        
    
    var float dailyHigh = na
    var float dailyLow = na
    getDailyHigh() =>
        request.security(syminfo.tickerid, dtf, high[1])
    getDailyLow() =>
        request.security(syminfo.tickerid, dtf, low[1])
        
    if is_new_bar(dtf)
        dailyHigh := getDailyHigh()
        dailyLow := getDailyLow()
        
    var float previousDayHigh = na
    var float previousDayLow = na
    
    if is_new_bar("D")
        previousDayHigh := getDailyHigh()
        previousDayLow := getDailyLow()
    float mid_price = (previousDayHigh + previousDayLow) / 2
    float diff      = previousDayHigh - previousDayLow
    
    //support price
    float support1  = mid_price - 0.618 * diff
    float support2  = mid_price - 1 * diff
    
    //压力位
    float pressure1 = mid_price + 0.618 * diff
    float pressure2 = mid_price + 1 * diff
    
    //是否显示支撑位和压力位
    show_support = input.bool(title="显示支撑位", defval=true) 
    show_pressure = input.bool(title="显示压力位", defval=true) 
    show_mid_price = input.bool(title="显示中心价", defval=true) 
    
    //固定一个时间周期
    timeframe = input.timeframe(defval="D", title="固定时间周期")
    float d_support1 = request.security(syminfo.tickerid, timeframe, support1)
    float d_support2 = request.security(syminfo.tickerid, timeframe, support2)
    float d_pressure1 = request.security(syminfo.tickerid, timeframe, pressure1)
    float d_pressure2 = request.security(syminfo.tickerid, timeframe, pressure2)
    float d_mid_price = request.security(syminfo.tickerid, timeframe, mid_price)
    bool d_barstate =  request.security(syminfo.tickerid, timeframe, barstate.islast)
    
    //绘制支撑位和压力位
    line_length = input.int(defval=10, title="支撑/压力线的长度")
    
    if d_barstate
        line.new(bar_index-1, d_support1[1], bar_index+line_length,d_support1[1], color = show_support ? color.green : na, width=1)
        label.new(bar_index+line_length, d_support1[1], text=str.tostring(d_support1[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
        
        line.new(bar_index-1, d_support2[1], bar_index+line_length,d_support2[1], color = show_support ? color.green : na, width=1)
        label.new(bar_index+line_length, d_support2[1], text=str.tostring(support2[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
      
    
        line.new(bar_index-1, d_pressure1[1], bar_index+line_length, d_pressure1[1], color = show_support ? color.red : na, width=1)
        label.new(bar_index+line_length, d_pressure1[1], text=str.tostring(pressure1[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
        
        line.new(bar_index-1, d_pressure2[1], bar_index+line_length, d_pressure2[1], color = show_support ? color.red : na, width=1)
        label.new(bar_index+line_length, d_pressure2[1], text=str.tostring(d_pressure2[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
        
    
        line.new(bar_index-1, d_mid_price[1], bar_index+line_length, d_mid_price[1], color = show_mid_price ? color.yellow : na, width = 1)
        label.new(bar_index+line_length, d_mid_price[1], text=str.tostring(mid_price[1]), xloc=xloc.bar_index, yloc=yloc.price, style=label.style_none, color=color.green, textcolor=color.green, size=size.small)
    

    You can see that the only changes are how the high and low are calculated, since every other value that is plotted relies on those two values. I am not positive if you are trying to use the previous days high and the previous days low, but that is what I used. If you are looking for the previous days close, then it would follow the same logic, but require a different method of data selection. This chart looks as follows with the daily time frame selected: enter image description here

    And here I have selected a different time frame: enter image description here

    Its the same values!

    It is possible that there is a way to do this more succinctly, as your script is now quite long, but I have taken enough time thus far that I do not wish to clean it up- if you are able to, though, I would be interested to see the final product.