designed to show the historical order book, which is similar to the proprietary Bookmap software. The background of the chart is a heatmap of the 20 order book levels above and below the order book price, with the lighter colours representing a higher percentage of the total order book order volume, the spheres are sized proportionally to the tick volume of the relevant OHLC bar and the blue and red lines represent the high and low of the bar respectively. The lighter colours nicely highlight the areas where orders are accumulated for potential support and resistance.
However, the above screenshot is actually a two dimensional view, from above, of a three dimensional surface plot, as can be seen in the short video below
I created this so that I can visually look for patterns in the historical data, the reason being that my statistical search for useful features, using the Boruta package, has not shown any useful results yet. The Octave code to produce a "Snake and Canyon" plot is given below. Of course, use of this code presupposes that you have the data available for loading from csv files. Enjoy!
clear all ;
cd /home/dekalog/Documents/octave/oanda_data/20m ;
orderbook_snapshots_files = glob( '*_historical_orderbook_snapshots' ) ;
## {
## [1,1] = aud_jpy_historical_orderbook_snapshots
## [2,1] = aud_usd_historical_orderbook_snapshots
## [3,1] = eur_aud_historical_orderbook_snapshots
## [4,1] = eur_chf_historical_orderbook_snapshots
## [5,1] = eur_gbp_historical_orderbook_snapshots
## [6,1] = eur_jpy_historical_orderbook_snapshots
## [7,1] = eur_usd_historical_orderbook_snapshots
## [8,1] = gbp_chf_historical_orderbook_snapshots
## [9,1] = gbp_jpy_historical_orderbook_snapshots
## [10,1] = gbp_usd_historical_orderbook_snapshots
## [11,1] = nzd_usd_historical_orderbook_snapshots
## [12,1] = usd_cad_historical_orderbook_snapshots
## [13,1] = usd_chf_historical_orderbook_snapshots
## [14,1] = usd_jpy_historical_orderbook_snapshots
## [15,1] = xag_usd_historical_orderbook_snapshots
## [16,1] = xau_usd_historical_orderbook_snapshots
## }
file_no = input( 'Enter file no. from list, a number 1 to 16 inclusive. ' ) ;
filename = orderbook_snapshots_files{ file_no } ;
str_split = strsplit( filename , "_" ) ;
price_name = strjoin( str_split( 1 : 2 ) , "_" ) ;
ohlc_20m = dlmread( [ price_name , '_ohlc_20m' ] ) ; ## price data
orders = dlmread( [ price_name , '_historical_orderbook_snapshots' ] ) ; ## get latest orderbook levels
if ( file_no == 1 || file_no == 6 || file_no == 9 || file_no == 14 )
bucket_size = 0.05 ;
elseif ( file_no == 16 )
bucket_size = 0.5 ;
else
bucket_size = 0.0005 ;
endif
order_price = orders( : , 6 ) ;
price_length = 250 ;
plot_price = order_price( end - price_length : end ) ;
rounded_price = round( plot_price ./ bucket_size ) .* bucket_size ;
x_length = ( 1 : 1 : ( price_length + 1 ) )' ;
y_max = max( rounded_price .+ ( 20 * bucket_size ) ) ;
y_min = min( rounded_price .- ( 20 * bucket_size ) ) ;
y = ( y_min : bucket_size : y_max )' ;
z = zeros( size( y , 1 ) , size( x_length , 1 ) ) ;
zz = orders( end - price_length : end , 7 : 47 ) .+ orders( end - price_length : end , 48 : 88 ) ;
for ii = 1 : size( z , 2 )
[ ~ , ix ] = min( abs( y .- plot_price( ii ) ) ) ;
z( ix - 20 : ix + 20 , ii ) = zz( ii , : ) ;
endfor
z_high = max( max( z ) ) ;
mid_y = ( ohlc_20m( end - price_length : end , 19 ) .+ ohlc_20m( end - price_length : end , 20 ) ) ./ 2 ;
vol = ohlc_20m( end - price_length : end , 22 ) ; vol = vol ./ max( vol ) ;
up_scatter_ix = find( ohlc_20m( end - price_length : end , 21 ) >= ohlc_20m( end - price_length : end , 18 ) ) ;
down_scatter_ix = find( ohlc_20m( end - price_length : end , 21 ) < ohlc_20m( end - price_length : end , 18 ) ) ;
figure(1) ;
colormap( 'cubehelix' ) ; surf( x_length , y , z , 'edgecolor' , 'none' , 'facecolor' , 'interp' , 'facealpha' , 0.75 ) ; view( 2 ) ;
axis( [ 1 price_length y_min y_max 0 z_high ] ) ; grid off ;
hold on ;
scatter3( up_scatter_ix , mid_y( up_scatter_ix ) , ones( size( up_scatter_ix ) ) .* z_high ./ 2 , 1000.*vol( up_scatter_ix ) , 'c' , 'o' , 'filled' ) ;
scatter3( down_scatter_ix , mid_y( down_scatter_ix ) , ones( size( down_scatter_ix ) ) .* z_high ./ 2 , 1000.*vol( down_scatter_ix ) , 'm' , 'o' , 'filled' ) ;
line( 'xdata' , x_length , 'ydata' , ohlc_20m( end - price_length : end , 19 ) , 'zdata' , ones(size(x_length)).*z_high ./ 2 , 'color','b' , 'linewidth' , 5 ) ;
line( 'xdata',x_length ,'ydata', ohlc_20m( end - price_length : end , 20 ) ,'zdata', ones(size(x_length)).*z_high ./ 2 , 'color','r' , 'linewidth' , 5 ) ;
xlabel( 'Time' ) ; ylabel( 'Levels - Price' ) ; zlabel( 'OrderBook Percent' ) ; title( strjoin( str_split( 1 : 2 ) , "-" ) ) ;
hold off ;
It sounds like avery interesting project but the visualisation you describe sounds over complicated if you want to visualise market depth and price points of interest why not use/modify an existing methodology that does a similar thing such as market profile theory you could even combine the historic elements of market profile and overlay the existing order book data onto in that way you track where resting orders are situated relative to key profile price points such as VPOC and CPOC etc just a thought
ReplyDeleteHi Darren,
ReplyDeleteThanks for your comment. I shall take your suggestion under considerarion.