Search code examples
pine-scriptlogarithm

The equation of a straight line on semi - logarithmic scale passing through two points


what I want is the equation of a straight line on a semi - logarithmic scale passing through two points. I will use it in an indicator. The base equation is as follows:

y = k * 10 ^ mx
m = slope of line = ∆(log y) / ∆x
k = y-intercept: value of y where line crosses the x = 0 axis

for example:

x0 = 69
x1 = 174
y0 = 0.0000296
y1 = 0.0001652
m = (log10(y1) - log10(y0)) / (x1 - x0)
k = y0 / pow(10, m * x0)
y = k * pow(10, m * bar_index)
plot(y)

While this equation is absolutely correct, the result of plotting it on logarithmic scale was a curve: https://www.tradingview.com/x/5Tl0lDK0/

Then I realized that apparently in the price < 0.001 range, the logarithmic chart of Tradingview is not working logarithmically!

See this image: https://www.tradingview.com/i/3vWZsxND/

I am so confused.

Does anyone know the cause?

What is the equation corresponding to the chart scale?

Please help if you can.


Solution

  • Concerning the scale with small values, it's expected behavior. Some charts on TradingView can go into negative territory. This would not be possible to accomplish on a real log scale, which is why the actual scale is only logarithmic up to a point and then it changes to linear. It's a necessary compromise to accommodate edge cases such as charts with negative values, drawings with coordinates that go below 0, etc.

    [EDIT 2021.06.07 10:08 — LucF]

    The equation for the calculation is as follows:

    //@version=4
    study("My Script", overlay=true)
    x1 = bar_index[10]
    y1 = input(0)
    x2 = bar_index
    y2 = input(1000)
    xi = bar_index[4]
    isLog = input(true)
    LOGICAL_OFFSET = 4
    COORD_OFFSET = 0.0001
    f_toLog(_price) =>
        _m = abs(_price)
        _res = log10(_m + COORD_OFFSET) + LOGICAL_OFFSET
        _m < 1e-8 ? 0 : _price < 0 ? - _res : _res
    f_fromLog(_logical) =>
        _m = abs(_logical)
        _res = pow(10, _m - LOGICAL_OFFSET) - COORD_OFFSET
        _m < 1e-8 ? 0 : _logical < 0 ? - _res : _res
    f_lineGetPrice(_x1, _y1, _x2, _y2, _xi) =>
        _y1 + (_y2 - _y1) / (_x2 - _x1) * (_xi - _x1)
    f_lineGetPriceLog(_x1, _y1, _x2, _y2, _xi) =>
        _y1Log = f_toLog(_y1)
        _y2Log = f_toLog(_y2)
        _target = f_lineGetPrice(_x1, _y1Log, _x2, _y2Log, _xi)
        f_fromLog(_target)
    if barstate.islast
        l1 = line.new(x1, y1, x2, y2)
        labelHeightxiBarsBack = isLog ? f_lineGetPriceLog(x1, y1, x2, y2, xi) : f_lineGetPrice(x1, y1, x2, y2, xi)
        label.new(xi, labelHeightxiBarsBack, text = tostring(labelHeightxiBarsBack))