Search code examples
gnuplot

Plotting financial data Renko-style in gnuplot


I've got OHLC data for the S&P 500 that I would like to plot as a so-called Renko plot ( https://en.wikipedia.org/wiki/Renko_chart ) in gnuplot. I have transformed the OHLC data to fixed-size bricks represented in data.dat as the upper and lower diagonal corners of rectangles. Here's a notional example:

# x1, y1, x2, y2
0 6 1 4
1 8 2 6
2 10 3 8
3 12 4 10
4 14 5 12
5 12 6 10

And then so far I can actually get them onto a plot using the following script:

set terminal pngcairo size 800,600
set output 'renko_chart.png'
set grid

set style fill solid
plot 'data.dat' using 1:2:1:3:2:4 with boxxy

Which produces the following:

Renko Chart in development

What I would like to do is colour "up bricks" green, and "down bricks" red. Furthermore, I would like to include a date along the X-axis, without affecting the horizontal scale of the bricks. To get a clearer idea of what I mean, here is an image from the wikipedia article:

Renko Chart, wikipedia

Note the date along the bottom, and how the axis scale varies across the width of the image. Towards the left, we see a period of about 6 days take the same amount of space on the chart as a period of just a few hours to the right. The idea is that the price action is decoupled from the time frame, and it is the axis that scales reactively to the data.

Is this possible in gnuplot?


Solution

  • Here is another suggestion. You are actually starting with some kind of OHLC data. Here, for illustration purpose, some random input data for testing is generated within the script (with just one y-value) and looks like the following:

    2024-05-23 19:17:19      93.1655
    2024-05-23 20:17:19      94.1
    2024-05-23 21:17:19      94.008
    2024-05-23 22:17:19      94.5589
    2024-05-23 23:17:19      94.1284
    2024-05-24 00:17:19      93.9924
    2024-05-24 01:17:19      93.8272
    2024-05-24 02:17:19      94.3609
    

    The data in $Renko looks for example like this, where column 1 and 2 contain the date where the brick started, column 3 contains the y-value and column 4 contains -1 and +1 depending on whether data in this brick was decreasing or increasing, respectively.

    2024-05-18 12:17:19      96.9638        1
    2024-05-20 00:17:19      99.4638        1
    2024-05-20 07:17:19      96.9638       -1
    2024-05-21 18:17:19      94.4638       -1
    2024-05-22 11:17:19      91.9638       -1
    2024-05-23 02:17:19      94.4638        1
    

    Some comments:

    • I very much hope that I implemented the Renko principle correctly (please double check)
    • the Renko brick height is defined by h, here h = 2.5.
    • in order to reduce the number of plotted xtics you use a second "dummy" plot command using xtics() (check help xticlabels) and every(check help every). Not sure if this is easy to understand. If you need more explanations let me know.

    Script:

    ### Renko style plot
    reset session
    
    myFmt = "%Y-%m-%d %H:%M:%S"
    
    # create some random test data
    set table $Data
        set samples 2000
        t0 = time(0)-1e7
        y0 = 100
        plot '+' u (strftime(myFmt,t0+$0*3600)):(y0=y0+rand(0)*2-1) w table
    unset table
    
    colX = 1
    colY = 3
    h    = 2.5   # Renko brick height
    
    set table $Renko
        plot $Data u (strftime(myFmt,timecolumn(colX,myFmt))): \
             (y=column(colY), $0==0 ? (s0=s1=1, y0=y) : 0, dy=y-y0, y0): \
             ((newBrick=abs(dy)>h) ? (y0=y0+sgn(dy)*h, s0=s1, s1=sgn(dy)) : 0, s0) \
              with table if newBrick
    unset table
    
    N           = |$Renko|       # number of Renko bricks
    Tx          = 7              # number of approx. xtics
    M           = int(N/(Tx-1))  # show only every M-th xtic
    myXtic(col) = strftime("%Y\n%m-%d",strptime(myFmt,strcol(col)))   # xtic format
    
    set key noautotitle
    set style fill solid 0.3
    set xrange[:] noextend
    set offsets graph 0.02, graph 0.02, 0, 0
    set grid x,y
    
    set multiplot layout 2,1
    
        set format x "%Y\n%m-%d" timedate
        plot $Data u (timecolumn(1,myFmt)):3 w l lc "blue"
    
        set format x "\n" numeric
        plot $Renko u 0:3:(0.5):(h/2.): \
             ($4>0 ? 0x00cc00 : 0xff0000) w boxxy lc rgb var, \
             '' every M u ($0*M):3:xtic(myXtic(1)) w p ps 0
    unset multiplot
    ### end of script
    

    Result:

    Top graph: input data.
    Bottom graph: Renko bricks (note the irregular time scale on x-axis)

    enter image description here