見出し画像

無料のTradingViewでも5つのEBBXを表示する方法(その2:価格の絶対値を追加)


はじめに

前回のnoteは、インジケータを1つ使って、5つのEBBXを表示するものでした。前回は価格について相対的な情報のみ扱い、価格がいくらかは無視していました。

今回は価格の絶対値も盛り込みました。次のようなチャートになります。

変更点


今回の変更点について見ていきます。

現在値に横線とラベルを追加

現在の値に横線とラベルを描いています。ラベルにはシンボルの名前と現在値を入れてあります。

draw_close(c, o_c, ticker, index) =>
    var ln = line.new(0, c, 0, c, extend=extend.left, color= dd11b.hsv2color((index-1)*h_step, 100, 60, 30))
    var lb = label.new(0, c, style=label.style_label_left, color=dd11b.hsv2color((index-1)*h_step, 15, 92), textcolor=black)
    if barstate.islast
        ln.set_xy1(bar_index-1, c)
        ln.set_xy2(bar_index, c)
        lb.set_text(ticker + "\n" + str.tostring(o_c, format.mintick))
        lb.set_xy(bar_index, c)

縦軸に目盛を追加

価格の目盛として使えるように、等間隔の横線とその価格を追加しました。

表示範囲の価格の最大、最小を求め、その範囲をカバーするように描いています。価格ラベルが読みやすくなるように、その最下位桁を1、2、5に限定しています。ソース中のnum_linesを変えることで、横線の数を増減できます。

draw_scale(o_h, o_l, o_plus_s_sigma, o_minus_s_sigma, plus_s_sigma, minus_s_sigma, index) =>
    var int int_all1 = int(math.pow(2, 53) - 1) // 最も多く1が並ぶ数
    var float_max = int_all1 * math.pow(2, 1024-53)
    var float_min = -float_max
    var o_highest = float_min
    var o_lowest = float_max
    if chart.left_visible_bar_time < time and time < chart.right_visible_bar_time // 表示範囲に反応
        o_highest := math.max(o_highest, o_h) // 表示範囲のhighest
        o_lowest := math.min(o_lowest, o_l) // 表示範囲のlowest

    if bar_index == last_bar_index-1 // 最後のbar直前で1回
        o_range = o_highest - o_lowest
        step = math.pow(10, math.floor(math.log10(o_range/num_lines))) // logで整数化して戻すことで最下位桁を1にする
        var a_mult = array.from(2, 2.5, 2) // 1*2=2, 2*2.5=5, 5*2=10
        i = 0
        while o_range/num_lines > step
            step *= a_mult.get(i%a_mult.size()) // 最下位桁が1、2、5、10(1桁上で1)を巡回する
            i += 1

        o_price = math.floor(o_lowest/step) * step // 目盛を描く価格
        ratio = (plus_s_sigma-minus_s_sigma) / (o_plus_s_sigma-o_minus_s_sigma)
        while o_price < o_highest + step
            p = (o_price-o_minus_s_sigma)*ratio + minus_s_sigma
            line.new(bar_index-1, p, bar_index, p, extend=extend.left, color=dd11b.gray(70, 50))
            label.new(bar_index, p, style=label.style_none, textcolor=dd11b.hsv2color((index-1)*h_step, 100, 50), text=str.tostring(o_price))
            o_price += step

単位の換算を追加

金(gold)など貴金属の円建て価格のチャートの場合、価格を表示するときにトロイオンスをグラムに換算したほうがいいと思うので 31.1035 で割っています。次のようにソース中で "XAUUSD*USDJPY/31.1035" と文字列で書いておくだけで、適当に処理してくれます。

    else if pt == "OANDA:XAUUSD"
        [ "XAUUSD*USDJPY/31.1035", "XAGUSD*USDJPY/31.1035", "XPTUSD*USDJPY/31.1035", "XPDUSD*USDJPY/31.1035" ]

チャートでの表示は次のようになります。

チャートの数を減らす方法

前回よりも更に線の数が増えているので、チャートの数を減らしたほうが使いやすいかもしれません。チャートの数を1つ減らしたい場合には、次の部分をコメントアウトすればいいです。2つ以上減らす場合も同様です。

// 描画4
[o4, h4, l4, c4, e0p4, e0d4, e1p4, col4] = do_all(sym4, level40, level41, 4)
plot(e0p4 + e0d4*2, color=color_band)
plot(e0p4 + e0d4*1, color=color_band)
plot(e0p4 - e0d4*1, color=color_band)
plot(e0p4 - e0d4*2, color=color_band)
pe0p4 = plot(e0p4, editable=false, display=display.none+display.price_scale)
pe1p4 = plot(e1p4, editable=false, display=display.none+display.price_scale)
fill(pe0p4, pe1p4, col4)
plotcandle(o4, h4, l4, c4, color=o4<c4 ? na : black, wickcolor=black, bordercolor=black)

おわりに

わんわんにとって今回の表示はちょっと煩雑なので、今のところ前回の形で使っています。左右のラベル、縦軸の目盛など、ご自分が必要なところを生かして使ってみてください。

上ではソースの注目部分のみを取り上げましたが、最後にソース全体をつけておきます。使っているライブラリ dig_dig_11/lib_beta/3 はこちらで貼ったものと全く同じです。

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dig_dig_11

//@version=5
indicator("ebbxs 202409")

import dig_dig_11/lib202408/1 as dd11
import dig_dig_11/lib_beta/3 as dd11b

var g_value = input.float(0, title="​g value", minval=0, inline="g")
var g_unit = input.string("b", title="​unit", options=["b", "s", "m", "h", "D", "W", "M", "Y"], inline="g")
var g_shift = input.int(0, title="​shift", inline="g",
  tooltip="value\n"
  + "  0: テーブルで設定\n"
  + "  他: 次のunitとともに解釈\n"
  + "unit\n"
  + "  b: bars\n  s: seconds\n  m: minutes\n  h: hours\n  D: days\n  W: weeks\n  M: months\n  Y: years\n"
  + "shift\n"
  + "  規定テーブルをずらす量")

var exclude = 5 // 最初のexclude*gで、塗りつぶしをしない")

var lic = input.string("", title="​lic", display=display.none,
  tooltip="入力なしで15分足まで使えます\n"
  + "より短い足で使うには https://x.com/dig_dig_11 のプロフィールから")

var s = input.float(1, title="​s", minval=0, step=0.1, tooltip="続く8つのboxのためのsの値")

var level10 = input.price(40, title="​symbol 1 ±sσ", inline="p1", display=display.none)
var level11 = input.price(42, title="", inline="p1", display=display.none,
  tooltip="画面左端でebbxの±sσを描く高さ\n左右どちらの入力が大きくても構わない")
var level20 = input.price(30, title="​symbol 2 ±sσ", inline="p2", display=display.none)
var level21 = input.price(32, title="", inline="p2", display=display.none)
var level30 = input.price(20, title="​symbol 3 ±sσ", inline="p3", display=display.none)
var level31 = input.price(22, title="", inline="p3", display=display.none)
var level40 = input.price(10, title="​symbol 4 ±sσ", inline="p4", display=display.none)
var level41 = input.price(12, title="", inline="p4", display=display.none)

var vline_width = input.int(1, title="​vline width", display=display.none,
  tooltip="g毎に描かれる縦線の太さ")

var info_position = input.string(position.bottom_left, title="​info table position",
  options=[position.bottom_left, position.bottom_right, position.top_right], display=display.none)

// gを計算
var g = dd11b.get_g(g_value, g_unit, g_shift, min_g_in_bars=90)
var margin = dd11b.get_margin(g*timeframe.in_seconds()/60)

var black = color.rgb(0, 0, 0)
var color_band = color.rgb(200, 200, 200)

var h_step = 90 // hueを何度ずつ回すか
var num_lines = 5 // 何本くらい横線を描きたいか

get_symbols() =>
    p = syminfo.prefix
    t = syminfo.ticker
    pt = p + ":" + t
    if t == "JPN225"
        [ "US30", "US100", "US500", "US2000" ]
    else if t == "AMZN"
        [ ticker.modify("NVDA", session.extended),
          ticker.modify("MSFT", session.extended),
          ticker.modify("GOOGL", session.extended),
          ticker.modify("AAPL", session.extended) ]
    else if t == "1326"
        [ "TSE:1540", "TSE:1541", "TSE:1542", "TSE:1543"]
    else if pt == "OANDA:XAUUSD"
        [ "XAUUSD*USDJPY/31.1035", "XAGUSD*USDJPY/31.1035", "XPTUSD*USDJPY/31.1035", "XPDUSD*USDJPY/31.1035" ]
    else if t == "WHEATUSD"
        [ "OANDA:WHEATUSD", "OANDA:CORNUSD", "OANDA:SOYBNUSD", "OANDA:SUGARU" ]
    else if t == "WTICOUSD"
        [ "OANDA:BCOUSD", "OANDA:NATGASUSD", "URANIUM", "OANDA:XCUUSD" ]
    else if t == "USDJPY"
        [ "OANDA:EURJPY", "OANDA:GBPJPY", "OANDA:AUDJPY", "OANDA:NZDJPY" ] 
    else
        [ "OANDA:EURUSD", "OANDA:GBPUSD", "OANDA:AUDUSD", "OANDA:NZDUSD" ]
[sym1, sym2, sym3, sym4] = get_symbols()

draw_close(c, o_c, ticker, index) =>
    var ln = line.new(0, c, 0, c, extend=extend.left, color= dd11b.hsv2color((index-1)*h_step, 100, 60, 30))
    var lb = label.new(0, c, style=label.style_label_left, color=dd11b.hsv2color((index-1)*h_step, 15, 92), textcolor=black)
    if barstate.islast
       ln.set_xy1(bar_index-1, c)
        ln.set_xy2(bar_index, c)
        lb.set_text(ticker + "\n" + str.tostring(o_c, format.mintick))
        lb.set_xy(bar_index, c)

draw_scale(o_h, o_l, o_plus_s_sigma, o_minus_s_sigma, plus_s_sigma, minus_s_sigma, index) =>
    var int int_all1 = int(math.pow(2, 53) - 1) // 最も多く1が並ぶ数
    var float_max = int_all1 * math.pow(2, 1024-53)
    var float_min = -float_max
    var o_highest = float_min
    var o_lowest = float_max
    if chart.left_visible_bar_time < time and time < chart.right_visible_bar_time // 表示範囲に反応
        o_highest := math.max(o_highest, o_h) // 表示範囲のhighest
        o_lowest := math.min(o_lowest, o_l) // 表示範囲のlowest

    if bar_index == last_bar_index-1 // 最後のbar直前で1回
        o_range = o_highest - o_lowest
        step = math.pow(10, math.floor(math.log10(o_range/num_lines))) // logで整数化して戻すことで最下位桁を1にする
        var a_mult = array.from(2, 2.5, 2) // 1*2=2, 2*2.5=5, 5*2=10
        i = 0
        while o_range/num_lines > step
            step *= a_mult.get(i%a_mult.size()) // 最下位桁が1、2、5、10(1桁上で1)を巡回する
            i += 1

        o_price = math.floor(o_lowest/step) * step // 目盛を描く価格
        ratio = (plus_s_sigma-minus_s_sigma) / (o_plus_s_sigma-o_minus_s_sigma)
        while o_price < o_highest + step
            p = (o_price-o_minus_s_sigma)*ratio + minus_s_sigma
            line.new(bar_index-1, p, bar_index, p, extend=extend.left, color=dd11b.gray(70, 50))
            label.new(bar_index, p, style=label.style_none, textcolor=dd11b.hsv2color((index-1)*h_step, 100, 50), text=str.tostring(o_price))
            o_price += step

get_col(e0p, e0d, e1p) =>
    pos = dd11b.get_ebbx_pos(e1p, e0p, e0d, margin)
    dd11b.pos2col4(pos, not_enough=bar_index<g*exclude) // 4色版

do_all(symbol, float level0, float level1, index) =>
    // o_* はoriginal scaleのデータ
    // o_* 以外はsub pane scaleのデータ
    [o_o, o_h, o_l, o_c] = request.security(symbol, timeframe.period, [open, high, low, close])
    [o_e0p, o_e0d, o_e1p] = dd11.ebbx(o_o, o_h, o_l, o_c, g, lic)

    var o_plus_s_sigma = 0.0
    var o_minus_s_sigma = 0.0
    o_plus_s_sigma := chart.left_visible_bar_time < time ? o_plus_s_sigma : o_e0p + o_e0d*s // 画面左端でのoriginal scaleの+sσ
    o_minus_s_sigma := chart.left_visible_bar_time < time ? o_minus_s_sigma : o_e0p - o_e0d*s // 画面左端でのoriginal scaleの-sσ

    var plus_s_sigma = math.max(level0, level1) // sub pane scaleで+sσを描く高さ
    var minus_s_sigma = math.min(level0, level1)  // sub pane scaleで-sσを描く高さ

    // original scaleからsub pane scaleに変換する
    ratio = (plus_s_sigma-minus_s_sigma) / (o_plus_s_sigma-o_minus_s_sigma)
    o = (o_o-o_minus_s_sigma)*ratio + minus_s_sigma
    h = (o_h-o_minus_s_sigma)*ratio + minus_s_sigma
    l = (o_l-o_minus_s_sigma)*ratio + minus_s_sigma
    c = (o_c-o_minus_s_sigma)*ratio + minus_s_sigma
    e0p = (o_e0p-o_minus_s_sigma)*ratio + minus_s_sigma
    e0d = o_e0d*ratio
    e1p = (o_e1p-o_minus_s_sigma)*ratio + minus_s_sigma

    var ticker = str.split(ticker.standard(symbol), ":").last()
    draw_close(c, o_c, ticker, index)
    draw_scale(o_h, o_l, o_plus_s_sigma, o_minus_s_sigma, plus_s_sigma, minus_s_sigma, index)
    if chart.left_visible_bar_time < time
        var lb = label.new(bar_index+1, e0p+e0d*2, // +2σにラベルを描く
          style=label.style_label_lower_left, textcolor=black, color=dd11b.hsv2color((index-1)*h_step, 15, 92), text=ticker)

    [o, h, l, c, e0p, e0d, e1p, get_col(o_e0p, o_e0d, o_e1p)]

// 描画0
[e0p0, e0d0, e1p0] = dd11.ebbx(open, high, low, close, g, lic)
col0 = get_col(e0p0, e0d0, e1p0)
plot(e0p0 + e0d0*2, color=color_band, force_overlay=true)
plot(e0p0 + e0d0*1, color=color_band, force_overlay=true)
plot(e0p0 - e0d0*1, color=color_band, force_overlay=true)
plot(e0p0 - e0d0*2, color=color_band, force_overlay=true)
pe0p0 = plot(e0p0, editable=false, display=display.none+display.price_scale, force_overlay=true)
pe1p0 = plot(e1p0, editable=false, display=display.none+display.price_scale, force_overlay=true)
fill(pe0p0, pe1p0, col0)
plotcandle(open, high, low, close, color=open<close ? na : black, wickcolor=black, bordercolor=black, editable=false, force_overlay=true) // main paneにもともとあるplotは最前面に表示できない

// 描画1
[o1, h1, l1, c1, e0p1, e0d1, e1p1, col1] = do_all(sym1, level10, level11, 1)
plot(e0p1 + e0d1*2, color=color_band)
plot(e0p1 + e0d1*1, color=color_band)
plot(e0p1 - e0d1*1, color=color_band)
plot(e0p1 - e0d1*2, color=color_band)
pe0p1 = plot(e0p1, editable=false, display=display.none+display.price_scale)
pe1p1 = plot(e1p1, editable=false, display=display.none+display.price_scale)
fill(pe0p1, pe1p1, col1)
plotcandle(o1, h1, l1, c1, color=o1<c1 ? na : black, wickcolor=black, bordercolor=black)

// 描画2
[o2, h2, l2, c2, e0p2, e0d2, e1p2, col2] = do_all(sym2, level20, level21, 2)
plot(e0p2 + e0d2*2, color=color_band)
plot(e0p2 + e0d2*1, color=color_band)
plot(e0p2 - e0d2*1, color=color_band)
plot(e0p2 - e0d2*2, color=color_band)
pe0p2 = plot(e0p2, editable=false, display=display.none+display.price_scale)
pe1p2 = plot(e1p2, editable=false, display=display.none+display.price_scale)
fill(pe0p2, pe1p2, col2)
plotcandle(o2, h2, l2, c2, color=o2<c2 ? na : black, wickcolor=black, bordercolor=black)

// 描画3
[o3, h3, l3, c3, e0p3, e0d3, e1p3, col3] = do_all(sym3, level30, level31, 3)
plot(e0p3 + e0d3*2, color=color_band)
plot(e0p3 + e0d3*1, color=color_band)
plot(e0p3 - e0d3*1, color=color_band)
plot(e0p3 - e0d3*2, color=color_band)
pe0p3 = plot(e0p3, editable=false, display=display.none+display.price_scale)
pe1p3 = plot(e1p3, editable=false, display=display.none+display.price_scale)
fill(pe0p3, pe1p3, col3)
plotcandle(o3, h3, l3, c3, color=o3<c3 ? na : black, wickcolor=black, bordercolor=black)

// 描画4
[o4, h4, l4, c4, e0p4, e0d4, e1p4, col4] = do_all(sym4, level40, level41, 4)
plot(e0p4 + e0d4*2, color=color_band)
plot(e0p4 + e0d4*1, color=color_band)
plot(e0p4 - e0d4*1, color=color_band)
plot(e0p4 - e0d4*2, color=color_band)
pe0p4 = plot(e0p4, editable=false, display=display.none+display.price_scale)
pe1p4 = plot(e1p4, editable=false, display=display.none+display.price_scale)
fill(pe0p4, pe1p4, col4)
plotcandle(o4, h4, l4, c4, color=o4<c4 ? na : black, wickcolor=black, bordercolor=black)

// 情報テーブル出力
if barstate.islast
    var a_str = array.from(dd11b.second2readable(g*timeframe.in_seconds()))
    var a_str_tt = array.from(str.tostring(g, "g=#.#bars ") + str.tostring(margin, "margin=#.0%"))
    var tbl = dd11b.get_table(a_str, a_str_tt, columns=2, force_overlay=true)
    tbl.cell_set_text(2, 0, text=str.tostring(e0d0/syminfo.mintick, "#"))
    for x = 1 to 2 // 0はextra spaceに使われている
        tbl.cell_set_bgcolor(x, 0, dd11b.tune_color(col0, transp=20))

// 背景色表示
c = dd11b.get_bg_color(g, vline_width=vline_width)
bgcolor(c, title="​colored session (main pane)", force_overlay=true)
bgcolor(c, title="​colored session (sub pane)")

ここから先は

0字

メンバー特典記事、メンバー限定掲示板が、他のnoteメーンバーシップと同様にあります。 このメンバ…

スタンダードプラン

¥500 / 月
初月無料

プレミアムプラン

¥1,500 / 月

この記事が気に入ったらサポートをしてみませんか?