Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

SAXO Bank OpenAPI REST-API access

Project description

saxo_openapi

Python wrapper for Saxo Bank OpenAPI REST-API (see here)

Most endpoints are covered by saxo_openapi. Check Covered endpoints for details.

https://travis-ci.org/hootnot/saxo_openapi.svg?branch=master Documentation Status Coverage PyPI Python versions https://api.codacy.com/project/badge/Grade/edcfcf6a416a4f94bb710413a35daa83

Interactive

Jupyter

Using the Jupyter notebook it is easy to experiment with the saxo_openapi library.

Install

# Setup a virtual environment
$ mkdir tst_saxo_openapi
$ cd tst_saxo_openapi
$ /usr/local/bin/python3.7 -m venv venv37
$ . ./venv37/bin/activate
(venv37) feite@oatr:~/tst_saxo_openapi$

$ pip install saxo_openapi requests

# get a token from developer.saxo
# try some examples

To use the latest development version from github:

$ pip install git+https://github.com/hootnot/saxo_openapi.git

Note

Only python3 is supported!

Design

The saxo_openapi covers each endpoint of the SAXO OpenAPI by a request class. Each request class representing an endpoint applies the following in a consistent way:

Endpoint parameters as documented by SAXO saxo_openpi request class Comment
route parameters named parameters: required  
example:    
/port/v1/positions/me/?FieldGroups=… portfolio.PositionsMe() No route params and no required params
     
querystring parameters params dict: optional and/or required parameters. If all parameters in params are optional the params parameter is optional, otherwise it is required  
example:    
/port/v1/positions/{PositionId}/?… pf.positions.SinglePosition(PositionId, params={..}) PositionId: required, params: required
     
body parameters data dict: optional and/or required parameters  
example:    
/trade/v2/orders/ tr.orders.Order(data={..}) data: required

Top saxo_openapi

Documentation

SAXO Bank has a full documentation of their REST interface available on https://www.developer.saxo/openapi/referencedocs.

The documentation of saxo_openapi is on https://saxo-openapi.readthedocs.io/en/latest. Each request-class is documented with a straightforward usage example.

Top saxo_openapi

Example

from saxo_openapi import API
import saxo_openapi.endpoints.rootservices as rs
from pprint import pprint

token = " ... [Paste your access token here - create a 24-hour token for testing on developer.saxo] ... "
client = API(access_token=token)

# lets make a diagnostics request, it should return '' with a state 200
r = rs.diagnostics.Get()
print("request is: ", r)
rv = client.request(r)
assert rv is None and r.status_code == 200
print('diagnostics passed')

# request available rootservices-features
r = rs.features.Availability()
rv = client.request(r)
print("request is: ", r)
print("response: ")
pprint(rv, indent=2)
print(r.status_code)

Output:

request is:  openapi/root/v1/diagnostics/get/
diagnostics passed
request is:  openapi/root/v1/features/availability/
response:
[ {'Available': True, 'Feature': 'News'},
  {'Available': True, 'Feature': 'GainersLosers'},
  {'Available': True, 'Feature': 'Calendar'},
  {'Available': True, 'Feature': 'Chart'}]
200

Top saxo_openapi

Some Trading

from saxo_openapi import API
import saxo_openapi.endpoints.trading as tr
import saxo_openapi.endpoints.portfolio as pf
import json

# Place your token in a file named: tok.txt
tok = ""
with open("tok.txt") as I:
    tok = I.read().strip()

# Our client to process the requests
client = API(access_token=tok)

# Positions, probably none, but maybe you see positions
# that you created by the explorer
r = pf.positions.PositionsMe()
rv = client.request(r)
print(json.dumps(rv, indent=2))

# Place some market orders
MO = [
{
    "AccountKey": "Cf4xZWiYL6W1nMKpygBLLA==",
    "Amount": "100000",
    "AssetType": "FxSpot",
    "BuySell": "Sell",
    "OrderType": "Market",
    "Uic": 21   # EURUSD
},
{
    "AccountKey": "Cf4xZWiYL6W1nMKpygBLLA==",
    "Amount": "80000",
    "AssetType": "FxSpot",
    "BuySell": "Buy",
    "OrderType": "Market",
    "Uic": 23   # GBPCAD
},
]

# create Order requests and process them
for r in [tr.orders.Order(data=orderspec) for orderspec in MO]:
    client.request(r)

# check for positions again
r = pf.positions.PositionsMe()
rv = client.request(r)
print(json.dumps(rv, indent=2))

Output:

{
  "__count": 0,
  "Data": []
}
{
  "__count": 2,
  "Data": [
    {
      "NetPositionId": "GBPCAD__FxSpot",
      "PositionBase": {
        "Uic": 23,
        "AccountId": "9226397",
        "Amount": 80000.0,
        "CanBeClosed": true,
        "SourceOrderId": "76306670",
        "ExecutionTimeOpen": "2019-03-05T22:39:43.738721Z",
        "Status": "Open",
        "IsMarketOpen": true,
        "CorrelationKey": "244b083d-7bce-4e4b-a01c-5117e5860321",
        "CloseConversionRateSettled": false,
        "ClientId": "9226397",
        "OpenPrice": 1.75937,
        "RelatedOpenOrders": [],
        "ValueDate": "2019-03-08T00:00:00.000000Z",
        "SpotDate": "2019-03-08",
        "AssetType": "FxSpot"
      },
      "PositionView": {
        "Exposure": 80000.0,
        "InstrumentPriceDayPercentChange": -0.04,
        "ConversionRateCurrent": 0.662245,
        "TradeCostsTotal": -14.07,
        "ExposureInBaseCurrency": 93196.8,
        "CurrentPriceType": "Bid",
        "TradeCostsTotalInBaseCurrency": -9.32,
        "ProfitLossOnTradeInBaseCurrency": -49.27,
        "CurrentPriceDelayMinutes": 0,
        "ConversionRateOpen": 0.662245,
        "ProfitLossOnTrade": -74.4,
        "ExposureCurrency": "GBP",
        "CurrentPrice": 1.75844,
        "CalculationReliability": "Ok"
      },
      "PositionId": "212702698"
    },
    {
      "NetPositionId": "EURUSD__FxSpot",
      "PositionBase": {
        "Uic": 21,
        "AccountId": "9226397",
        "Amount": -100000.0,
        "CanBeClosed": true,
        "SourceOrderId": "76306669",
        "ExecutionTimeOpen": "2019-03-05T22:39:43.546536Z",
        "Status": "Open",
        "IsMarketOpen": true,
        "CorrelationKey": "4dab5814-8b84-421e-859b-dfdbdbec06ec",
        "CloseConversionRateSettled": false,
        "ClientId": "9226397",
        "OpenPrice": 1.13054,
        "RelatedOpenOrders": [],
        "ValueDate": "2019-03-08T00:00:00.000000Z",
        "SpotDate": "2019-03-08",
        "AssetType": "FxSpot"
      },
      "PositionView": {
        "Exposure": -100000.0,
        "InstrumentPriceDayPercentChange": -0.01,
        "ConversionRateCurrent": 0.884455,
        "TradeCostsTotal": -11.3,
        "ExposureInBaseCurrency": -100000.0,
        "CurrentPriceType": "Ask",
        "TradeCostsTotalInBaseCurrency": -9.99,
        "ProfitLossOnTradeInBaseCurrency": -17.69,
        "CurrentPriceDelayMinutes": 0,
        "ConversionRateOpen": 0.884455,
        "ProfitLossOnTrade": -20.0,
        "ExposureCurrency": "EUR",
        "CurrentPrice": 1.13074,
        "CalculationReliability": "Ok"
      },
      "PositionId": "212702696"
    }
  ]
}

Top saxo_openapi

Or by using: contrib.orders

The same orders but now using MarketOrderFxSpot to create the orderbodies.

from saxo_openapi import API
import saxo_openapi.endpoints.trading as tr
import saxo_openapi.endpoints.portfolio as pf
from saxo_openapi.contrib.orders import tie_account_to_order, MarketOrderFxSpot
from saxo_openapi.contrib.session import account_info
import json

# Place your token in a file named: token.txt
token = ""
with open("token.txt") as I:
    tok = I.read().strip()

# client to process the requests
client = API(access_token=token)
ai = account_info(client)

# Positions, probably none, but maybe you see positions
# that you created by the explorer
r = pf.positions.PositionsMe()
rv = client.request(r)
print(json.dumps(rv, indent=2))

# Place some market orders, only Amount and Uic needed
# the other body parameters will be generated by MarketOrderFxSpot
MO = [
   {
       "Amount": -100000,    # negative amount indicates a Sell
       "Uic": 21   # EURUSD
   },
   {
       "Amount": 80000,      # positive amount indicates a buy
       "Uic": 23   # GBPCAD
   }]

# create Order requests and process them
for spec in MO:
    mospec = tie_account_to_order(ai.AccountKey, MarketOrderFxSpot(**spec))
    r = tr.orders.Order(data=mospec)
    client.request(r)

# check for positions again
r = pf.positions.PositionsMe()
rv = client.request(r)
print(json.dumps(rv, indent=2))

Top saxo_openapi

Covered endpoints

SAXO Bank organizes the endpoints in groups/subgroups, see: https://www.developer.saxo/openapi/referencedocs

States:

  • [ ] not covered yet
  • [.] work in progress
  • [x] covered
Account History
  Account Values
     AccountSummary          [x]
  HistoricalPositions
     HistoricalPositions     [x]
  Performance
     AccountPerformance      [x]

Auto Trading
  Investments
  Trade Followers
  Trade Leaders

Chart
  Charts                     [x]

Client Management
  Signups v1
  Signups v2
  Users

Client Reporting
  Historical Report Data - Account Statement
  Historical Report Data - Portfolio Management
  Historical Report Data - Trade Details
  Historical Report Data - Trades Executed
  Historical Report Data - Transaction
  Historical Report Data - Transaction Balance

Client Services
  Audit Activities
  Audit OrderActivities
  CashManagement - InterAcountTransfer
  CashManagement - Wiretransfers
  ClientInfo
  Historical Report Data - Aggregated amounts
  Historical Report Data - Bookings
  Historical Report Data - Closed positions
  Historical Report Data - Trades
  Support - Cases

Event Notification Services
  ClientActivities
    create a subscription for client events   [x]
    remove subscription                       [x]
    remove subscriptions                      [x]
    get activities for client/account         [x]

Partner Integration (Beta/Early Preview)
  InteractiveIdVerification

Platform
  Articles
    Get a specific article from sitecore           [ ]
    Get a list of articles from sitecore           [ ]
  ConfigurationInvestor
    Get the structure configuration for platform   [ ]
    Get a specific page for not loading full site  [ ]
  ConfigurationTrader
    Get the structure configuration for platform   [ ]
    Get a specific page for not loading full site  [ ]

Portfolio
  AccountGroups
    AccountGroupDetails      [x]
    AccountGroupsMe          [x]
    AccountGroupsList        [x]
    AccountGroupUpdate       [x]

  Accounts
    AccountDetails           [x]
    AccountList              [x]
    AccountListByClient      [x]
    AccountUpdate            [x]
    Accountreset             [x]
    SubscriptionCreate       [x]
    SubscriptionRemoveByTag  [x]
    SubscriptionRemoveById   [x]

  Balances
    AccountBalancesMe                 [x]
    AccountBalances                   [x]
    MarginOverview                    [x]
    BalanceSubscriptionCreate         [x]
    BalanceSubscriptionRemoveByTag    [x]
    BalanceSubscriptionRemoveById     [x]

  Clients
    ClientDetailsMe                   [x]
    ClientDetails                     [x]
    ClientDetailsUpdate               [x]
    ClientDetailsByOwner              [x]
    ClientSwitchPosNettingMode        [x]

  ClosedPositions
    ClosedPositionList                     [x]
    ClosedPositionById                     [x]
    ClosedPositionDetails                  [x]
    ClosedPositionsMe                      [x]
    ClosedPositionSubscription             [x]
    ClosedPositionSubscriptionUpdate       [x]
    ClosedPositionSubscriptionsRemove      [x]
    ClosedPositionSubscriptionRemoveById   [x]

  Exposure
    NetInstrumentsExposureMe                  [x]
    NetInstrumentsExposure                    [x]
    CreateExposureSubscription                [x]
    RemoveExposureSubscriptionsByTag          [x]
    RemoveExposureSubscription                [x]
    CurrencyExposureMe                        [x]
    CurrencyExposureSpecific                  [x]
    FxSpotExposureMe                          [x]
    FxSpotExposurSpecific                     [x]

  NetPositions
    Get a single netposition                                            [x]
    Get detailed information for a single netposition                   [x]
    Get netpositions for the logged-in client                           [x]
    Get netpositions for a client, account group, account or a position [x]
    Create a netsubscription on a list of positions and make it active  [x]
    Remove multiple subscriptions                                       [x]
    Remove a subscription                                               [x]

  Orders
    GetOpenOrder                               [x]
    GetOpenOrdersMe                            [x]
    OrderDetails                               [x]
    GetAllOpenOrders                           [x]
    CreateOpenOrdersSubscription               [x]
    RemoveOpenOrderSubscriptionsByTag          [x]
    RemoveOpenOrderSubscription                [x]

  Positions
    Get a single position                                            [x]
    Get detailed information for a single position                   [x]
    Get positions for the logged-in client                           [x]
    Get positions for a client, account group, account or a position [x]
    Create a subscription on a list of positions and make it active  [x]
    Change the subscription page size                                [x]
    Remove multiple subscriptions                                    [x]
    Remove a subscription                                            [x]

  Users
    UsersMe                                    [x]
    Users                                      [x]
    UserDetails                                [x]
    UserUpdate                                 [x]

Reference Data
  AlgoStrategies
    Get all strategies                         [x]
    Get details about a specific strategy      [x]
  Countries                                    [x]
  Cultures                                     [x]
  Currencies                                   [x]
  Exchanges
    Get all exchanges                          [x]
    Get details about a specific exchange      [x]
  Instruments
    Instruments                                [x]
    InstrumentsDetails                         [x]
    InstrumentDetails                          [x]
    ContractoptionSpaces                       [x]
    FuturesSpaces                              [ ]
    TradingSchedule                            [x]
  Languages                                    [x]
  StandardDates
    Get a list of forward tenor dates          [x]
    Get a list of FX option expiry dates       [x]
  TimeZones                                    [x]

Root Services
  Diagnostics
    GET test endpoint      [x]
    POST test endpoint     [x]
    PUT test endpoint      [x]
    DELETE test endpoint   [x]
    PATCH test endpoint    [x]
    HEAD test endpoint     [x]
    OPTIONS test endpoint  [x]
    ECHO test endpoint     [x]

  Features
    Get availability of all features           [x]
    Create a feature availability subscription [x]
    Remove a feature availability subscription [x]
  Sessions
    Get Session capabilities                  [x]
    Change Session capabilities               [x]
    Create Session capabilities subscr.       [x]
    Remove Session capabilities subscr.       [x]
  Subscriptions
    Rmove multiple active subscr              [x]
  User                                        [x]

Trading
  AllocationKeys
    Get a list of existing allocation keys    [x]
    Get detailed inform. about an alloc. key  [x]
    Create an allocation key                  [x]
    Delete an allocation key                  [x]
  InfoPrices
    Get an info price for a specific instrum. [x]
    Get info prices for a list of instruments [x]
    Create info pr subscr. on list of instr.  [x]
    Remove info pr subscr. on instruments     [x]
    Remove info pr subscr on an instrument    [x]
  Messages                                    [x]
  OptionChain
    Create options chain subscription         [x]
    Modify options chain subscription         [x]
    Remove options chain subscription         [x]
    ResetATM options chain subscription       [x]
  v1 Orders
  v2 Orders
    Place a new order                         [x]
    Change one or more existing orders        [x]
    Cancel one or more orders                 [x]
    Precheck a single order                   [x]
  Positions
    Create pos by quote                       [x]
    Update a position                         [x]
    Exercise a position                       [x]
    Exercise an amount                        [x]
  Prices
    CreatePriceSubscriptions                  [x]
    RequestMarginImpact                       [x]
    RemovePriceSubscriptionByTag              [x]
    RemovePriceSubscription                   [x]

Value Add
  PriceAlerts
    Get all price alert definitions                   [x]
    Get a specific price alert definition             [x]
    Create a new price alert definition               [x]
    Update an existing price alert def.               [x]
    Delete price alert definitions                    [x]
    Get the current users's notification settings     [x]
    Modify the current users's notification settings  [x]

Top saxo_openapi

Changelog

[Unreleased]

v0.6.0 (2019-09-16)

New Features

Style Fixes

  • fixed flake8 style issues

Documentation Changes

  • [sphinx config] fixed typo

v0.5.0 (2019-09-10)

New Features

  • [endpoints] chart endpoints

    addition of all chart endpoint classes

Documentation Changes

  • [endpoints] chart endpoints documentation

    all chart endpoint classes documentation

  • various doc/docstring updates

v0.4.1 (2019-05-23)

New Features

  • [endpoints] eventnotificationservices

    addition all eventnotificationservices endpoint classes

  • [definitions] activities and reportformats

    addition of definitions for ‘activities’ and ‘reportformats’

Bug Fixes

  • corrected config causing broken build

    replace auto-changelog

Documentation Changes

  • [endpoints] eventnotificationservices

    addition all eventnotificationservices endpoint classes

v0.3.1 (2019-05-04)

v0.3.0 (2019-05-04)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for saxo-openapi, version 0.6.0
Filename, size File type Python version Upload date Hashes
Filename, size saxo_openapi-0.6.0-py2.py3-none-any.whl (123.4 kB) File type Wheel Python version py2.py3 Upload date Hashes View hashes
Filename, size saxo_openapi-0.6.0.tar.gz (72.4 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page