Saturday, 11 April 2020

Get Latest Pricing Octave_Oanda_API Function

Following on from my my earlier, simple account summary API function, here is a function which downloads the latest pricing information for a given currency cross/tradable
## Copyright (C) 2020 dekalog
## 
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see
## .

## -*- texinfo -*- 
## @deftypefn {} {@var{best_bid}, @var{best_ask} =} get_current_pricing (@var{currency_cross})
##
## Returns the current pricing (best bid and ask prices) for CURRENCY_CROSS given by the Oanda API call,
## for example,
##
## "https://api-fxtrade.oanda.com/v3/accounts//pricing?instruments=EUR_USD"
##
## for CURRENCY_CROSS == 'eur_usd' (input is a character vector)
##
## Internally the function runs system() which calls the Curl
## library for the actual API download. The function is hard coded
## with the account token and account ID.
##
## @seealso{}
## @end deftypefn

## Author: dekalog 
## Created: 2020-04-05

function [ best_bid , best_ask ] = get_current_pricing ( cross )
 
if ( ischar( cross ) == 0 )
   error( 'Input must be a character vector for currency crosss/tradable, e.g. "eur_usd"' ) ;
endif
 
## set up the headers
query = [ 'curl -s -H "Content-Type: application/json"' ] ; ## -s is silent mode for Curl for no paging to terminal
query = [ query , ' -H "Authorization: Bearer 63926d856d2f6d7ed16ff014c8227042-3ceb540b828a7380b02dfdb273e7ab68"' ] ;

## construct the API call
query = [ query , ' "https://api-fxtrade.oanda.com/v3/accounts/001-004-225017-001/pricing?instruments=' ] ;
query = [ query , toupper( cross ) , '"' ] ;

## call to use external Unix systems/Curl and return result
[ ~ , ret_JSON ] = system( query , RETURN_OUTPUT = 'TRUE' ) ;

## convert the returned JSON object to Octave structure
s = load_json( ret_JSON ) ;

best_bid = s.prices{1}.bids{1}.price ;
best_ask = s.prices{1}.asks{1}.price ;

endfunction

## Typically, the retval output structure s will look like this:-
##
## s =
##
##   scalar structure containing the fields:
##
##     time = 2020-04-10T17:42:13.317424312Z
##     prices =
##     {
##       [1,1] =
##
##         scalar structure containing the fields:
##
##           type = PRICE
##           time = 2020-04-10T17:42:09.734257300Z
##           bids =
##           {
##             [1,1] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,2] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,3] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,4] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##           }
##
##           asks =
##           {
##             [1,1] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,2] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,3] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##             [1,4] =
##
##               scalar structure containing the fields:
##
##                 price: 1x7 sq_string
##                 liquidity: 1x1 uint32 scalar
##
##           }
##
##           closeoutBid = 1.09358
##           closeoutAsk = 1.09388
##           status = tradeable
##           tradeable = 1
##           unitsAvailable =
##
##             scalar structure containing the fields:
##
##               default: 1x1 scalar struct
##               openOnly: 1x1 scalar struct
##               reduceFirst: 1x1 scalar struct
##               reduceOnly: 1x1 scalar struct
##
##           quoteHomeConversionFactors =
##
##             scalar structure containing the fields:
##
##               positiveUnits: 1x10 sq_string
##               negativeUnits: 1x10 sq_string
##
##           instrument = EUR_USD
##
##     }
##
## where bid and ask fields etc. just give information rather than values.
## Can access values by, e.g. values = s.prices
## to get
##
## b =
## {
##   [1,1] =
##
##     scalar structure containing the fields:
##
##       type = PRICE
##       time = 2020-04-10T17:48:17.265291655Z
##       bids =
##       {
##         [1,1] =
##
##           scalar structure containing the fields:
##
##             price = 1.09352
##             liquidity = 1000000
##
##         [1,2] =
##
##           scalar structure containing the fields:
##
##             price = 1.09351
##             liquidity = 2000000
##
##         [1,3] =
##
##           scalar structure containing the fields:
##
##             price = 1.09350
##             liquidity = 2000000
##
##         [1,4] =
##
##           scalar structure containing the fields:
##
##             price = 1.09348
##             liquidity = 5000000
##
##       }
##
##       asks =
##       {
##         [1,1] =
##
##           scalar structure containing the fields:
##
##             price = 1.09393
##             liquidity = 1000000
##
##         [1,2] =
##
##           scalar structure containing the fields:
##
##             price = 1.09395
##             liquidity = 2000000
##
##         [1,3] =
##
##           scalar structure containing the fields:
##
##             price = 1.09396
##             liquidity = 2000000
##
##         [1,4] =
##
##           scalar structure containing the fields:
##
##             price = 1.09397
##             liquidity = 5000000
##
##       }
##
##       closeoutBid = 1.09348
##       closeoutAsk = 1.09397
##       status = tradeable
##       tradeable = 1
##       unitsAvailable =
##
##         scalar structure containing the fields:
##
##           default =
##
##             scalar structure containing the fields:
##
##               long: 1x6 sq_string
##               short: 1x6 sq_string
##
##           openOnly =
##
##             scalar structure containing the fields:
##
##               long: 1x6 sq_string
##               short: 1x6 sq_string
##
##           reduceFirst =
##
##             scalar structure containing the fields:
##
##               long: 1x6 sq_string
##               short: 1x6 sq_string
##
##           reduceOnly =
##
##             scalar structure containing the fields:
##
##               long: 1x1 sq_string
##               short: 1x1 sq_string
##
##
##       quoteHomeConversionFactors =
##
##         scalar structure containing the fields:
##
##           positiveUnits = 0.80113441
##           negativeUnits = 0.80178317
##
##       instrument = EUR_USD
##
## }
##
## where some of the values are now "viewable" in terminal.
##
## to do this directly do
##
## s.prices{1}.asks{1}.price, which  will give 1.09393
##
## and 
##
## s.prices{1}.asks{1}.liquidity, which will give 1000000
The function returns are the best bid and ask prices; however, it would be a simple enough task for readers to edit the function to get further levels, a la Market depth, liquidity at these levels and some other price metrics. There is a comment section at the end of the function which shows how to do this.

I wrote this function with a view to it perhaps becoming the basis of a client-side, trailing stop functionality. Enjoy!

No comments: