In [1]:
import configparser
# v1 OANDA API
# pip install git+https://github.com/oanda/oandapy.git
# Note: You can request a v1 instead of v20 account by contacting Oanda chat support
import oandapy as opy
config = configparser.ConfigParser()
config.read('oanda.cfg')
oanda = opy.API(environment='practice',
access_token=config['oanda']['access_token'])
In [2]:
import pandas as pd
data = oanda.get_history(instrument='EUR_USD', # our instrument
start='2016-12-08', # start data
end='2016-12-10', # end date
granularity='M1') # minute bars
df = pd.DataFrame(data['candles']).set_index('time')
df.index = pd.DatetimeIndex(df.index)
df.info()
In [3]:
import numpy as np
df['returns'] = np.log(df['closeAsk'] / df['closeAsk'].shift(1))
cols = []
for momentum in [15, 30, 60, 120]:
col = 'position_%s' % momentum
df[col] = np.sign(df['returns'].rolling(momentum).mean())
cols.append(col)
In [33]:
%matplotlib inline
import seaborn as sns; sns.set()
strats = ['returns']
for col in cols:
strat = 'strategy_%s' % col.split('_')[1]
df[strat] = df[col].shift(1) * df['returns']
strats.append(strat)
df[strats].dropna().cumsum().apply(np.exp).plot()
Out[33]:
In [34]:
class MomentumTrader(opy.Streamer):
def __init__(self, momentum, *args, **kwargs):
opy.Streamer.__init__(self, *args, **kwargs)
self.ticks = 0
self.position = 0
self.df = pd.DataFrame()
self.momentum = momentum
self.units = 100000
def create_order(self, side, units):
order = oanda.create_order(config['oanda']['account_id'],
instrument='EUR_USD', units=units, side=side,
type='market')
print('\n', order)
def on_success(self, data):
self.ticks += 1
# print(self.ticks, end=', ')
# appends the new tick data to the DataFrame object
self.df = self.df.append(pd.DataFrame(data['tick'],
index=[data['tick']['time']]))
# transforms the time information to a DatetimeIndex object
self.df.index = pd.DatetimeIndex(self.df['time'])
# resamples the data set to a new, homogeneous interval
dfr = self.df.resample('5s').last()
# calculates the log returns
dfr['returns'] = np.log(dfr['ask'] / dfr['ask'].shift(1))
# derives the positioning according to the momentum strategy
dfr['position'] = np.sign(dfr['returns'].rolling(
self.momentum).mean())
if dfr['position'].ix[-1] == 1:
# go long
if self.position == 0:
self.create_order('buy', self.units)
elif self.position == -1:
self.create_order('buy', self.units * 2)
self.position = 1
elif dfr['position'].ix[-1] == -1:
# go short
if self.position == 0:
self.create_order('sell', self.units)
elif self.position == 1:
self.create_order('sell', self.units * 2)
self.position = -1
if self.ticks == 250:
# close out the position
if self.position == 1:
self.create_order('sell', self.units)
elif self.position == -1:
self.create_order('buy', self.units)
self.disconnect()
In [31]:
mt = MomentumTrader(momentum=12, environment='practice',
access_token=config['oanda']['access_token'])
In [32]:
mt.rates(account_id=config['oanda']['account_id'], instruments=['DE30_EUR'], ignore_heartbeat=True)
In [26]:
mystreamer = opy.Streamer(environment='practice',access_token=config['oanda']['access_token'])
In [22]:
mystreamer.rates(account_id="8ba5b3b5e28cd20292383895127b7991-e910b2fd79a67404fb7efcd8132f85e1", instruments="DE30_EUR")
In [ ]: