0

So I have a list of instruments in a csv that looks like this:

EUR_HUF
EUR_DKK
USD_MXN
GBP_USD
CAD_CHF
EUR_GBP
GBP_CHF 
...

To submit an order on an individual instrument is done by doing this api request:

import asyncio
import aiohttp
import logging
import json

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer 83da58ee4d8b630115ba04368ed6916c-db53699ac5f596bfd495b835571ed878"
}

async def post(session,instrument):
    headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer 83da58ee4d8b630115ba04368ed6916c-db53699ac5f596bfd495b835571ed878"
    },

    data = {
        "order": {
            "units": 1,
            "instrument": instrument,
            "timeInForce": "FOK",
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    async with session.post(f"https://api-fxpractice.oanda.com/v3/accounts/101-004-22347481-001/orders") as response:
        return await response.text()


async def pre_post(instruments):
    data = {
        "order": {
            "units": 1,
            "instrument": instruments,
            "timeInForce": "FOK",
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    async with aiohttp.ClientSession(headers=headers) as session:
        results = await asyncio.gather(*[post(session,instrument) for instrument in instruments])
        return results


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    instruments = [ "EUR_HUF",
        # "EUR_DKK",
        # "USD_MXN",
        # "GBP_USD",
        # "CAD_CHF",
        # "EUR_GBP",
        # "GBP_CHF"
        ]
    response = loop.run_until_complete(pre_post(instruments))
    print(response)

Now I want to submit an order concurrently for all instruments in my instrument csv. I have looked into threading and AIOhttp but I am not sure how to apply it to my scenario.

Any guidance or example would be appreciated

Thanks

Harry
  • 27
  • 5

2 Answers2

1

Below you'll see an example of how you can send the requests concurrently. Do note that this code isn't complete. acc_num and token are missing since they weren't specified in your question. This should give you an idea and won't require much to modify for your needs.

import asyncio
import aiohttp


async def post(session, token, acc_num, instrument):
    headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + token
    }
    data = {
        "order": {
            "units": 1,
            "instrument": instrument,
            "timeInForce": "FOK",
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    async with session.post(f"https://api-fxpractice.oanda.com/v3/accounts/{acc_num}/orders") as response:
        return await response.text()


async def pre_post(instruments):
    async with aiohttp.ClientSession() as session:
        results = await asyncio.gather(*[fetch(session, token, acc_num, instrument) for instrument in instruments])
        return results


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    instruments = [ "EUR_HUF",
        "EUR_DKK",
        "USD_MXN",
        "GBP_USD",
        "CAD_CHF",
        "EUR_GBP",
        "GBP_CHF" 
        ]
    response = loop.run_until_complete(pre_post(instruments))
    print(response)

Borrowed some code from https://stackoverflow.com/a/51728016/18777481.

  • Thanks Kevin, I changed the fetch to post but It doesnt work. it looks as though its performing each request without the headers – Harry May 10 '22 at 13:33
  • I copied the headers to be outside the first function which seems to fix it. But now I am unable to include the data params for each request. – Harry May 10 '22 at 14:00
  • Hi, did you try adding the `headers=headers` and `data=data` params to the post? – KevinIssaDev May 10 '22 at 14:35
  • I updated the original question with the code I am trying now. It seems it doesnt take the data=data into account – Harry May 10 '22 at 14:47
  • 1
    @Harry You need to pass the data argument to the POST request, `async with session.post("...", data=data)` – KevinIssaDev May 10 '22 at 15:18
  • 1
    Thank you for your help dude! It works YOURE A LEGEND!!! – Harry May 10 '22 at 16:22
1

Thanks to KevinssaDev, I manage to fix it. Here is the complete solution

import asyncio
import aiohttp
import logging
import json

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer 83da58ee4d8b630115ba04368ed6916c-db53699ac5f596bfd495b835571ed878"
}

async def post(session,instrument):
    headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer 83da58ee4d8b630115ba04368ed6916c-db53699ac5f596bfd495b835571ed878"
    },

    data = {
        "order": {
            "units": 1,
            "instrument": instrument,
            "timeInForce": "FOK",
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    async with session.post(f"https://api-fxpractice.oanda.com/v3/accounts/101-004-22347481-001/orders",data=json.dumps(data)) as response:
        return await response.text()


async def pre_post(instruments):
    data = {
        "order": {
            "units": 1,
            "instrument": instruments,
            "timeInForce": "FOK",
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }
    async with aiohttp.ClientSession(headers=headers) as session:
        results = await asyncio.gather(*[post(session,instrument) for instrument in instruments])
        return results


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    instruments = [ "EUR_HUF",
        "EUR_DKK",
        "USD_MXN",
        "GBP_USD",
        "CAD_CHF",
        "EUR_GBP",
        "GBP_CHF"
        ]
    response = loop.run_until_complete(pre_post(instruments))
    print(response)
Harry
  • 27
  • 5