A Port of Williams Vix Fix Indicator

[BTCUSDT 4H Timeframe]

Code

PineTS makes it easy to port your Pine Script code to JavaScript.
See the example below, this is the "Williams Vix Fix Indicator" indicator converted from Pine Script to PineTS.
you can barely tell the difference if you ignore JS variables declarations syntax (const/let/...etc)

Pine Script v5 code   PineTS Ported code

pd = input.int(22, title='LookBack Period Standard Deviation High')
bbl = input.int(20, title='Bolinger Band Length')
mult = input.float(2.0, minval=1, maxval=5, title='Bollinger Band Standard Devaition Up')
lb = input.int(50, title='Look Back Period Percentile High')
ph = input.float(.85, title='Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%')
pl = input.float(1.01, title='Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%')
hp = input.bool(true, title='Show High Range - Based on Percentile and LookBack Period?')
sd = input.bool(true, title='Show Standard Deviation Line?')

wvf = (ta.highest(close, pd) - low) / ta.highest(close, pd) * 100

sDev = mult * ta.stdev(wvf, bbl)
midLine = ta.sma(wvf, bbl)
lowerBand = midLine - sDev
upperBand = midLine + sDev

rangeHigh = ta.highest(wvf, lb) * ph
rangeLow = ta.lowest(wvf, lb) * pl

col = wvf >= upperBand or wvf >= rangeHigh ? color.lime : color.gray

RangeHigh = hp and rangeHigh ? rangeHigh : na
RangeLow = hp and rangeLow ? rangeLow : na
UpperBand = sd and upperBand ? upperBand : na

plot(RangeHigh, title='Range High Percentile', style=plot.style_line, linewidth=4, color=color.new(color.orange, 0))
plot(RangeLow, title='Range Low Percentile', style=plot.style_line, linewidth=4, color=color.new(color.orange, 0))
plot(UpperBand, title='Upper Band', style=plot.style_line, linewidth=3, color=color.new(color.aqua, 0))
plot(wvf, title='Williams Vix Fix', style=plot.style_histogram, linewidth=4, color=col)
                            

const pd = input.int(22, 'LookBack Period Standard Deviation High');
const bbl = input.int(20, 'Bolinger Band Length');
const mult = input.float(2.0, 'Bollinger Band Standard Devaition Up');
const lb = input.int(50, 'Look Back Period Percentile High');
const ph = input.float(0.85, 'Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%');
const pl = input.float(1.01, 'Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%');
const hp = input.bool(true, 'Show High Range - Based on Percentile and LookBack Period?');
const sd = input.bool(true, 'Show Standard Deviation Line?');

const wvf = ((ta.highest(close, pd) - low) / ta.highest(close, pd)) * 100;

const sDev = mult * ta.stdev(wvf, bbl);
const midLine = ta.sma(wvf, bbl);
const lowerBand = midLine - sDev;
const upperBand = midLine + sDev;

const rangeHigh = ta.highest(wvf, lb) * ph;
const rangeLow = ta.lowest(wvf, lb) * pl;

const col = wvf >= upperBand || wvf >= rangeHigh ? color.lime : color.gray;

const RangeHigh = hp && rangeHigh ? rangeHigh : NaN;
const RangeLow = hp && rangeLow ? rangeLow : NaN;
const UpperBand = sd && upperBand ? upperBand : NaN;

plot(RangeHigh, 'RangeHigh', { style: 'line', linewidth: 1, color: 'lime' });
plot(RangeLow, 'RangeLow', { style: 'line', linewidth: 1, color: 'orange' });
plot(UpperBand, 'UpperBand', { style: 'line', linewidth: 2, color: 'aqua' });
plot(wvf, 'WilliamsVixFix', { style: 'histogram', linewidth: 4, color: col });
                            
Note : PineTS plot directive returns an object with plot data, it does not actually render it as PineTS does not handle rendering.
The rendering part is implemented with lightweight-charts library in the current example (see check chart.js script used in this page).

Usage

Once you port the code, you can use PineTS to run it, plot directives returns objects with all required data to render the charts, This is how we rendered the indicator above.


const pineTS = new PineTS( PineTS.Provider.Binance,
    'BTCUSDT', //the tickerId
    'W', //the timeframe in Pine Script format
    500, //the number of periods to query
  );

  const { plots } = await pineTS.run((context) => {
    const { close, high, low } = context.data; //import OHLCV data
    const { plot, plotchar, nz, color } = context.core; //import core functions
    const ta = context.ta; //import technical analysis namespace
    const math = context.math; //import math namespace
    const input = context.input; //import input namespace
    

    //below is the converted code from Pine Script to PineTS
    const pd = input.int(22, 'LookBack Period Standard Deviation High');
    const bbl = input.int(20, 'Bolinger Band Length');
    const mult = input.float(2.0, 'Bollinger Band Standard Devaition Up');
    const lb = input.int(50, 'Look Back Period Percentile High');
    const ph = input.float(0.85, 'Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%');
    const pl = input.float(1.01, 'Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%');
    const hp = input.bool(true, 'Show High Range - Based on Percentile and LookBack Period?');
    const sd = input.bool(true, 'Show Standard Deviation Line?');
    
    const wvf = ((ta.highest(close, pd) - low) / ta.highest(close, pd)) * 100;
    
    const sDev = mult * ta.stdev(wvf, bbl);
    const midLine = ta.sma(wvf, bbl);
    const lowerBand = midLine - sDev;
    const upperBand = midLine + sDev;
    
    const rangeHigh = ta.highest(wvf, lb) * ph;
    const rangeLow = ta.lowest(wvf, lb) * pl;
    
    const col = wvf >= upperBand || wvf >= rangeHigh ? color.lime : color.gray;
    
    const RangeHigh = hp && rangeHigh ? rangeHigh : NaN;
    const RangeLow = hp && rangeLow ? rangeLow : NaN;
    const UpperBand = sd && upperBand ? upperBand : NaN;
    
    plot(RangeHigh, 'RangeHigh', { style: 'line', linewidth: 1, color: 'lime' });
    plot(RangeLow, 'RangeLow', { style: 'line', linewidth: 1, color: 'orange' });
    plot(UpperBand, 'UpperBand', { style: 'line', linewidth: 2, color: 'aqua' });
    plot(wvf, 'WilliamsVixFix', { style: 'histogram', linewidth: 4, color: col });
  });

  console.log(plots);