[dharmatech] U.S. Treasury Yield Curve
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dharmatech

// 2023-10-01 : Hardcoded timeframe of securities to 1D. Without this, RRP doesn't load at lower timeframes.
//              Also, without this, at lower timeframes, the yield curve difference is sometimes hardly noticeable.

//@version=5
indicator("US Treasury Yield Curve", overlay = false, precision = 4)

width = input.int(defval = 15, title = "Spacing between labels in bars")

prev = input.int(defval = 1, title = "Previous")

prev_1 = input.int(defval =  30, title = "Previous 1")
prev_2 = input.int(defval =  60, title = "Previous 2")
prev_3 = input.int(defval =  90, title = "Previous 3")
prev_4 = input.int(defval = 180, title = "Previous 4")
prev_5 = input.int(defval = 360, title = "Previous 5")

prev_1_on = input.bool(defval = false)
prev_2_on = input.bool(defval = false)
prev_3_on = input.bool(defval = false)
prev_4_on = input.bool(defval = false)
prev_5_on = input.bool(defval = false)

symbols = 13

rrp   = request.security("RRPONTSYAWARD", timeframe = '1D', expression = close)

us1m  = request.security("US01MY", timeframe = '1D', expression = close)
us2m  = request.security("US02MY", timeframe = '1D', expression = close)
us3m  = request.security("US03MY", timeframe = '1D', expression = close)
us4m  = request.security("US04MY", timeframe = '1D', expression = close)
us6m  = request.security("US06MY", timeframe = '1D', expression = close)
us1y  = request.security("US01Y",  timeframe = '1D', expression = close)
us2y  = request.security("US02Y",  timeframe = '1D', expression = close)
us3y  = request.security("US03Y",  timeframe = '1D', expression = close)
us5y  = request.security("US05Y",  timeframe = '1D', expression = close)
us7y  = request.security("US07Y",  timeframe = '1D', expression = close)
us10y = request.security("US10Y",  timeframe = '1D', expression = close)
us20y = request.security("US20Y",  timeframe = '1D', expression = close)
us30y = request.security("US30Y",  timeframe = '1D', expression = close)

pos(idx) =>
    bar_index - (symbols - idx) * width

draw_label(idx, src, txt) =>
    var label la = na
    label.delete(la)
    la := label.new(x = pos(idx), y = src - 0.1, text = txt, color = color.black, style = label.style_label_up, textcolor = color.white)

draw_line(idx1, src1, idx2, src2) =>
    var line li = na
    line.delete(li)    
    li := line.new(x1 = pos(idx1), y1 = src1, x2 = pos(idx2), y2 = src2, color=color.red, width=3)

draw_line_prev(idx1, src1, idx2, src2) =>
    var line li2 = na
    line.delete(li2)
    li2 := line.new(x1 = pos(idx1), y1 = src1[prev], x2 = pos(idx2), y2 = src2[prev], color=color.yellow, width=1)

draw_line_prev_alt(idx1, src1, idx2, src2, color) =>
    var line li3 = na
    line.delete(li3)
    li3 := line.new(x1 = pos(idx1), y1 = src1[prev], x2 = pos(idx2), y2 = src2[prev], color=color, width=1)

draw_label( -1,  rrp,  "RRP% \n (" + str.tostring(math.round(rrp,  3)) + ")")
draw_label(  0,  us1m,  "1M \n (" + str.tostring(math.round(us1m,  3)) + ")")
draw_label(  1,  us2m,  "2M \n (" + str.tostring(math.round(us2m,  3)) + ")")
draw_label(  2,  us3m,  "3M \n (" + str.tostring(math.round(us3m,  3)) + ")")
draw_label(  3,  us4m,  "4M \n (" + str.tostring(math.round(us4m,  3)) + ")")
draw_label(  4,  us6m,  "6M \n (" + str.tostring(math.round(us6m,  3)) + ")")
draw_label(  5,  us1y,  "1Y \n (" + str.tostring(math.round(us1y,  3)) + ")")
draw_label(  6,  us2y,  "2Y \n (" + str.tostring(math.round(us2y,  3)) + ")")
draw_label(  7,  us3y,  "3Y \n (" + str.tostring(math.round(us3y,  3)) + ")")
draw_label(  8,  us5y,  "5Y \n (" + str.tostring(math.round(us5y,  3)) + ")")
draw_label(  9,  us7y,  "7Y \n (" + str.tostring(math.round(us7y,  3)) + ")")
draw_label( 10, us10y, "10Y \n (" + str.tostring(math.round(us10y, 3)) + ")")
draw_label( 11, us20y, "20Y \n (" + str.tostring(math.round(us20y, 3)) + ")")
draw_label( 12, us30y, "30Y \n (" + str.tostring(math.round(us30y, 3)) + ")")

draw_line(-1,   rrp,  0,  us1m)
draw_line( 0,  us1m,  1,  us2m)
draw_line( 1,  us2m,  2,  us3m)
draw_line( 2,  us3m,  3,  us4m)
draw_line( 3,  us4m,  4,  us6m)
draw_line( 4,  us6m,  5,  us1y)
draw_line( 5,  us1y,  6,  us2y)
draw_line( 6,  us2y,  7,  us3y)
draw_line( 7,  us3y,  8,  us5y)
draw_line( 8,  us5y,  9,  us7y)
draw_line( 9,  us7y, 10, us10y)
draw_line(10, us10y, 11, us20y)
draw_line(11, us20y, 12, us30y)

draw_line_prev(-1,   rrp,  0,  us1m)
draw_line_prev( 0,  us1m,  1,  us2m)
draw_line_prev( 1,  us2m,  2,  us3m)
draw_line_prev( 2,  us3m,  3,  us4m)
draw_line_prev( 3,  us4m,  4,  us6m)
draw_line_prev( 4,  us6m,  5,  us1y)
draw_line_prev( 5,  us1y,  6,  us2y)
draw_line_prev( 6,  us2y,  7,  us3y)
draw_line_prev( 7,  us3y,  8,  us5y)
draw_line_prev( 8,  us5y,  9,  us7y)
draw_line_prev( 9,  us7y, 10, us10y)
draw_line_prev(10, us10y, 11, us20y)
draw_line_prev(11, us20y, 12, us30y)

draw_curve(int n, color color) =>
    draw_line_prev_alt(-1,   rrp[n],  0,  us1m[n], color)
    draw_line_prev_alt( 0,  us1m[n],  1,  us2m[n], color)
    draw_line_prev_alt( 1,  us2m[n],  2,  us3m[n], color)
    draw_line_prev_alt( 2,  us3m[n],  3,  us4m[n], color)
    draw_line_prev_alt( 3,  us4m[n],  4,  us6m[n], color)
    draw_line_prev_alt( 4,  us6m[n],  5,  us1y[n], color)
    draw_line_prev_alt( 5,  us1y[n],  6,  us2y[n], color)
    draw_line_prev_alt( 6,  us2y[n],  7,  us3y[n], color)
    draw_line_prev_alt( 7,  us3y[n],  8,  us5y[n], color)
    draw_line_prev_alt( 8,  us5y[n],  9,  us7y[n], color)
    draw_line_prev_alt( 9,  us7y[n], 10, us10y[n], color)
    draw_line_prev_alt(10, us10y[n], 11, us20y[n], color)    
    draw_line_prev_alt(11, us20y[n], 12, us30y[n], color)    

if prev_1_on
    draw_curve(prev_1, color.green)
if prev_2_on
    draw_curve(prev_2, color.blue)
if prev_3_on
    draw_curve(prev_3, color.orange)
if prev_4_on
    draw_curve(prev_4, color.white)
if prev_5_on
    draw_curve(prev_5, color.teal)

us10y3m = (us10y - us3m) * 100
us10y2y = (us10y - us2y) * 100

p = "Important spreads:\n\n"
p := p + "10Y/03M: " + str.tostring(us10y3m) + " bps\n"
p := p + "10Y/02Y: " + str.tostring(us10y2y) + " bps\n"

// draw_label(12, us30y, p)