hootnot / oanda-api-v20

OANDA REST-V20 API wrapper. Easy access to OANDA's REST v20 API with oandapyV20 package. Checkout the Jupyter notebooks!
MIT License
398 stars 107 forks source link

asyncio support? #206

Closed spchamp closed 10 months ago

spchamp commented 10 months ago

Has there perhaps been any discussion about introducing asyncio support for oandapyv20?

Alternate Approaches ??

As one hypothetically possible approach for asyncio support with the Oanda REST API in Python, today I was taking a look at using the Python (client) generator from the OpenAPI-generator project, starting with the v20-openapi spec from Oanda. The resulting Python code - as produced with templates in the OpenAPI generator Java libraries - it had a sort of optional asyncio feature. It was able to contact the Oanda server, but it looks like it may not have just matched the request URLs expected by the server. Candidly I haven't tried to debug this further, still quite new to this framework. The code doesn't work, as yet, but for purpose of example I might at least try to publish the tooling for the build.

If evaluating the approach of using OpenAPI-generator to produce AIO code: There is a shell script. It needs Java, Maven 3, and jq. When the script's generator command is applied as follows:

HERE=$PWD
mkdir -p ${HERE}/api/client
cd ${HERE}/api/client
${HERE}/scripts/openapi-generator-cli.sh generate -g python --additional-properties library=asyncio \
  --additional-properties disallowAdditionalPropertiesIfNotPresent=false \
  --additional-properties packageName=project_name \
  --additional-properties packageVersion=1.0.0 \
  --additional-properties projectName=project_name  \
  -i ${HERE}/build/v20-openapi-3.0.25/json/v20.json \
  --invoker-package project_name --skip-validate-spec

...then the generator will produce a complete Python project, including a pyproject.toml and test files, etc, in the current working directory. In the example, that would be api/client when the script is called

The generated code is usable for e.g list_accounts() in the following,

import project_name
from pprint import pprint

configuration = project_name.Configuration( host = 'https://api-fxpractice.oanda.com/' )
async with project_name.ApiClient(configuration) as api_client:
    api_instance = project_name.DefaultApi(api_client)
    auth = 'Bearer <private_bearer_token_from_oanda>'
    api_response = await api_instance.list_accounts(auth)
    pprint(api_response)

I'd seen some errors from this, previously, thus alternately the question about aio support here

After restarting the ipython session, it seems to work though. I'll try to publish the build configuration for this, perhaps it's not an entirely straightforward toolchain albeit.

Applications ?

Towards applying aio support for the Oanda REST API: Candidly, I was thinking about trying to mix asyncio with PySide6 (Qt for Python) starting with the Oanda REST support.

The idea here has been to develop an alternative to MetaTrader 5. While the MetaTrader 5 platform might offer some improvements for calculations, compared to MT4, and it offers support for OpenCL and DirectX but it seems that - perhaps due to the absence of broker support - MetaTrader 5 is principally unavailable for live trading with FX brokers licensed in the US.

afaict the earlier MT4 platform might not do really well with a moderate amount of data- and number-crunching for technical indicators. MT4 does OK with line drawing, but after some technical analysis methods developed by John F. Ehlers, MT4 may almost literally start to crunch.

I understand that it should be possible to use synchronous I/O throughout. Considering the possibility of opening a Qt GUI with a tab for each of a set of trading instruments, I thought it might be useful to start out with AIO if possible, whatever hacks might be needed to keep the Python aio parts synchronized with the Qt GUI.

On the Qt GUI side, there's also PythonQwt. It could probably be extended for a presentation of OHLC time series, as well as tick volume series and time-series data from technical indicators, in a Qt chart window.

Considering the possible complexity of the GUI features, I thought it might be conducive to start with the I/O features first, however.

Synchronous and Asynchronous Methods in the Same API ?

For the I/O components, considering the approach used in the code generated with OpenAPI-generator when applied as in the previous, perhaps it may be possible to implement both aio and synchronous I/O client methods in parallel. The code may seem to rely on the aspect that an async def method would return an async generator, such that can be applied as like an AIO Future under an await expression within some calling function, or otherwise applied within the aio framework.

So, perhaps it may be possible to implement that in parallel with a synchronous I/O implementation.

With apologies for if this may resemble something like a blog article: Thus the question of aio support ...?