Skip to main content

Asynchronous wrapper for OANDA's v20 REST API

Project description

async_v20: Asynchronous OANDA v20 client

A foreign exchange client

async-v20 logo https://travis-ci.org/jamespeterschinner/async_v20.svg?branch=master https://codecov.io/gh/jamespeterschinner/async_v20/branch/master/graph/badge.svg Documentation Status

Documentation

http://async-v20.readthedocs.io/

Disclaimer

  • Losses can exceed investment.

  • async_v20 and its creator has no affiliation with OANDA. And is not endorsed by OANDA in any manner.

  • async_v20 is in Beta stage and has not been tested on a live OANDA account

  • Use at own risk

Features

  • Exposes the entire v20 API

  • No *args, **kwargs In client methods. Therefore no need to guess what arguments a method takes

  • Serialize objects directly into pandas Series or DataFrame objects

  • Construct concurrent trading algorithms

installation

REQUIRES:

python >= 3.6

https://www.python.org/

$ pip install async_v20

async_v20 is built with aiohttp. It is therefore recommended to also install cchardet and aiodns as per aiohttp documentation

$ pip install cchardet

$ pip install aiodns

Why async_v20?

There are many OANDA clients for python already available so why create another? The main driver for creating async_v20 was to facilitate better risk management, by allowing user’s to concurrently monitor account status and trade currency’s.

An unintended consequence of async_v20 is the ability to create clear segregation between implementation ideas.

A simple example might contain a coroutine for the following:

  • Monitoring overall account status

  • Watching price stream and triggering buy/sell signals

  • Monitoring individual trades and closing movements against held positions

A synchronous implementation would require considerable effort to determine which task communicates with the server next. async_v20 removes this burden by using aiohttp

Further goals of async_v20 has been to lower the barrier of entry for algorithmic trading by providing a complete and simple to use interface.

Getting started

Creating an Account

To use async_v20 you must have an account with OANDA

Setting up environment

  • Install async_v20 as per installation

  • Create a new environment variable with the name ‘OANDA_TOKEN’ and value as the token generated from above

Note:

  • It is considered best practice use a virtual environment

  • It is not required to store the token in an environment variable. The token can be passed to OandaClient

Using async_v20

Once an account has been created as per create-account and the environment is configured as per setting-up-environment we are ready to begin.

Lets first take a look at this code example, then go though it line by line.

import asyncio

from async_v20 import OandaClient


async def get_account():
    async with OandaClient() as client:
        return await client.account()


loop = asyncio.get_event_loop()
account = loop.run_until_complete(get_account())

# pandas Series
print(account.series())

# HTTP response state
print(account)

# JSON data in python dictionary format
print(account.dict())

First we need to import asyncio this allows us to run our coroutine

import asyncio

We then import OandaClient which provides us the means to interact with OANDA

from async_v20 import OandaClient

Because OandaClient returns coroutines we use async def. This allows the use of the await syntax

async def get_account():

OandaClient is a context manager, we use async with to instantiate a client instance. Doing so will automatically close the http session when we’re done

async with OandaClient() as client:

We then create and run the coroutine by calling client. account()

return await client.account()

Now we have defined our coroutine we need to execute it. To do so we need an event loop. Achieved using asyncio. get_event_loop()

loop = asyncio.get_event_loop()

The value returned by executing the account() coroutine is accessed through the event loop.

account = loop.run_until_complete(get_account())

async_v20 objects have a series() method that returns a pandas. Series. By default async_v20. DateTime’s will be converted into pandas. Timestamp’s.

print(account.series())

Outputs

alias                                                          Primary
balance                                                        97801.9
commission                                                           0
created_by_user_id                                             1234567
created_time                       2017-08-11 15:04:31.639182352+00:00
currency                                                           AUD
financing                                                      -3.5596
hedging_enabled                                                  False
id                                                 123-123-1234567-123
last_margin_call_extension_time                                   None
last_transaction_id                                               6360
margin_available                                               97801.9
margin_call_enter_time                                            None
margin_call_extension_count                                       None
margin_call_margin_used                                              0
margin_call_percent                                                  0
margin_closeout_margin_used                                          0
margin_closeout_nav                                            97801.9
margin_closeout_percent                                              0
margin_closeout_position_value                                       0
margin_closeout_unrealized_pl                                        0
margin_rate                                                       0.02
margin_used                                                          0
nav                                                            97801.9
open_position_count                                                  0
open_trade_count                                                     0
orders                                                              []
pending_order_count                                                  0
pl                                                            -2194.53
position_value                                                       0
positions                                                           []
resettable_pl                                                 -2194.53
resettabled_pl_time                                               None
trades                                                              []
unrealized_pl                                                        0
withdrawal_limit                                               97801.9
dtype: object

Changelog

6.2.1b0

  • Array class lazy instantiates objects

  • Model objects with same attributes now compare equal (proving equal DateTime format)

  • Improved repr of Array objects

  • Improved implementation of get_instrument/s, get_id

  • All Array objects have get_instrument and get_instruments. Returns either the first or all matching objects

  • Removed Model class _template attribute as it was obsolete

  • Added get(self, name, default=None) method to Model to allow for dict like key access.

6.2.0b0

  • Changed get_transactions method to get_transaction (API call can only return one transaction)

  • Removed default parameter argument for get_transaction.(transaction_id) it is a required parameter.

  • Made OandaClient.hosts a protected member. Now OandaClient._hosts

  • Array. get_instruments() returns an Array of the same type this is when there is a one to many relationship between the instrument and objects the array contains. Array. get_instrument() Returns the single object when there is a one to one relationship. Both methods are mutually exclusive

  • All objects now lazy instantiate attribute instances.

  • Large refactoring of async_v20.definitions.base

6.1.0b0

  • Changed incorrect naming _i_ds to _ids

  • Fixed OrderRequest formatting when a OrderRequest instance is passed that defines an instrument.

6.0.2b0

  • Fixed InvalidFormatRequest Error when OrderRequest does not define an instrument attribute

6.0.1b0

  • Fixed incorrect handling of stream response when endpoint returned status 400

6.0.0b0

  • Added health API and initialization check

  • Fixed stream_transactions. Now returns correct type

  • Changed streaming responses keys. Where stream_pricing() returned ‘PRICE’ or ‘HEARTBEAT’ response now contains ‘price’ or ‘heartbeat’. Like wise stream_transactions() now returns ‘transaction’ or ‘heartbeat’. This has been done to standardise access to the transaction stream response and ‘heartbeat’ objects. Due to the different types these objects may take.

  • Added async_v20.exceptions module

  • Added logging to modules

5.0.3b0

  • Added default argument to Array.get_id & Array.get_instrument

  • Removed default value from get_candles(count)

5.0.2b0

  • Fixed bug in rest implementation. Positions now update correctly

5.0.1b0

  • OandaClient.datetime_format is read only

  • OandaClient._instruments is no longer a protected attribute. It is now OandaClient.instruments

5.0.0b0

  • DateTime’s create pandas.Timestamp’s

  • Model.dict argument datetime is now datetime_format. Argument behaviour now specifies the representation of times. Either RFC3339 or UNIX. Corresponding json argument changes the representation of UNIX times to either a str or numpy.int64

  • Response .json() accepts datetime_format argument string

4.0.0b0

  • Changed get_positions to get_position (as method can only close one position)

  • _in_context accepts negative units

3.0.0b0

  • Array.get_instrument() works with ArrayInstrument

  • OandaClient.initialize() gets account instruments

  • OandaClient has format_order_request attribute

  • async_v20.definitions.primitives.Unit has been removed

  • PriceValue and Decimal number has additional method format(precision, min_, max_)

2.3.0b0

  • Updated limit_replace_order() method to expose all arguments

  • TransactionID, TradeID & OrderID get stored as integers and cast to strings when creating JSON representations

  • Added documentation for order API methods

2.2.5b2

  • Fixed get_candles default value

2.2.5b1

  • RejectTransactions have no required arguments

  • API methods now apply default values

  • Added undocumented attributes

  • Path class has been removed in favour of helper function. Allowing for more useful error message on failure.

2.2.5b0

  • PriceComponent accepts all combinations of ‘M’ ‘A’ ‘B’

2.2.4b3

Added attributes to TradeSummary:
  • margin_used

2.2.4b1

Added attributes to TradeReduce:
  • guaranteed_execution_fee

2.2.4b0

Added attributes to Transaction:
  • guaranteed_execution_fee

  • gain_quote_home_conversion_factor

  • loss_quote_home_conversion_factor

Added attributes to TradeOpen:
  • price

  • guaranteed_execution_fee

2.2.3b0

  • Added ‘margin_used’ to Position object. (OANDA added new attribute, causing error)

  • Added TimeoutError to stream

2.2.2b0

  • Added get_position_book and get_order_book API calls

2.2.1b0

  • series() method converts both UNIX and RFC3339 time’s to pandas.Timestamp ‘s

2.2.0b0

  • Initialization doesn’t freeze after failure

  • Order methods exposes all arguments

2.1.0b0

  • Beta release. At present time client is considered feature full with 100% test coverage

  • _fields attribute stored on instance not class

  • RESTful account() method added

  • close_all_trades() method added

  • Added replace() method to Model

  • Simplified Endpoint decorator (No serial requests)

  • Changes close_trades to close_trade (Method can only close one trade)

  • Response parser checks HTTP status first

  • Added tests

2.0.1a0

  • type argument is set automatically for subclass that define it

  • implementation improvements

2.0.0a0

  • async_v20 objects are now immutable (greatly reducing complexity)

  • Objects now have a repr

  • removed inflection as a dependency

  • Higher test coverage

1.1.6a0

  • Issue with object serialization not working with lists of Type[str, float, int]

1.1.5a4

  • Argument passing

1.1.5a3

  • Fix long description on PyPI

1.1.5a0

  • method signatures were offset buy 1 argument due to handling of ‘self’ parameter. Methods now displaying correct signature

1.1.4a0

  • Fixed incorrect annotation on:

  • PUTPositionsInstrumentClose

  • GETPositionsInstrument

1.1.3a0

  • Fixed incorrect annotation on Interface methods

  • Fixed argument passing bug caused by false’y evaluation

1.1.2a5

  • Added Travis CI

  • Added Codecov

1.1.2a4

  • Additional documentation

1.1.2a1

  • OandaClient.initialize() method is now exposed

  • OandaClient is now also a context manager. To automatically close the http session

  • Additional documentation

1.1.1a1

  • Floating point numbers are rounded to the correct accuracy required for correct serialization.

1.1.0a1

  • Model.series() returns data in more specific types instead of all ‘str’

  • OandaClient methods now have correct signature instead of args, kwargs

1.0.1a1

  • Fixed code examples in bin directory

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

async_v20-6.2.1b1.tar.gz (145.5 kB view hashes)

Uploaded Source

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