Skip to main content

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.

TOC

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

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.

Source Distribution

saxo_openapi-0.6.0.tar.gz (72.4 kB view details)

Uploaded Source

Built Distribution

saxo_openapi-0.6.0-py2.py3-none-any.whl (123.4 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file saxo_openapi-0.6.0.tar.gz.

File metadata

  • Download URL: saxo_openapi-0.6.0.tar.gz
  • Upload date:
  • Size: 72.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.14.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.3

File hashes

Hashes for saxo_openapi-0.6.0.tar.gz
Algorithm Hash digest
SHA256 88d16ecae4f11885a68f7064bb1addb6dc1ece19c3e09c21609527783c458636
MD5 c6c44f872ef7d3824389a398fc07c9d4
BLAKE2b-256 92fc689a3a0899a04464e48a67d11cc3130234605170d52bfd4ede289de68630

See more details on using hashes here.

File details

Details for the file saxo_openapi-0.6.0-py2.py3-none-any.whl.

File metadata

  • Download URL: saxo_openapi-0.6.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 123.4 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.14.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.3

File hashes

Hashes for saxo_openapi-0.6.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 03857bb81c5f8e77c8f679de233f1edb7dbb4f585d2c253350b5ba4e74211119
MD5 6f6afd4964f2061be069565dd3e3bebd
BLAKE2b-256 399a2182948a822b484b8f0fc458d690878d30c2866f1fd4ae5d409ea7e3716f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page