//@version=6
// ════════════════════════════════════════════════════════════════════
// TRADZY TA FILL SHEET v7 — MODULAR INDEPENDENT TABLES
// ────────────────────────────────────────────────────────────────
// Every category (Momentum, Trend, MACD/Volume, Volatility,
// Ichimoku/VWAP, MTF/Misc) is now its OWN table with its OWN
// Show / Position / Text-Size controls — toggle any one on/off
// independently, park it wherever you want, size it however you
// want. Each row holds 5 label=value pairs (10 columns) instead
// of the old 3, so far fewer rows are needed and less cuts off.
//
// PAYLOAD is its own table too. Pick how many rows to split the
// paste-ready string into (1–10) — if it's still cutting off,
// just bump the row count up and copy each line.
// ════════════════════════════════════════════════════════════════════
indicator("TRADZY TA FILL SHEET v7", overlay=true, max_labels_count=1)
// ──────────────────────────────────────────────────────────────────
// ① TA INPUT FIELD CONTROLS
// ──────────────────────────────────────────────────────────────────
g_mom = "① Momentum Lengths"
rsiLen = input.int(14, "RSI Length", group=g_mom)
stochLen = input.int(14, "Stoch %K Length", group=g_mom)
stochDLen = input.int(3, "Stoch %D Smoothing", group=g_mom)
stochRsiLen = input.int(14, "Stoch RSI Length (RSI-of-RSI)", group=g_mom)
adxDiLen = input.int(14, "ADX / DI Length", group=g_mom)
adxLen = input.int(14, "ADX Smoothing", group=g_mom)
cciLen = input.int(20, "CCI Length", group=g_mom)
williamsLen = input.int(14, "Williams %R Length", group=g_mom)
mfiLen = input.int(14, "MFI Length", group=g_mom)
rocLen = input.int(9, "ROC Length", group=g_mom)
cmoLen = input.int(14, "CMO Length", group=g_mom)
g_trend = "② Trend / MA Lengths"
ema9Len = input.int(9, "EMA 9 Length", group=g_trend)
ema21Len = input.int(21, "EMA 21 Length", group=g_trend)
ema50Len = input.int(50, "EMA 50 Length", group=g_trend)
ema100Len = input.int(100, "EMA 100 Length", group=g_trend)
ema200Len = input.int(200, "EMA 200 Length", group=g_trend)
wmaLen = input.int(20, "WMA Length", group=g_trend)
hmaLen = input.int(9, "HMA Length", group=g_trend)
vwmaLen = input.int(20, "VWMA Length", group=g_trend)
demaLen = input.int(21, "DEMA Length", group=g_trend)
temaLen = input.int(21, "TEMA Length", group=g_trend)
lrLen = input.int(20, "Linear Regression Slope Length", group=g_trend)
supertrendFactor = input.float(3.0, "Supertrend Factor", group=g_trend)
supertrendAtrLen = input.int(10, "Supertrend ATR Length", group=g_trend)
sarStart = input.float(0.02, "Parabolic SAR Start", step=0.01, group=g_trend)
sarInc = input.float(0.02, "Parabolic SAR Increment", step=0.01, group=g_trend)
sarMax = input.float(0.2, "Parabolic SAR Max", step=0.01, group=g_trend)
g_macdvol = "③ MACD / Volume Lengths"
macdFast = input.int(12, "MACD Fast Length", group=g_macdvol)
macdSlow = input.int(26, "MACD Slow Length", group=g_macdvol)
macdSignal = input.int(9, "MACD Signal Length", group=g_macdvol)
volSmaLen = input.int(20, "Volume SMA Length (for Vol %)", group=g_macdvol)
rvolLen = input.int(20, "RVOL Avg Length", group=g_macdvol)
cmfLen = input.int(20, "CMF Length", group=g_macdvol)
volDeltaLen = input.int(14, "Volume Delta EMA Length", group=g_macdvol)
g_vol1 = "④ Volatility Lengths — ATR / BB"
atrLen = input.int(14, "ATR Length", group=g_vol1)
bbLen = input.int(20, "Bollinger Band Length", group=g_vol1)
bbMult = input.float(2.0, "Bollinger Band Mult", step=0.1, group=g_vol1)
hvLen = input.int(20, "Historical Volatility Length", group=g_vol1)
chopLen = input.int(14, "Choppiness Index Length", group=g_vol1)
g_vol2 = "⑤ Volatility Lengths — KC / DC / Squeeze / STC"
kcLen = input.int(20, "Keltner EMA Length", group=g_vol2)
kcAtrLen = input.int(10, "Keltner ATR Length", group=g_vol2)
kcMult = input.float(2.0, "Keltner Mult", step=0.1, group=g_vol2)
dcLen = input.int(20, "Donchian Length", group=g_vol2)
squeezeLen = input.int(20, "Squeeze Linreg Length", group=g_vol2)
stcFast = input.int(23, "STC Fast", group=g_vol2)
stcSlow = input.int(50, "STC Slow", group=g_vol2)
stcCycle = input.int(10, "STC Cycle", group=g_vol2)
g_ichi = "⑥ Ichimoku / Alligator Lengths"
ichiConv = input.int(9, "Ichimoku Conversion (Tenkan)", group=g_ichi)
ichiBase = input.int(26, "Ichimoku Base (Kijun)", group=g_ichi)
ichiSpanB = input.int(52, "Ichimoku Span B", group=g_ichi)
alliJawLen = input.int(13, "Alligator Jaw Length", group=g_ichi)
alliJawShift = input.int(8, "Alligator Jaw Shift", group=g_ichi)
alliTeethLen = input.int(8, "Alligator Teeth Length", group=g_ichi)
alliTeethShift= input.int(5, "Alligator Teeth Shift", group=g_ichi)
alliLipsLen = input.int(5, "Alligator Lips Length", group=g_ichi)
alliLipsShift = input.int(3, "Alligator Lips Shift", group=g_ichi)
g_misc = "⑦ Aroon / AO / Elder Ray / DPO"
aroonLen = input.int(14, "Aroon Length", group=g_misc)
aoFastLen = input.int(5, "Awesome Oscillator Fast", group=g_misc)
aoSlowLen = input.int(34, "Awesome Oscillator Slow", group=g_misc)
elderEmaLen = input.int(13, "Elder Ray EMA Length", group=g_misc)
dpoLen = input.int(14, "DPO Length", group=g_misc)
g_prec = "⑧ Display Precision"
priceDec = input.int(2, "Price-Value Decimal Places (EMA/WMA/VWAP/BB/KC/DC/Pivots)", minval=0, maxval=6, group=g_prec)
oscDec = input.int(1, "Oscillator Decimal Places (RSI/ADX/CCI/etc)", minval=0, maxval=4, group=g_prec)
// ──────────────────────────────────────────────────────────────────
// ② PER-TABLE DISPLAY CONTROLS — every category fully independent
// ──────────────────────────────────────────────────────────────────
f_pos(p) =>
switch p
"Top Left" => position.top_left
"Top Right" => position.top_right
"Top Center" => position.top_center
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Middle Center" => position.middle_center
"Bottom Left" => position.bottom_left
"Bottom Center" => position.bottom_center
=> position.bottom_right
f_size(s) =>
switch s
"Tiny" => size.tiny
"Small" => size.small
"Large" => size.large
=> size.normal
g_combo = "📊 Combined TA Table (everything except payload)"
comboPos = f_pos(input.string("Middle Center", "Position", options=["Top Left", "Top Right", "Top Center", "Middle Left", "Middle Right", "Middle Center", "Bottom Left", "Bottom Right", "Bottom Center"], group=g_combo))
comboSz = f_size(input.string("Small", "Text Size", options=["Tiny", "Small", "Normal", "Large"], group=g_combo))
showMom = input.bool(true, "Show Momentum Section", group=g_combo)
showTrend = input.bool(true, "Show Trend / MA Section", group=g_combo)
showMacd = input.bool(true, "Show MACD / Volume Section", group=g_combo)
showVol = input.bool(true, "Show Volatility Section", group=g_combo)
showIchi = input.bool(true, "Show Ichimoku / VWAP / Pivots Section", group=g_combo)
showMisc = input.bool(true, "Show MTF RSI / Misc Section", group=g_combo)
g_pay = "📋 Table: Raw Paste Payload"
showPay = input.bool(true, "Show Payload Table", group=g_pay)
posPay = f_pos(input.string("Bottom Left", "Position", options=["Top Left", "Top Right", "Middle Left", "Middle Right", "Bottom Left", "Bottom Right"], group=g_pay))
szPay = f_size(input.string("Tiny", "Text Size", options=["Tiny", "Small", "Normal", "Large"], group=g_pay))
payRows = input.int(8, "Split Payload Into N Rows (raise if it still cuts off)", minval=1, maxval=12, group=g_pay)
// ──────────────────────────────────────────────────────────────────
// ③ CALCULATIONS (unchanged formulas — verified against Tradzy QSM)
// ──────────────────────────────────────────────────────────────────
f_donchianMid(len) => math.avg(ta.highest(high, len), ta.lowest(low, len))
tenkan_val = f_donchianMid(ichiConv)
kijun_val = f_donchianMid(ichiBase)
spanA_val = math.avg(tenkan_val, kijun_val)
spanB_val = f_donchianMid(ichiSpanB)
chikou_val = close
jaw_val = ta.wma(hl2, alliJawLen)[alliJawShift]
teeth_val = ta.wma(hl2, alliTeethLen)[alliTeethShift]
lips_val = ta.wma(hl2, alliLipsLen)[alliLipsShift]
vwap_val = ta.vwap(hlc3)
vwap_std = ta.stdev(close, 20)
vwap_u1 = vwap_val + 1 * vwap_std
vwap_l1 = vwap_val - 1 * vwap_std
vwap_u2 = vwap_val + 2 * vwap_std
vwap_l2 = vwap_val - 2 * vwap_std
vwap_pos_str = close > vwap_val ? "above" : "below"
ao_val = ta.sma(hl2, aoFastLen) - ta.sma(hl2, aoSlowLen)
ao_prev_val = ao_val[1]
elderEma = ta.ema(close, elderEmaLen)
bull_power = high - elderEma
bear_power = low - elderEma
dpo_val = close - ta.sma(close, dpoLen)[math.floor(dpoLen / 2) + 1]
cmo_val = ta.cmo(close, cmoLen)
[bb_mid, bb_upper, bb_lower] = ta.bb(close, bbLen, bbMult)
bb_width_val = (bb_upper - bb_lower) / bb_mid * 100
bb_pctb_val = (close - bb_lower) / (bb_upper - bb_lower)
bb_upper_price = ta.sma(close, bbLen) + bbMult * ta.stdev(close, bbLen)
bb_lower_price = ta.sma(close, bbLen) - bbMult * ta.stdev(close, bbLen)
bb_mid_price = ta.sma(close, bbLen)
kc_mid = ta.ema(close, kcLen)
kc_atr = ta.atr(kcAtrLen)
kc_upper = kc_mid + kcMult * kc_atr
kc_lower = kc_mid - kcMult * kc_atr
log_ret = math.log(close / close[1])
hv_val = ta.stdev(log_ret, hvLen) * math.sqrt(252) * 100
clv = ((close - low) - (high - close)) / (high - low)
ad_val = ta.cum(nz(clv * volume))
ad_prev = ad_val[1]
cmf_mfv = high != low ? ((close - low) - (high - close)) / (high - low) * volume : 0.0
cmf_val = math.sum(cmf_mfv, cmfLen) / math.sum(volume, cmfLen)
mfi_dx_val = (high - low) / volume
mfi_dx_prev = mfi_dx_val[1]
[plus_di, minus_di, adx_val] = ta.dmi(adxDiLen, adxLen)
mfi_val = ta.mfi(hlc3, mfiLen)
cci_val = ta.cci(hlc3, cciLen)
williams_val = ta.wpr(williamsLen)
[macd_line, macd_signal_line, macd_hist] = ta.macd(close, macdFast, macdSlow, macdSignal)
macd_val_now = macd_line
macd_val_prev = macd_line[1]
obv_val = ta.cum(volume * math.sign(ta.change(close)))
obv_val_prev = obv_val[1]
trix_e1 = ta.ema(close, 18)
trix_e2 = ta.ema(trix_e1, 18)
trix_e3 = ta.ema(trix_e2, 18)
trix_val = 100 * (trix_e3 - trix_e3[1]) / trix_e3[1]
roc_val = ta.roc(close, rocLen)
[supertrend_line, _stDir] = ta.supertrend(supertrendFactor, supertrendAtrLen)
supertrend_sig = close > supertrend_line ? 1 : -1
sar_val = ta.sar(sarStart, sarInc, sarMax)
ema9_val = ta.ema(close, ema9Len)
ema21_val = ta.ema(close, ema21Len)
ema50_val = ta.ema(close, ema50Len)
ema100_val = ta.ema(close, ema100Len)
ema200_val = ta.ema(close, ema200Len)
ema21_pos = close > ema21_val ? 1 : 0
vol_pct = volume / ta.sma(volume, volSmaLen) * 100
rvol_avg = ta.sma(volume, rvolLen)
rvol_val = rvol_avg > 0 ? volume / rvol_avg : 1.0
atr_pct = ta.atr(atrLen) / close * 100
atr_raw = ta.atr(atrLen)
tr_val = ta.tr(true)
rsi_val = ta.rsi(close, rsiLen)
rsi_prev = rsi_val[1]
stoch_k = ta.stoch(close, high, low, stochLen)
stoch_d = ta.sma(stoch_k, stochDLen)
stoch_rsi_k = ta.rsi(rsi_val, stochRsiLen)
rsi_htf1h = request.security(syminfo.tickerid, "60", ta.rsi(close, rsiLen), lookahead=barmerge.lookahead_off)
rsi_htf4h = request.security(syminfo.tickerid, "240", ta.rsi(close, rsiLen), lookahead=barmerge.lookahead_off)
rsi_htf1d = request.security(syminfo.tickerid, "1D", ta.rsi(close, rsiLen), lookahead=barmerge.lookahead_off)
wma20_val = ta.wma(close, wmaLen)
hma_val = ta.wma(2 * ta.wma(close, math.floor(hmaLen / 2)) - ta.wma(close, hmaLen), math.round(math.sqrt(hmaLen)))
hma_prev = hma_val[1]
vwma_val = ta.vwma(close, vwmaLen)
dema_e1 = ta.ema(close, demaLen)
dema_val = 2 * dema_e1 - ta.ema(dema_e1, demaLen)
tema_e1 = ta.ema(close, temaLen)
tema_e2 = ta.ema(tema_e1, temaLen)
tema_e3 = ta.ema(tema_e2, temaLen)
tema_val = 3 * tema_e1 - 3 * tema_e2 + tema_e3
lr_val = ta.linreg(close, lrLen, 0)
lr_prev = ta.linreg(close, lrLen, 1)
lr_slope = (lr_val - lr_prev) / close * 100
sqz_on = bb_lower > kc_lower and bb_upper < kc_upper
sqz_val = ta.linreg(close - math.avg(math.avg(ta.highest(high, squeezeLen), ta.lowest(low, squeezeLen)), ta.sma(close, squeezeLen)), squeezeLen, 0)
sqz_prev = ta.linreg(close - math.avg(math.avg(ta.highest(high, squeezeLen), ta.lowest(low, squeezeLen)), ta.sma(close, squeezeLen)), squeezeLen, 1)
chop_atr = math.sum(ta.atr(1), chopLen)
chop_hl = ta.highest(high, chopLen) - ta.lowest(low, chopLen)
chop_val = 100 * math.log10(chop_atr / chop_hl) / math.log10(chopLen)
dc_upper = ta.highest(high, dcLen)
dc_lower = ta.lowest(low, dcLen)
dc_mid = (dc_upper + dc_lower) / 2
stc_macd = ta.ema(close, stcFast) - ta.ema(close, stcSlow)
stc_d1_h = ta.highest(stc_macd, stcCycle)
stc_d1_l = ta.lowest(stc_macd, stcCycle)
var float stc_f1 = na
stc_f1 := stc_d1_h != stc_d1_l ? (stc_macd - stc_d1_l) / (stc_d1_h - stc_d1_l) * 100 : nz(stc_f1[1])
stc_pf1 = ta.ema(stc_f1, 2)
stc_d2_h = ta.highest(stc_pf1, stcCycle)
stc_d2_l = ta.lowest(stc_pf1, stcCycle)
var float stc_f2 = na
stc_f2 := stc_d2_h != stc_d2_l ? (stc_pf1 - stc_d2_l) / (stc_d2_h - stc_d2_l) * 100 : nz(stc_f2[1])
stc_val = ta.ema(stc_f2, 2)
stc_prev = stc_val[1]
vol_up = volume * (close > open ? 1 : 0)
vol_dn = volume * (close < open ? 1 : 0)
vol_delta = ta.ema(vol_up - vol_dn, volDeltaLen)
vol_d_prev= vol_delta[1]
pp_val = (high[1] + low[1] + close[1]) / 3
r1_val = 2 * pp_val - low[1]
s1_val = 2 * pp_val - high[1]
r2_val = pp_val + (high[1] - low[1])
s2_val = pp_val - (high[1] - low[1])
aroon_up = (ta.highestbars(high, aroonLen + 1) + aroonLen) / aroonLen * 100
aroon_dn = (ta.lowestbars(low, aroonLen + 1) + aroonLen) / aroonLen * 100
// ──────────────────────────────────────────────────────────────────
// ④ "key=value" STRINGS — single source of truth
// priceDec controls price-like values, oscDec controls oscillators
// ──────────────────────────────────────────────────────────────────
kv_rsi = "rsi=" + str.tostring(math.round(rsi_val, oscDec))
kv_rsiPrev = "rsiPrev=" + str.tostring(math.round(rsi_prev, oscDec))
kv_stoch = "stoch=" + str.tostring(math.round(stoch_k, oscDec))
kv_stochD = "stochD=" + str.tostring(math.round(stoch_d, oscDec))
kv_stochRsiK = "stochRsiK=" + str.tostring(math.round(stoch_rsi_k, oscDec))
kv_adx = "adx=" + str.tostring(math.round(adx_val, oscDec))
kv_plusDI = "plusDI=" + str.tostring(math.round(plus_di, oscDec))
kv_minusDI = "minusDI=" + str.tostring(math.round(minus_di, oscDec))
kv_cci = "cci=" + str.tostring(math.round(cci_val, oscDec))
kv_williams = "williams=" + str.tostring(math.round(williams_val, oscDec))
kv_mfi = "mfi=" + str.tostring(math.round(mfi_val, oscDec))
kv_rocVal = "rocVal=" + str.tostring(math.round(roc_val, oscDec))
kv_cmo = "cmo=" + str.tostring(math.round(cmo_val, oscDec))
kv_ema9 = "ema9=" + str.tostring(math.round(ema9_val, priceDec))
kv_ema21 = "ema21=" + str.tostring(math.round(ema21_val, priceDec))
kv_ema21pos = "ema21pos=" + str.tostring(ema21_pos)
kv_ema50 = "ema50=" + str.tostring(math.round(ema50_val, priceDec))
kv_ema100 = "ema100=" + str.tostring(math.round(ema100_val, priceDec))
kv_ema200 = "ema200=" + str.tostring(math.round(ema200_val, priceDec))
kv_wma20 = "wma20=" + str.tostring(math.round(wma20_val, priceDec))
kv_hmaVal = "hmaVal=" + str.tostring(math.round(hma_val, priceDec))
kv_hmaPrev = "hmaPrev=" + str.tostring(math.round(hma_prev, priceDec))
kv_vwmaVal = "vwmaVal=" + str.tostring(math.round(vwma_val, priceDec))
kv_demaVal = "demaVal=" + str.tostring(math.round(dema_val, priceDec))
kv_temaVal = "temaVal=" + str.tostring(math.round(tema_val, priceDec))
kv_supertrend = "supertrend=" + str.tostring(supertrend_sig)
kv_sarVal = "sarVal=" + str.tostring(math.round(sar_val, priceDec))
kv_lrSlope = "lrSlope=" + str.tostring(math.round(lr_slope, priceDec))
kv_macdVal = "macdVal=" + str.tostring(math.round(macd_val_now, priceDec + 2))
kv_macdPrev = "macdPrev=" + str.tostring(math.round(macd_val_prev, priceDec + 2))
kv_obvVal = "obvVal=" + str.tostring(math.round(obv_val, 0))
kv_obvPrev = "obvPrev=" + str.tostring(math.round(obv_val_prev, 0))
kv_adVal = "adVal=" + str.tostring(math.round(ad_val, 0))
kv_adPrev = "adPrev=" + str.tostring(math.round(ad_prev, 0))
kv_cmf = "cmf=" + str.tostring(math.round(cmf_val, 3))
kv_volPct = "volPct=" + str.tostring(math.round(vol_pct, oscDec))
kv_rvolVal = "rvolVal=" + str.tostring(math.round(rvol_val, 3))
kv_volDelta = "volDelta=" + str.tostring(math.round(vol_delta, 0))
kv_volDeltaPrev = "volDeltaPrev=" + str.tostring(math.round(vol_d_prev, 0))
kv_mfiDx = "mfiDx=" + str.tostring(math.round(mfi_dx_val, 6))
kv_mfiDxPrev = "mfiDxPrev=" + str.tostring(math.round(mfi_dx_prev, 6))
kv_atrPct = "atrPct=" + str.tostring(math.round(atr_pct, oscDec))
kv_atrRaw = "atrRaw=" + str.tostring(math.round(atr_raw, priceDec))
kv_trVal = "trVal=" + str.tostring(math.round(tr_val, priceDec))
kv_bbWidth = "bbWidth=" + str.tostring(math.round(bb_width_val, oscDec))
kv_bbPctB = "bbPctB=" + str.tostring(math.round(bb_pctb_val, 3))
kv_bbUpperPrice = "bbUpperPrice=" + str.tostring(math.round(bb_upper_price, priceDec))
kv_bbLowerPrice = "bbLowerPrice=" + str.tostring(math.round(bb_lower_price, priceDec))
kv_bbMidPrice = "bbMidPrice=" + str.tostring(math.round(bb_mid_price, priceDec))
kv_hv = "hv=" + str.tostring(math.round(hv_val, oscDec))
kv_chopVal = "chopVal=" + str.tostring(math.round(chop_val, oscDec))
kv_kcUpper = "kcUpper=" + str.tostring(math.round(kc_upper, priceDec))
kv_kcLower = "kcLower=" + str.tostring(math.round(kc_lower, priceDec))
kv_dcUpper = "dcUpper=" + str.tostring(math.round(dc_upper, priceDec))
kv_dcLower = "dcLower=" + str.tostring(math.round(dc_lower, priceDec))
kv_dcMid = "dcMid=" + str.tostring(math.round(dc_mid, priceDec))
kv_sqzOn = "sqzOn=" + str.tostring(sqz_on ? 1 : 0)
kv_sqzVal = "sqzVal=" + str.tostring(math.round(sqz_val, priceDec))
kv_sqzPrev = "sqzPrev=" + str.tostring(math.round(sqz_prev, priceDec))
kv_stcVal = "stcVal=" + str.tostring(math.round(stc_val, oscDec))
kv_stcPrev = "stcPrev=" + str.tostring(math.round(stc_prev, oscDec))
kv_tenkan = "tenkan=" + str.tostring(math.round(tenkan_val, priceDec))
kv_kijun = "kijun=" + str.tostring(math.round(kijun_val, priceDec))
kv_spanA = "spanA=" + str.tostring(math.round(spanA_val, priceDec))
kv_spanB = "spanB=" + str.tostring(math.round(spanB_val, priceDec))
kv_chikou = "chikou=" + str.tostring(math.round(chikou_val, priceDec))
kv_jaw = "jaw=" + str.tostring(math.round(jaw_val, priceDec))
kv_teeth = "teeth=" + str.tostring(math.round(teeth_val, priceDec))
kv_lips = "lips=" + str.tostring(math.round(lips_val, priceDec))
kv_vwapVal = "vwapVal=" + str.tostring(math.round(vwap_val, priceDec))
kv_vwapPos = "vwapPos=" + vwap_pos_str
kv_vwapU1 = "vwapU1=" + str.tostring(math.round(vwap_u1, priceDec))
kv_vwapL1 = "vwapL1=" + str.tostring(math.round(vwap_l1, priceDec))
kv_vwapU2 = "vwapU2=" + str.tostring(math.round(vwap_u2, priceDec))
kv_vwapL2 = "vwapL2=" + str.tostring(math.round(vwap_l2, priceDec))
kv_pp = "pp=" + str.tostring(math.round(pp_val, priceDec))
kv_r1 = "r1=" + str.tostring(math.round(r1_val, priceDec))
kv_s1 = "s1=" + str.tostring(math.round(s1_val, priceDec))
kv_r2 = "r2=" + str.tostring(math.round(r2_val, priceDec))
kv_s2 = "s2=" + str.tostring(math.round(s2_val, priceDec))
kv_rsi1h = "rsi1h=" + str.tostring(math.round(rsi_htf1h, oscDec))
kv_rsi4h = "rsi4h=" + str.tostring(math.round(rsi_htf4h, oscDec))
kv_rsi1d = "rsi1d=" + str.tostring(math.round(rsi_htf1d, oscDec))
kv_aroonUp = "aroonUp=" + str.tostring(math.round(aroon_up, oscDec))
kv_aroonDn = "aroonDn=" + str.tostring(math.round(aroon_dn, oscDec))
kv_ao = "ao=" + str.tostring(math.round(ao_val, priceDec))
kv_aoPrev = "aoPrev=" + str.tostring(math.round(ao_prev_val, priceDec))
kv_bullPower = "bullPower=" + str.tostring(math.round(bull_power, priceDec))
kv_bearPower = "bearPower=" + str.tostring(math.round(bear_power, priceDec))
kv_dpo = "dpo=" + str.tostring(math.round(dpo_val, priceDec))
kv_trixVal = "trixVal=" + str.tostring(math.round(trix_val, priceDec))
// ── DERIVED / ALIAS FIELDS — fills every slot the app reads automatically ──
//
// Aliases (app accepts both key names; send both so either parser path works)
kv_diPlus = "diPlus=" + str.tostring(math.round(plus_di, oscDec))
kv_diMinus = "diMinus=" + str.tostring(math.round(minus_di, oscDec))
kv_priceAlias = "price=" + str.tostring(math.round(close, priceDec))
kv_rsiVal = "rsiVal=" + str.tostring(math.round(rsi_val, oscDec))
// Previous session OHLC (high[1]/low[1]/close[1])
kv_prevH = "prevH=" + str.tostring(math.round(high[1], priceDec))
kv_prevL = "prevL=" + str.tostring(math.round(low[1], priceDec))
kv_prevC = "prevC=" + str.tostring(math.round(close[1], priceDec))
// ── ASSET MOVE % (feeds Position Calculator's volatility finder: move-1d/1w/1m/1y) ──
// Pulls prior close from each higher timeframe via request.security, then computes
// the % move from that close to current price. lookahead_off avoids future-leak.
_move1dRef = request.security(syminfo.tickerid, "D", close[1], lookahead=barmerge.lookahead_off)
_move1wRef = request.security(syminfo.tickerid, "W", close[1], lookahead=barmerge.lookahead_off)
_move1mRef = request.security(syminfo.tickerid, "M", close[1], lookahead=barmerge.lookahead_off)
_move1yRef = request.security(syminfo.tickerid, "12M", close[1], lookahead=barmerge.lookahead_off)
_move1d = _move1dRef > 0 ? (close - _move1dRef) / _move1dRef * 100 : na
_move1w = _move1wRef > 0 ? (close - _move1wRef) / _move1wRef * 100 : na
_move1m = _move1mRef > 0 ? (close - _move1mRef) / _move1mRef * 100 : na
_move1y = _move1yRef > 0 ? (close - _move1yRef) / _move1yRef * 100 : na
kv_move1d = "move1d=" + (na(_move1d) ? "0" : str.tostring(math.round(math.abs(_move1d), 2)))
kv_move1w = "move1w=" + (na(_move1w) ? "0" : str.tostring(math.round(math.abs(_move1w), 2)))
kv_move1m = "move1m=" + (na(_move1m) ? "0" : str.tostring(math.round(math.abs(_move1m), 2)))
kv_move1y = "move1y=" + (na(_move1y) ? "0" : str.tostring(math.round(math.abs(_move1y), 2)))
// ── PRICE 3 DAYS AGO (feeds QSM drop-filter: qsm-price-3d) ──
// Daily close from 3 trading days back. Validated rule: RSI<30 + drop>5% over
// 3 days = 75% accuracy (vs 59% baseline) — see app tooltip on qsm-price-3d.
_price3dRef = request.security(syminfo.tickerid, "D", close[3], lookahead=barmerge.lookahead_off)
kv_price3d = "price3d=" + (na(_price3dRef) ? "0" : str.tostring(math.round(_price3dRef, priceDec)))
// RSI condition: rising / falling / flat (threshold ±1 point to avoid noise)
_rsiDelta = rsi_val - rsi_prev
kv_rsiCond = "rsiCond=" + (_rsiDelta > 1.0 ? "rising" : _rsiDelta < -1.0 ? "falling" : "flat")
// EMA position: how many EMAs price is above (9/21/50/100/200)
_emaCnt = (close > ema9_val ? 1 : 0) + (close > ema21_val ? 1 : 0) + (close > ema50_val ? 1 : 0) + (close > ema100_val ? 1 : 0) + (close > ema200_val ? 1 : 0)
kv_emaPos = "emaPos=" + (_emaCnt >= 4 ? "above-all" : _emaCnt >= 2 ? "mixed-above" : _emaCnt >= 1 ? "mixed-below" : "below-all")
// Volume regime: derived from volPct thresholds
kv_volRegime = "volRegime=" + (vol_pct > 200 ? "extreme" : vol_pct > 120 ? "high" : vol_pct > 80 ? "normal" : "low")
// BB chip: overbought/squeeze/oversold from bbPctB
kv_bb = "bb=" + (bb_pctb_val > 0.8 ? "overbought" : bb_pctb_val < 0.2 ? "oversold" : "squeeze")
// Ichimoku chip: bullish / bearish / neutral — price above/below the cloud (spanA & spanB)
_ichiCloudTop = math.max(spanA_val, spanB_val)
_ichiCloudBot = math.min(spanA_val, spanB_val)
kv_ichi = "ichi=" + (close > _ichiCloudTop ? "bullish" : close < _ichiCloudBot ? "bearish" : "neutral")
// Pivot position chip: above-pivot / below-pivot from classical daily pivot
kv_pivotPos = "pivotPos=" + (close > pp_val ? "above-pivot" : "below-pivot")
// MTF bias chip: bull / bear / mixed from 1h, 4h, 1d RSI vs 50 midline
_mtfBull = (rsi_htf1h > 50 ? 1 : 0) + (rsi_htf4h > 50 ? 1 : 0) + (rsi_htf1d > 50 ? 1 : 0)
kv_mtfBias = "mtfBias=" + (_mtfBull >= 3 ? "full-bull" : _mtfBull >= 2 ? "mixed-bull" : _mtfBull >= 1 ? "mixed-bear" : "full-bear")
// HTF alignment chip: full-align / partial / against-htf (vs current TF RSI direction)
_curRsiDir = rsi_val > 50
_htfAlignCnt = (_curRsiDir == (rsi_htf1h > 50) ? 1 : 0) + (_curRsiDir == (rsi_htf4h > 50) ? 1 : 0) + (_curRsiDir == (rsi_htf1d > 50) ? 1 : 0)
kv_htfAlign = "htfAlign=" + (_htfAlignCnt >= 3 ? "full-align" : _htfAlignCnt >= 2 ? "partial" : "against-htf")
// timeframe.period returns raw TV values ("1","5","15","60","240","1D","1W"...)
// but the Tradzy app's TF_CONFIG / timeframe pills key off short labels
// ("1m","5m","15m","1h","4h","1d","1w"). Convert so TV Import sets the
// correct timeframe pill + adaptive config instead of silently failing
// to match (e.g. raw "240" never matches the "4h" pill).
f_tfLabel() =>
switch timeframe.period
"1" => "1m"
"3" => "3m"
"5" => "5m"
"15" => "15m"
"30" => "30m"
"45" => "45m"
"60" => "1h"
"120" => "2h"
"180" => "3h"
"240" => "4h"
"1D" => "1d"
"1W" => "1w"
"1M" => "1mo"
=> timeframe.period
kv_ticker = "ticker=" + syminfo.ticker
kv_tf = "tf=" + f_tfLabel()
kv_price = "qsmPrice=" + str.tostring(math.round(close, priceDec))
// ──────────────────────────────────────────────────────────────────
// ⑤ TABLE-DRAWING ENGINE
// Each category builds an array of "label","value" strings.
// All sections get written into ONE combined table object
// (no overlap), stacked top-to-bottom, 5 pairs per row.
// ──────────────────────────────────────────────────────────────────
clrBgA = color.new(#0a0a0a, 0)
clrBgB = color.new(#141414, 0)
clrLbl = color.rgb(138, 160, 184)
clrVal = color.rgb(184, 245, 0)
clrLime = color.rgb(184, 245, 0)
clrLime2 = color.rgb(140, 200, 0)
clrBlack = color.new(#000000, 0)
PAIRS_PER_ROW = 5
COLS = PAIRS_PER_ROW * 2
f_pushKV(arr, lbl, val) =>
array.push(arr, lbl)
array.push(arr, val)
f_dataRows(kvArr) =>
n = array.size(kvArr) / 2
int(math.ceil(n / float(PAIRS_PER_ROW)))
// Draws one section (title row + its grid rows) starting at row `startRow`
// inside an already-created table. Returns the next free row index.
f_drawSection(tbl, startRow, titleTxt, kvArr, sz) =>
n = array.size(kvArr) / 2
dataRows = f_dataRows(kvArr)
table.cell(tbl, 0, startRow, titleTxt, text_color=clrBlack, text_size=sz, bgcolor=clrLime, text_halign=text.align_left)
table.merge_cells(tbl, 0, startRow, COLS - 1, startRow)
idx = 0
for r = 0 to dataRows - 1
rowNum = startRow + 1 + r
bg = r % 2 == 0 ? clrBgA : clrBgB
for c = 0 to PAIRS_PER_ROW - 1
lblCol = c * 2
valCol = c * 2 + 1
if idx < n
lbl = array.get(kvArr, idx * 2)
val = array.get(kvArr, idx * 2 + 1)
table.cell(tbl, lblCol, rowNum, lbl, text_color=clrLbl, text_size=sz, bgcolor=bg, text_halign=text.align_left)
table.cell(tbl, valCol, rowNum, val, text_color=clrVal, text_size=sz, bgcolor=bg, text_halign=text.align_left)
else
table.cell(tbl, lblCol, rowNum, "", text_color=clrLbl, text_size=sz, bgcolor=bg)
table.cell(tbl, valCol, rowNum, "", text_color=clrVal, text_size=sz, bgcolor=bg)
idx += 1
startRow + 1 + dataRows
// ──────────────────────────────────────────────────────────────────
// ⑥ PAYLOAD SPLITTER — breaks the big "|" joined string into N
// rows, only cutting at "|" boundaries, so nothing is sliced
// mid-field. Raise "Split Payload Into N Rows" if a line is
// still too long to read/copy on your screen.
// ──────────────────────────────────────────────────────────────────
f_drawPayload(pos, sz, rows, payloadStr) =>
tokens = str.split(payloadStr, "|")
ntok = array.size(tokens)
totalLen = str.length(payloadStr)
targetLen = totalLen / rows
lines = array.new<string>()
curLine = ""
for i = 0 to ntok - 1
tok = array.get(tokens, i)
candidate = curLine == "" ? tok : curLine + "|" + tok
if str.length(candidate) > targetLen and curLine != "" and array.size(lines) < rows - 1
array.push(lines, curLine)
curLine := tok
else
curLine := candidate
array.push(lines, curLine)
nLines = array.size(lines)
tbl = table.new(pos, 1, nLines + 1, border_width=1, border_color=color.new(#1a1a1a, 0), frame_color=color.new(#1a1a1a, 0), frame_width=1)
table.cell(tbl, 0, 0, "◈ RAW PASTE PAYLOAD — copy each line into Tradzy TV Import", text_color=clrBlack, text_size=sz, bgcolor=clrLime, text_halign=text.align_left)
for i = 0 to nLines - 1
bg = i % 2 == 0 ? clrBgA : clrBgB
table.cell(tbl, 0, i + 1, array.get(lines, i), text_color=clrLime, text_size=sz, bgcolor=bg, text_halign=text.align_left)
// ──────────────────────────────────────────────────────────────────
// ⑦ BUILD + DRAW (only on the last bar)
// ──────────────────────────────────────────────────────────────────
if barstate.islast
momArr = array.new<string>()
f_pushKV(momArr, "Symbol", kv_ticker)
f_pushKV(momArr, "Timeframe", kv_tf)
f_pushKV(momArr, "Price", kv_price)
f_pushKV(momArr, "RSI", kv_rsi)
f_pushKV(momArr, "RSI Prev", kv_rsiPrev)
f_pushKV(momArr, "Stoch%K", kv_stoch)
f_pushKV(momArr, "Stoch%D", kv_stochD)
f_pushKV(momArr, "StochRSI%K", kv_stochRsiK)
f_pushKV(momArr, "ADX", kv_adx)
f_pushKV(momArr, "+DI", kv_plusDI)
f_pushKV(momArr, "-DI", kv_minusDI)
f_pushKV(momArr, "CCI", kv_cci)
f_pushKV(momArr, "Williams%R", kv_williams)
f_pushKV(momArr, "MFI", kv_mfi)
f_pushKV(momArr, "ROC", kv_rocVal)
f_pushKV(momArr, "CMO", kv_cmo)
trendArr = array.new<string>()
f_pushKV(trendArr, "EMA9", kv_ema9)
f_pushKV(trendArr, "EMA21", kv_ema21)
f_pushKV(trendArr, "EMA21pos", kv_ema21pos)
f_pushKV(trendArr, "EMA50", kv_ema50)
f_pushKV(trendArr, "EMA100", kv_ema100)
f_pushKV(trendArr, "EMA200", kv_ema200)
f_pushKV(trendArr, "WMA", kv_wma20)
f_pushKV(trendArr, "Hull", kv_hmaVal)
f_pushKV(trendArr, "Hull Prev", kv_hmaPrev)
f_pushKV(trendArr, "VWMA", kv_vwmaVal)
f_pushKV(trendArr, "DEMA", kv_demaVal)
f_pushKV(trendArr, "TEMA", kv_temaVal)
f_pushKV(trendArr, "Supertrend", kv_supertrend)
f_pushKV(trendArr, "SAR", kv_sarVal)
f_pushKV(trendArr, "LR Slope%", kv_lrSlope)
macdArr = array.new<string>()
f_pushKV(macdArr, "MACD", kv_macdVal)
f_pushKV(macdArr, "MACD Prev", kv_macdPrev)
f_pushKV(macdArr, "OBV", kv_obvVal)
f_pushKV(macdArr, "OBV Prev", kv_obvPrev)
f_pushKV(macdArr, "A/D", kv_adVal)
f_pushKV(macdArr, "A/D Prev", kv_adPrev)
f_pushKV(macdArr, "CMF", kv_cmf)
f_pushKV(macdArr, "Vol%", kv_volPct)
f_pushKV(macdArr, "RVOL", kv_rvolVal)
f_pushKV(macdArr, "VolDelta", kv_volDelta)
f_pushKV(macdArr, "VolDeltaPrev", kv_volDeltaPrev)
f_pushKV(macdArr, "MFI-DX", kv_mfiDx)
f_pushKV(macdArr, "MFI-DX Prev", kv_mfiDxPrev)
volArr = array.new<string>()
f_pushKV(volArr, "ATR%", kv_atrPct)
f_pushKV(volArr, "ATR raw", kv_atrRaw)
f_pushKV(volArr, "TrueRange", kv_trVal)
f_pushKV(volArr, "BBWidth", kv_bbWidth)
f_pushKV(volArr, "BB%B", kv_bbPctB)
f_pushKV(volArr, "BB Upper", kv_bbUpperPrice)
f_pushKV(volArr, "BB Lower", kv_bbLowerPrice)
f_pushKV(volArr, "BB Mid", kv_bbMidPrice)
f_pushKV(volArr, "HV", kv_hv)
f_pushKV(volArr, "Choppiness", kv_chopVal)
f_pushKV(volArr, "KC Upper", kv_kcUpper)
f_pushKV(volArr, "KC Lower", kv_kcLower)
f_pushKV(volArr, "DC Upper", kv_dcUpper)
f_pushKV(volArr, "DC Lower", kv_dcLower)
f_pushKV(volArr, "DC Mid", kv_dcMid)
f_pushKV(volArr, "SqzOn", kv_sqzOn)
f_pushKV(volArr, "Sqz Val", kv_sqzVal)
f_pushKV(volArr, "Sqz Prev", kv_sqzPrev)
f_pushKV(volArr, "STC", kv_stcVal)
f_pushKV(volArr, "STC Prev", kv_stcPrev)
ichiArr = array.new<string>()
f_pushKV(ichiArr, "Tenkan", kv_tenkan)
f_pushKV(ichiArr, "Kijun", kv_kijun)
f_pushKV(ichiArr, "Span A", kv_spanA)
f_pushKV(ichiArr, "Span B", kv_spanB)
f_pushKV(ichiArr, "Chikou", kv_chikou)
f_pushKV(ichiArr, "Jaw", kv_jaw)
f_pushKV(ichiArr, "Teeth", kv_teeth)
f_pushKV(ichiArr, "Lips", kv_lips)
f_pushKV(ichiArr, "VWAP", kv_vwapVal)
f_pushKV(ichiArr, "VWAP Pos", kv_vwapPos)
f_pushKV(ichiArr, "VWAP+1σ", kv_vwapU1)
f_pushKV(ichiArr, "VWAP-1σ", kv_vwapL1)
f_pushKV(ichiArr, "VWAP+2σ", kv_vwapU2)
f_pushKV(ichiArr, "VWAP-2σ", kv_vwapL2)
f_pushKV(ichiArr, "Pivot", kv_pp)
f_pushKV(ichiArr, "R1", kv_r1)
f_pushKV(ichiArr, "S1", kv_s1)
f_pushKV(ichiArr, "R2", kv_r2)
f_pushKV(ichiArr, "S2", kv_s2)
miscArr = array.new<string>()
f_pushKV(miscArr, "1H RSI", kv_rsi1h)
f_pushKV(miscArr, "4H RSI", kv_rsi4h)
f_pushKV(miscArr, "1D RSI", kv_rsi1d)
f_pushKV(miscArr, "Aroon Up", kv_aroonUp)
f_pushKV(miscArr, "Aroon Dn", kv_aroonDn)
f_pushKV(miscArr, "AO", kv_ao)
f_pushKV(miscArr, "AO Prev", kv_aoPrev)
f_pushKV(miscArr, "Bull Pwr", kv_bullPower)
f_pushKV(miscArr, "Bear Pwr", kv_bearPower)
f_pushKV(miscArr, "DPO", kv_dpo)
f_pushKV(miscArr, "TRIX", kv_trixVal)
f_pushKV(miscArr, "Move 1D%", kv_move1d)
f_pushKV(miscArr, "Move 1W%", kv_move1w)
f_pushKV(miscArr, "Move 1M%", kv_move1m)
f_pushKV(miscArr, "Move 1Y%", kv_move1y)
f_pushKV(miscArr, "Price 3D Ago", kv_price3d)
// ── compute total rows needed for the combined table ──
totalRows = 0
totalRows += showMom ? 1 + f_dataRows(momArr) : 0
totalRows += showTrend ? 1 + f_dataRows(trendArr) : 0
totalRows += showMacd ? 1 + f_dataRows(macdArr) : 0
totalRows += showVol ? 1 + f_dataRows(volArr) : 0
totalRows += showIchi ? 1 + f_dataRows(ichiArr) : 0
totalRows += showMisc ? 1 + f_dataRows(miscArr) : 0
if totalRows > 0
comboTbl = table.new(comboPos, COLS, totalRows, border_width=1, border_color=color.new(#1a1a1a, 0), frame_color=color.new(#1a1a1a, 0), frame_width=1)
rowPtr = 0
if showMom
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ MOMENTUM", momArr, comboSz)
if showTrend
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ TREND / MOVING AVERAGES", trendArr, comboSz)
if showMacd
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ MACD / VOLUME", macdArr, comboSz)
if showVol
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ VOLATILITY", volArr, comboSz)
if showIchi
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ ICHIMOKU / VWAP / PIVOTS", ichiArr, comboSz)
if showMisc
rowPtr := f_drawSection(comboTbl, rowPtr, "◈ MTF RSI / MISC", miscArr, comboSz)
// ── PAYLOAD (own separate table, splits into payRows lines) ──
if showPay
// ── BLOCK 1: Identity + Momentum ──
p1 = kv_ticker + "|" + kv_tf + "|" + kv_price + "|" + kv_priceAlias + "|" + kv_rsiVal + "|" + kv_rsi + "|" + kv_rsiPrev + "|" + kv_rsiCond + "|" + kv_stoch + "|" + kv_stochD + "|" + kv_stochRsiK + "|" + kv_adx + "|" + kv_plusDI + "|" + kv_minusDI + "|" + kv_diPlus + "|" + kv_diMinus + "|" + kv_cci + "|" + kv_williams + "|" + kv_mfi + "|" + kv_rocVal + "|" + kv_cmo
// ── BLOCK 2: Trend / MAs ──
p2 = kv_ema9 + "|" + kv_ema21 + "|" + kv_ema21pos + "|" + kv_ema50 + "|" + kv_ema100 + "|" + kv_ema200 + "|" + kv_emaPos + "|" + kv_wma20 + "|" + kv_hmaVal + "|" + kv_hmaPrev + "|" + kv_vwmaVal + "|" + kv_demaVal + "|" + kv_temaVal + "|" + kv_supertrend + "|" + kv_sarVal + "|" + kv_lrSlope
// ── BLOCK 3: MACD / Volume ──
p3 = kv_macdVal + "|" + kv_macdPrev + "|" + kv_obvVal + "|" + kv_obvPrev + "|" + kv_adVal + "|" + kv_adPrev + "|" + kv_cmf + "|" + kv_volPct + "|" + kv_rvolVal + "|" + kv_volDelta + "|" + kv_volDeltaPrev + "|" + kv_mfiDx + "|" + kv_mfiDxPrev + "|" + kv_volRegime
// ── BLOCK 4: Volatility ──
p4 = kv_atrPct + "|" + kv_atrRaw + "|" + kv_trVal + "|" + kv_bbWidth + "|" + kv_bbPctB + "|" + kv_bbUpperPrice + "|" + kv_bbLowerPrice + "|" + kv_bbMidPrice + "|" + kv_bb + "|" + kv_hv + "|" + kv_chopVal + "|" + kv_kcUpper + "|" + kv_kcLower + "|" + kv_dcUpper + "|" + kv_dcLower + "|" + kv_dcMid + "|" + kv_sqzOn + "|" + kv_sqzVal + "|" + kv_sqzPrev + "|" + kv_stcVal + "|" + kv_stcPrev
// ── BLOCK 5: Ichimoku / VWAP / Pivots ──
p5 = kv_tenkan + "|" + kv_kijun + "|" + kv_spanA + "|" + kv_spanB + "|" + kv_chikou + "|" + kv_ichi + "|" + kv_jaw + "|" + kv_teeth + "|" + kv_lips + "|" + kv_vwapVal + "|" + kv_vwapPos + "|" + kv_vwapU1 + "|" + kv_vwapL1 + "|" + kv_vwapU2 + "|" + kv_vwapL2 + "|" + kv_pp + "|" + kv_r1 + "|" + kv_s1 + "|" + kv_r2 + "|" + kv_s2 + "|" + kv_pivotPos
// ── BLOCK 6: MTF / Misc / Derived ──
p6 = kv_rsi1h + "|" + kv_rsi4h + "|" + kv_rsi1d + "|" + kv_mtfBias + "|" + kv_htfAlign + "|" + kv_aroonUp + "|" + kv_aroonDn + "|" + kv_ao + "|" + kv_aoPrev + "|" + kv_bullPower + "|" + kv_bearPower + "|" + kv_dpo + "|" + kv_trixVal
// ── BLOCK 7: Previous session + price aliases ──
p7 = kv_prevH + "|" + kv_prevL + "|" + kv_prevC
// ── BLOCK 8: Asset Move % (volatility finder) ──
p8 = kv_move1d + "|" + kv_move1w + "|" + kv_move1m + "|" + kv_move1y + "|" + kv_price3d
fullPayload = p1 + "|" + p2 + "|" + p3 + "|" + p4 + "|" + p5 + "|" + p6 + "|" + p7 + "|" + p8
f_drawPayload(posPay, szPay, payRows, fullPayload)