TradingView indicator guides

VuManChu Cipher A: Exact Signal Rules and Pine Script

This implementation combines eight close-based EMAs with WaveTrend and RSI. Its eight marker conditions are different Boolean tests, not eight independent confirmations. The copy below uses fixed settings; five threshold arguments do nothing, and the component called RSI+MFI contains no volume. The guide explains those boundaries before interpreting the shapes.

Inspect the Pine Script

Identify the version before comparing signals

VuManChu Cipher A by vumanchu is a public TradingView publication dated November 11, 2019. The code on this page is Pineify’s v6 implementation. A shared name does not establish equivalence with every community revision or a commercial indicator.

The eight close EMAs have lengths 5, 11, 15, 18, 21, 24, 28 and 34. The fifth is 21, not 17. Their blue shades distinguish periods; the code does not switch the ribbon’s color according to trend, rank all eight lines, or require five lines to slope together.

Separate the three calculations

WaveTrend starts with ESA = EMA(hlc3, 9), DE = EMA(abs(hlc3 − ESA), 9), and CI = (hlc3 − ESA) / (0.015 × DE). WT1 is EMA(CI, 13), and WT2 is SMA(WT1, 3). The separately calculated RSI uses close and length 14. Neither oscillator is plotted as a lower-pane line here; they feed selected shapes.

The misleadingly named RSI+MFI component is SMA(150 × (close − open) / (high − low), 60), requested in the chart’s own timeframe. It is a smoothed signed candle-body fraction. It does not call RSI or standard MFI, use volume, identify aggressive buyers, or measure institutional money flow.

For a hypothetical bar with open 100, high 104, low 99 and close 102, the body fraction is 2/5 and the scaled contribution is 60. With 59 preceding valid contributions of zero, the 60-observation mean is 1; a single positive candle therefore need not make the smoothed series positive if preceding contributions were negative. A doji with a nonzero range contributes zero. A zero-range bar instead divides by zero: this implementation has no explicit replacement or full-window validity policy. WaveTrend likewise lacks a guard when DE is zero.

Read each marker as its actual condition

  • Long EMA: EMA 11 crosses above EMA 34. Short EMA: EMA 34 crosses above EMA 11. Both use circles, green and red respectively.
  • Red Cross: EMA 5 crosses below EMA 11. Blue Triangle: EMA 11 crosses above EMA 15. Neither condition includes RSI, volume or WaveTrend.
  • Red Diamond: WT1 crosses below WT2. There is no overbought requirement, so it can appear below zero as well as above it.
  • Blood Diamond: Red Diamond and Red Cross occur on the same bar. One event followed by the other a bar later does not qualify. Co-occurrence alone establishes no higher win rate.
  • Yellow Cross: Red Diamond is true, −80 < WT2 < 45, 15 < RSI < 30, and the body/range SMA is below −5. All these inequalities are strict. This is a downward WaveTrend crossover under additional conditions, not a bullish reversal confirmation.
  • Bull Candle: the current open is above the current EMA 11 and EMA 34, both the preceding and current candles close above their own opens, and neither Red Diamond nor Red Cross is true. It is a yellow diamond. It does not test all eight EMA slopes or prove buying aggression.

All eight marker types are drawn above bars, including the green circle and blue upward triangle. Their location is a display choice, not a stop price, entry fill or direction of an order.

Check the boundaries with synthetic values

Suppose the prior WT1/WT2 values are 10/9 and the current values are 8/9. WT1 moved from above WT2 to below it, so Red Diamond is true even though neither line reached an overbought threshold. If RSI is 20 and the body/range mean is −6, Yellow Cross is also true because WT2 = 9 lies strictly between −80 and 45. Setting WT2 to exactly 45 or −80, RSI to exactly 15 or 30, or the body/range mean to exactly −5 makes Yellow Cross false.

If the EMA 5/11 crossunder occurred on the previous bar, that same Red Diamond is not a Blood Diamond. It must occur on the current bar too. These are Boolean test fixtures, not observed trades; a full price-series test must also verify that the calculated EMA, RSI and WaveTrend values produce the chosen fixture.

For Bull Candle, a current open of 102 above current EMA values 101 and 100, a current close of 103, and a preceding candle that rose from 100 to 101 meet the price conditions. The result still requires both excluded bearish markers to be false. The comparison uses current EMA values, which include the current close; it is not a test frozen when the bar opened.

Distinguish configurable arguments from effective controls

The helper accepts 22 arguments, but this script passes constants and contains no input functions. There is no 22-control Inputs panel in this copy. Pineify’s Visual Editor has a separate configuration; its helper currently accepts the same five inactive thresholds.

The unused arguments are obLevel, obLevel2, obLevel3, osLevel and osLevel2. Changing their defaults 53, 60, 100, −53 and −60 cannot change any marker in the shown implementation. Only osLevel3, default −80, participates in Yellow Cross. The upper bound 45, RSI bounds 15/30 and body/range cutoff −5 are literal constants, not those other threshold parameters.

Changing WaveTrend lengths can change its computed crossover series, but no measured signal frequency or false-signal reduction is established here. Do not select a “best” timeframe from untested settings or optimize an inactive parameter and attribute the result to it.

Verify timing and define a strategy separately

The source has no bar-close gate. Current close, high and low can change while a bar is open, moving the ribbon and creating or removing shapes. A same-timeframe request is not a higher-timeframe confirmation. TradingView’s repainting documentation explains the distinction between historical and live-bar behavior.

The copy defines neither alertcondition calls nor strategy orders. Before creating alerts or a backtest, specify which marker is actionable, whether it must remain true at bar close, the earliest permitted fill, position sizing, exits, commission and slippage. Avoid counting overlapping Red and Blood Diamonds as two independent trades. Preserve failed signals in the test; none of the shape names establishes exhaustion or profitability.

Useful separate references are WaveTrend Cross for oscillator crosses and RSI for the momentum calculation. Adding another price-derived series does not automatically add independent evidence.

Pine Script v6: implementation and limits

The Pineify v6 calculation is retained so its limitations are inspectable. It plots eight EMAs and eight possible shapes with fixed settings; it does not implement the optional execution rules discussed above. The unguarded division cases and inactive arguments are disclosed, not silently repaired in the shared product generator.

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

//======================================================================//
//                    ____  _            _  __                          //
//                   |  _ \\\(_)_ __   ___(_)/ _|_   _                    //
//                   | |_) | | '_ \\ / _ \\ | |_| | | |                   //
//                   |  __/| | | | |  __/ |  _| |_| |                   //
//                   |_|   |_|_| |_|\\___|_|_|  \\__, |                   //
//                                             |___/                    //
//======================================================================//

//@version=6
indicator(title="VuManChu Cipher A", overlay=true, max_labels_count=500)

//#region --- Custom Code

//#endregion

//#region --- Common Dependence

p_comm_time_range_to_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_unix_time = na
    int end_unix_time = na
    int start_time_hour = na
    int start_time_minute = na
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    start_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)
    end_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)
    [start_unix_time, end_unix_time]

p_comm_time_range_to_start_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_time_hour = na
    int start_time_minute = na
    if str.length(time_range) == 11
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
    else if str.length(time_range) == 9
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)

p_comm_time_range_to_end_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)

p_comm_timeframe_to_seconds(simple string tf) =>
    float seconds = 0
    tf_lower = str.lower(tf)
    value = str.tonumber(str.substring(tf_lower, 0, str.length(tf_lower) - 1))
    if str.endswith(tf_lower, 's')
        seconds := value
    else if str.endswith(tf_lower, 'd')
        seconds := value * 86400
    else if str.endswith(tf_lower, 'w')
        seconds := value * 604800
    else if str.endswith(tf_lower, 'm')
        seconds := value * 2592000
    else
        seconds := str.tonumber(tf_lower) * 60
    seconds

p_custom_sources() =>
    [open, high, low, close, volume]

//#endregion

//#region --- Ta Dependence

f_wavetrend(src, chlen, avg, malen) =>
    esa = ta.ema(src, chlen)
    de = ta.ema(math.abs(src - esa), chlen)
    ci = (src - esa) / (0.015 * de)
    tci = ta.ema(ci, avg)
    wt1 = tci
    wt2 = ta.sma(wt1, malen)
    [wt1, wt2]

f_emaRibbon(src, e1, e2, e3, e4, e5, e6, e7, e8) =>
    ema1 = ta.ema(src, e1)
    ema2 = ta.ema(src, e2)
    ema3 = ta.ema(src, e3)
    ema4 = ta.ema(src, e4)
    ema5 = ta.ema(src, e5)
    ema6 = ta.ema(src, e6)
    ema7 = ta.ema(src, e7)
    ema8 = ta.ema(src, e8)
    [ema1, ema2, ema3, ema4, ema5, ema6, ema7, ema8]

f_rsimfi(period, multiplier, tf) => request.security(syminfo.tickerid, tf, ta.sma(((close - open) / (high - low)) * multiplier, period))

p_ta_vmc_cipher_a(simple int wtChannelLen, simple int wtAverageLen, series float wtMASource, simple int wtMALen, simple int obLevel, simple int obLevel2, simple int obLevel3, simple int osLevel, simple int osLevel2, simple int osLevel3, simple int ema1Len, simple int ema2Len, simple int ema3Len, simple int ema4Len, simple int ema5Len, simple int ema6Len, simple int ema7Len, simple int ema8Len, series float rsiSource, simple int rsiLen, simple int rsiMFIperiod, simple float rsiMFIMultiplier) =>
    _src_wt = wtMASource
    _src_rsi = rsiSource

    [ema1, ema2, ema3, ema4, ema5, ema6, ema7, ema8] = f_emaRibbon(close, ema1Len, ema2Len, ema3Len, ema4Len, ema5Len, ema6Len, ema7Len, ema8Len)
    rsi = ta.rsi(_src_rsi, rsiLen)
    [wt1, wt2] = f_wavetrend(_src_wt, wtChannelLen, wtAverageLen, wtMALen)

    wtCross = ta.cross(wt1, wt2)
    wtCrossUp = wt2 - wt1 <= 0
    wtCrossDown = wt2 - wt1 >= 0
    rsiMFI = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, timeframe.period)

    longEma = ta.crossover(ema2, ema8)
    redCross = ta.crossunder(ema1, ema2)
    blueTriangle = ta.crossover(ema2, ema3)
    redDiamond = wtCross and wtCrossDown
    yellowCross = redDiamond and (wt2 < 45) and (wt2 > osLevel3) and (rsi < 30) and (rsi > 15) and (rsiMFI < -5)
    bloodDiamond = redDiamond and redCross
    bullCandle = open > ema2 and open > ema8 and (close[1] > open[1]) and (close > open) and not redDiamond and not redCross
    shortEma = ta.crossover(ema8, ema2)

    [ema1, ema2, ema3, ema4, ema5, ema6, ema7, ema8, longEma, shortEma, redCross, blueTriangle, redDiamond, bloodDiamond, yellowCross, bullCandle]

//#endregion

//#region --- Constants
string P_GP_1      =      ""
//#endregion

//#region --- Inputs
//#endregion

//#region --- Price Data
//#endregion

//#region --- Indicators
[p_ind_1_ema1, p_ind_1_ema2, p_ind_1_ema3, p_ind_1_ema4, p_ind_1_ema5, p_ind_1_ema6, p_ind_1_ema7, p_ind_1_ema8, p_ind_1_longEma, p_ind_1_shortEma, p_ind_1_redCross, p_ind_1_blueTriangle, p_ind_1_redDiamond, p_ind_1_bloodDiamond, p_ind_1_yellowCross, p_ind_1_bullCandle] = p_ta_vmc_cipher_a(9, 13, hlc3, 3, 53, 60, 100, -53, -60, -80, 5, 11, 15, 18, 21, 24, 28, 34, close, 14, 60, 150)
//#endregion

//#region --- Conditions
//#endregion

//#region --- Indicator Plots
plot(p_ind_1_ema1, "VMC A - EMA1", color=color.new(#1573D4, 0), linewidth=2)
plot(p_ind_1_ema2, "VMC A - EMA2", color=color.new(#3096FF, 0), linewidth=2)
plot(p_ind_1_ema3, "VMC A - EMA3", color=color.new(#57ABFF, 0), linewidth=2)
plot(p_ind_1_ema4, "VMC A - EMA4", color=color.new(#85C2FF, 0), linewidth=2)
plot(p_ind_1_ema5, "VMC A - EMA5", color=color.new(#9BCDFF, 0), linewidth=2)
plot(p_ind_1_ema6, "VMC A - EMA6", color=color.new(#B3D9FF, 0), linewidth=2)
plot(p_ind_1_ema7, "VMC A - EMA7", color=color.new(#C9E5FF, 0), linewidth=2)
plot(p_ind_1_ema8, "VMC A - EMA8", color=color.new(#DFECFB, 0), linewidth=2)
plotshape(p_ind_1_longEma, style=shape.circle, color=color.rgb(76, 175, 80, 0), location=location.abovebar, size=size.tiny, title="VMC A - Long EMA")
plotshape(p_ind_1_shortEma, style=shape.circle, color=color.rgb(242, 54, 69, 0), location=location.abovebar, size=size.tiny, title="VMC A - Short EMA")
plotshape(p_ind_1_redCross, style=shape.xcross, color=color.rgb(242, 54, 69, 0), location=location.abovebar, size=size.tiny, title="VMC A - Red Cross")
plotshape(p_ind_1_blueTriangle, style=shape.triangleup, color=color.rgb(41, 98, 255, 0), location=location.abovebar, size=size.small, title="VMC A - Blue Triangle")
plotshape(p_ind_1_redDiamond, style=shape.diamond, color=color.rgb(242, 54, 69, 0), location=location.abovebar, size=size.tiny, title="VMC A - Red Diamond")
plotshape(p_ind_1_bullCandle, style=shape.diamond, color=color.rgb(253, 216, 53, 0), location=location.abovebar, size=size.tiny, title="VMC A - Bull Candle")
plotshape(p_ind_1_bloodDiamond, style=shape.diamond, color=color.rgb(242, 54, 69, 0), location=location.abovebar, size=size.small, title="VMC A - Blood Diamond")
plotshape(p_ind_1_yellowCross, style=shape.xcross, color=color.rgb(253, 216, 53, 0), location=location.abovebar, size=size.small, title="VMC A - Yellow Cross")
//#endregion

//#region --- Custom Plots
//#endregion

//#region --- Alert
//#endregion

Specify a checkable adaptation in Pineify

Ask the Pine Script AI Coding Agent for an explicit adaptation: effective inputs only, a documented zero-range and zero-DE policy, optional bar-close gating, and alerts for selected markers. Compare each change against the original calculation and check the final script in TradingView. Pineify’s Visual Editor lists this indicator as a paid component; this guide does not promise account-free access or automatically expose every argument as a working control.

Open Pine Script AI Coding Agent

Educational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.

Implementation questions

No. Its function accepts 22 arguments, but the script passes fixed constants and contains no input functions. Five overbought or oversold arguments are also unused.

No. Here it is a 60-observation SMA of 150 times the signed candle body divided by high minus low. It uses neither volume nor the standard Money Flow Index.

No. It is a downward WT1/WT2 crossover. The overbought arguments do not participate in that condition.

No. It combines the bearish WaveTrend crossover with strict WT2, RSI and body/range limits. It does not require a subsequent price reversal or place a buy order.

Yes. There is no barstate.isconfirmed gate. Current price-derived values and marker conditions can change on the live bar.

No reproducible performance study is supplied here. Define a complete strategy and evaluate costs and unseen data; do not infer a win rate from marker names.