Introduction To OANDA-System


Environment:

  • Python-Anaconda 2.7
  • pandas, json, requests

Config Class

  • Contains infomations that we need to connect to OANDA server and make requests.

In [2]:
from api import*

myConfig = Config()
myConfig.view()


{
    "config_body": {
        "account_id": 2804581, 
        "domain": "api-sandbox.oanda.com", 
        "domain_stream": "stream-sandbox.oanda.com", 
        "header": {
            "Authorization": "Bearer 4c56cbf8105642050bbfdb36aad29c6a-77dfc84d1fc6a2ced8e1b15641d0d69e", 
            "Connection": "keep-alive", 
            "Content-Type": "application/x-www-form-urlencoded", 
            "X-Accept-Datetime-Format": "unix"
        }, 
        "password": "DequejHid&", 
        "ssl": false, 
        "username": "geonaroben", 
        "version": "v1"
    }, 
    "config_head": "my token", 
    "user_token": "4c56cbf8105642050bbfdb36aad29c6a-77dfc84d1fc6a2ced8e1b15641d0d69e"
}

Data Containers

  • Tick
  • Bar

Event Objects

  • market event
  • bar event
  • signal event
  • order event
  • fill event

Event Queue Object

  • Should be structured in a dictionary with specific names.

In [4]:
q1 = EventQueue()
q2 = EventQueue()
q = {'mkt': q1, 'bar': q2}

Api class

  • The object that make every requests. Basis of the entire system.
  • Initialized with Config( ) and a dictionary of event queues. ( )

In [5]:
myapi = PyApi(Config(), q)

Simple Requests

  • get instruments
  • get account infomation
  • get positions
  • get orders
  • get price
  • get historical data

the return value of these functions are json-like dictionaries. (see examples)

get_instruments( )


In [27]:
instrumentList = myapi.get_instruments()
print instrumentList['instruments'][0:3]


[{u'pip': u'1.0', u'instrument': u'AU200_AUD', u'maxTradeUnits': 200, u'displayName': u'Australia 200'}, {u'pip': u'0.0001', u'instrument': u'AUD_CAD', u'maxTradeUnits': 10000000, u'displayName': u'AUD/CAD'}, {u'pip': u'0.0001', u'instrument': u'AUD_CHF', u'maxTradeUnits': 10000000, u'displayName': u'AUD/CHF'}]

Beautify JSON output


In [28]:
import json
print json.dumps(instrumentList['instruments'][0:3], sort_keys=True, indent=4)


[
    {
        "displayName": "Australia 200", 
        "instrument": "AU200_AUD", 
        "maxTradeUnits": 200, 
        "pip": "1.0"
    }, 
    {
        "displayName": "AUD/CAD", 
        "instrument": "AUD_CAD", 
        "maxTradeUnits": 10000000, 
        "pip": "0.0001"
    }, 
    {
        "displayName": "AUD/CHF", 
        "instrument": "AUD_CHF", 
        "maxTradeUnits": 10000000, 
        "pip": "0.0001"
    }
]

get_prices(instrument)

  • instrument: string

In [8]:
print json.dumps(myapi.get_prices("EUR_USD"), sort_keys=True, indent=4)


{
    "prices": [
        {
            "ask": 1.24068, 
            "bid": 1.24054, 
            "instrument": "EUR_USD", 
            "time": "1442024548072937"
        }
    ]
}

get_account_info(account_id=-1)

  • account_id: integer/string, the account id. Default = -1, use that in config.

In [10]:
print json.dumps(myapi.get_account_info(), sort_keys=True, indent=4)


{
    "accountCurrency": "USD", 
    "accountId": 2804581, 
    "accountName": "Primary", 
    "balance": 100010.825, 
    "marginAvail": 99997.1247, 
    "marginRate": 0.05, 
    "marginUsed": 13.7024, 
    "openOrders": 1, 
    "openTrades": 4, 
    "realizedPl": -0.0125, 
    "unrealizedPl": 0.0021
}

get_positions( )

  • TODO:

In [11]:
print json.dumps(myapi.get_positions(), sort_keys=True, indent=4)


{
    "positions": [
        {
            "avgPrice": 1.24082, 
            "instrument": "EUR_USD", 
            "side": "sell", 
            "units": 100
        }, 
        {
            "avgPrice": 1.14339, 
            "instrument": "USD_CAD", 
            "side": "buy", 
            "units": 150
        }
    ]
}

get_orders( )

  • TODO:

In [13]:
print json.dumps(myapi.get_orders(), sort_keys=True, indent=4)


{
    "orders": [
        {
            "expiry": "1442094172000000", 
            "id": 175583929, 
            "instrument": "USD_CAD", 
            "lowerBound": 0, 
            "price": 0.994, 
            "side": "buy", 
            "stopLoss": 0, 
            "takeProfit": 0, 
            "time": "1442022173000000", 
            "trailingStop": 0, 
            "type": "limit", 
            "units": 50, 
            "upperBound": 0
        }
    ]
}

get_trades( )

  • TODO:

In [15]:
print json.dumps(myapi.get_trades(), sort_keys=True, indent=4)


{
    "trades": [
        {
            "id": 175583938, 
            "instrument": "USD_CAD", 
            "price": 1.14335, 
            "side": "buy", 
            "stopLoss": 0, 
            "takeProfit": 0, 
            "time": "1442023302000000", 
            "trailingAmount": 0, 
            "trailingStop": 0, 
            "units": 100
        }, 
        {
            "id": 175583937, 
            "instrument": "EUR_USD", 
            "price": 1.24082, 
            "side": "sell", 
            "stopLoss": 0, 
            "takeProfit": 0, 
            "time": "1442023190000000", 
            "trailingAmount": 0, 
            "trailingStop": 0, 
            "units": 50
        }, 
        {
            "id": 175583936, 
            "instrument": "EUR_USD", 
            "price": 1.24082, 
            "side": "sell", 
            "stopLoss": 0, 
            "takeProfit": 0, 
            "time": "1442023181000000", 
            "trailingAmount": 0, 
            "trailingStop": 0, 
            "units": 50
        }, 
        {
            "id": 175583930, 
            "instrument": "USD_CAD", 
            "price": 1.14346, 
            "side": "buy", 
            "stopLoss": 0, 
            "takeProfit": 0, 
            "time": "1442022173000000", 
            "trailingAmount": 0, 
            "trailingStop": 0, 
            "units": 50
        }
    ]
}

place_order( )

  • params: see docs in .py file

In [19]:
print json.dumps(myapi.get_positions(), sort_keys=True, indent=4)
myapi.place_order('USD_CAD', 'sell', 150, None, 'market') #fill USD_CAD long position
print '\n--------------AFTER--------------\n'
print json.dumps(myapi.get_positions(), sort_keys=True, indent=4)


{
    "positions": [
        {
            "avgPrice": 1.24082, 
            "instrument": "EUR_USD", 
            "side": "sell", 
            "units": 100
        }, 
        {
            "avgPrice": 1.14357, 
            "instrument": "USD_CAD", 
            "side": "buy", 
            "units": 150
        }
    ]
}

--------------AFTER--------------

{
    "positions": [
        {
            "avgPrice": 1.24082, 
            "instrument": "EUR_USD", 
            "side": "sell", 
            "units": 100
        }
    ]
}

Streaming

  • PyApi.make_stream(instrument)
  • Monitor market impulses.
  • Support strategies.

In [22]:
from strat import *
class BuyAndHold(BaseStrategy):
    """
    some parameters here.
    """
    instrument = 'USD_CAD'
    BHFlag = True

    def __init__(self, api):
        """
        override constructor.
        """
        self.api = api

    def on_bar(self, event):
        """
        Strategy logics.
        """
        if self.BHFlag: # If BHFlag == True, buy 100 CA dollar
            self.market_buy(100)
            self.BHFlag = 0 # then hold.

        # Print account summary and bar data.
        print '---------------------'
        print json.dumps(self.api.get_account_info(), sort_keys=True, indent=4)
        print '\n---------------------\n'
        event.body.view()
        print '---------------------'

In [ ]:
q1 = EventQueue()
    q2 = EventQueue()
    q = {'mkt': q1, 'bar': q2} # construct event queues
    
    api = PyApi(Config(), q) # initialize api

    mystrat = BuyAndHold(api) # initialize strategy

    q1.bind('ETYPE_MKT', api.on_market_impulse) # let queues listen to some events
    q2.bind('ETYPE_BAR', mystrat.on_bar)

    q1.open() # start pushing event to strategies and other functions
    q2.open()
    api.make_stream('USD_CAD') # make connection to server.