def main(): access_token = "df36fd83bc0d3b33010ebbea7feb99d7-5849f313292879ab44e0a824de58e1ad" api = API(access_token=access_token, environment="practice") # count = 2000 count = 100 params = { "count": count, # 足3本取得 "granularity": "M5", # 1分足を取得 "price": "B", # Bidを取得 } instruments_candles = instruments.InstrumentsCandles(instrument="GBP_USD", params=params) try: api.request(instruments_candles) response = instruments_candles.response df = pd.DataFrame([candle["bid"] for candle in response["candles"]], dtype=np.float64) df['v'] = [candle["volume"] for candle in response["candles"]] df.columns = ['Open', 'High', 'Low', 'Close', 'Volume'] df['date'] = [candle["time"] for candle in response["candles"]] df['date'] = pd.to_datetime(df['date']) df.set_index('date', inplace=True) # print(df) for i in range(int(count / 10)): mpf.plot(df[i * 10:(i + 1) * 10], type='candle', style='nightclouds', savefig=f'data/candles{i}.png') # mpf.show() except V20Error as e: print("Error: {}".format(e))
def connect_v20(access_token, accountID, instruments): api = API(access_token=access_token, environment="practice") s = PricingStream(accountID=accountID, params={"instruments": instruments}) response = api.request(s) try: n = 0 for R in api.request(s): # print (msg['type']) if R['type'] == 'HEARTBIT': print(json.dumps(R['type'], indent=2), json.dumps(R['type']['time'], indent=2)) if R['type'] == 'PRICE': instrument = json.loads(json.dumps(R['instrument'], indent=2)) status = json.loads(json.dumps(R['status'], indent=2)) timestamp = json.loads(json.dumps(R['time'], indent=2)) closeoutBid = json.loads(json.dumps(R['closeoutBid'], indent=2)) closeoutAsk = json.loads(json.dumps(R['closeoutAsk'], indent=2)) askBook = json.loads(json.dumps(R['asks'], indent=2)) # influx_record(R['type']) print(instrument, timestamp, closeoutBid, closeoutAsk) position_open(instrument, closeoutBid, closeoutAsk) # for line in askBook: # price = json.loads(json.dumps(line["price"], indent=2)) # liquidity = json.loads(json.dumps(line["liquidity"], indent=2)) # print (price,liquidity) # return instrument,closeoutBid, closeoutAsk # n += 1 # if n > 125: # s.terminate("maxrecs received: {}".format(MAXREC)) except V20Error as e: print("Error: {}".format(e))
def bulkloadlivedatabytime(instrument, granularity, start): # load data from start date to now # example: bulkloadlivedatabytime('EUR_GBP','M15','2017-08-07T00:00:00Z') client = API(access_token=access_token) time = [] value = [] stop_date = datetime.utcnow() start_date = datetime.strptime(start, "%Y-%m-%dT%H:%M:%SZ") diff = stop_date - start_date mins = int(diff.total_seconds() / (60 * 15)) print(mins) stop = stop_date.strftime("%Y-%m-%dT%H:%M:%SZ") print(stop) params = { "from": start, "to": stop, "granularity": granularity, "count": mins } for r in InstrumentsCandlesFactory(instrument=instrument, params=params): client.request(r) data = r.response.get('candles') for k in range(len(data)): time.append(data[k]['time']) value.append(data[k]['mid']['c']) d = {'time': time, instrument: value} df = pandas.DataFrame(data=d) return df
def main(): """ My first attempt at pulling data from Oanda """ oanda_environment = 'Practice' if oanda_environment == 'Live': # oanda_account_id = os.environ['OANDA_ACCOUNTID'] oanda_access_token = os.environ['OANDA_ACCESS_TOKEN'] # oanda_hostname = "api-fxtrade.oanda.com" else: # oanda_account_id = os.environ['OANDA_ACCOUNTID_DEV'] oanda_access_token = os.environ['OANDA_ACCESS_TOKEN_DEV'] # oanda_hostname = "api-fxpractice.oanda.com" # oanda_port = "443" client = API(oanda_access_token) instrument, granularity = "EUR_USD", "M15" _from = "2021-03-01T00:00:00Z" params = {"from": _from, "granularity": granularity} fn = "/tmp/{}.{}.json".format(instrument, granularity) if os.path.isfile(fn): os.remove(fn) with open(fn, "w") as OUT: # The factory returns a generator generating consecutive # requests to retrieve full history from date 'from' till 'to' json_data = list() for r in InstrumentsCandlesFactory(instrument=instrument, params=params): client.request(r) json_data.extend(r.response.get('candles')) OUT.write(json.dumps(json_data, indent=2))
def get_price_data(pair, config_file, output, **kwargs): """Get data from Oanda and put in CSV. Parameters ---------- pair: str The instrument pair in which to fetch prices. config_file : str Location of configuration file. output: str Location and name of output .csv file. """ conf = get_config(config_file) kwargs['price'] = 'BA' r = instruments.InstrumentsCandles(instrument=pair, params=kwargs) api = API(access_token=conf['token']) api.request(r) prices = [] for _ in r.response['candles']: prices.append([ _['time'], _['bid']['c'], _['ask']['c'], float(_['ask']['c']) - float(_['bid']['c']) ]) df = pd.DataFrame(prices) df.columns = ['time', 'bid', 'ask', 'spread'] df.to_csv(output, sep='\t', index=False)
def get_exrate_as_df(instrument='EUR_USD', granularity='D', from_=None, to='2019-03-01', count=100): if from_ is None: params = { 'granularity': granularity, 'to': to, 'count': count, } else: params = { 'granularity': granularity, 'from': from_, 'to': to, } api = API(access_token=ACCESS_TOKEN) r = instruments.InstrumentsCandles(instrument=instrument, params=params) api.request(r) data = [] for row in r.response['candles']: data.append([ row['time'], row['mid']['o'], row['mid']['h'], row['mid']['l'], row['mid']['c'], row['volume'] ]) df = pd.DataFrame(data) df.columns = ['time', 'open', 'high', 'low', 'close', 'volume'] df = df.set_index('time') df.index = pd.to_datetime(df.index) df = df.astype(float) return df
def InstrumentsPositionBook(access_token, instrument, params): # check 'Get positionbook data for a specified Instrument.' r = instruments.InstrumentsPositionBook(instrument=instrument, params=params) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def oanda(): account_id = "" access_token = "" api = API(access_token=access_token, environment="live") params = {"instruments": "USD_JPY"} pricing_info = PricingInfo(accountID=account_id, params=params) oal_ask = 0 oal_ask_pre = 0 oal_bid = 0 oal_bid_pre = 0 try: while True: api.request(pricing_info) response = pricing_info.response oal_ask_pre = oal_ask oal_ask = response['prices'][0]['asks'] oal_bid_pre = oal_bid oal_bid = response['prices'][0]['bids'] if oal_ask != oal_ask_pre: print("oandaask:" + str(oal_ask) + " oandabid:" + str(oal_bid)) except V20Error as e: print("Error: {}".format(e))
def TransactionsTransactionDetails(access_token, accountID, transactionID): 'Get the details of a single Account Transaction.' r = transactions.TransactionDetails(accountID=accountID, transactionID=transactionID) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def oanda_close_positions(side): # API取得 api = API(access_token=token) # 注文内容 if side == "BUY": order_data = {"shortUnits": "ALL"} if side == "SELL": order_data = {"longUnits": "ALL"} while True: # 注文実行 try: r = positions.PositionClose(accountID, instrument=currency, data=order_data) api.request(r) print_log("\nすべての建玉を決済しました\n決済価格は平均 {}円です".format( str(data["forming"]["close_price"]))) return order_data except V20Error as e: print_log("OANDAのAPIで問題発生" + str(e)) print_log("20秒待機してやり直します") time.sleep(20)
class APIClient(object): def __init__(self, access_token, account_id, environment='practice'): self.access_token = access_token self.account_id = account_id self.client = API(access_token=access_token, environment=environment) def get_balance(self) -> Balance: req = accounts.AccountSummary(accountID=self.account_id) try: resp = self.client.request(req) except V20Error as e: logger.error(f'action=get_balance error={e}') raise available = float(resp['account']['balance']) currency = resp['account']['currency'] return Balance(currency, available) def get_ticker(self, product_code) -> Ticker: params = {'instruments': product_code} req = PricingInfo(accountID=self.account_id, params=params) try: resp = self.client.request(req) except V20Error as e: logger.error(f'action=get_ticker error={e}') raise timestamp = datetime.timestamp(dateutil.parser.parse(resp['time'])) price = resp['prices'][0] instrument = price['instrument'] bid = float(price['bids'][0]['price']) ask = float(price['asks'][0]['price']) volume = 11111 return Ticker(instrument, timestamp, bid, ask, volume)
def get_candles(instrument, params): _conf = PyOandaConfig() _api = API(access_token=_conf.access_token, environment="practice") _request = instruments.InstrumentsCandles(instrument=instrument, params=params) _api.request(_request) return _request.response
def get_live_candles(instrument, params): """ @param instrument: @param params: @return: dataframe of live candles data """ client = API(access_token=access_token) r = instruments.InstrumentsCandles(instrument=instrument, params=params) client.request(r) candles = r.response.get("candles") data = [] df1 = pd.DataFrame(candles)[['complete', 'volume', 'time']] df2 = pd.DataFrame(list(pd.DataFrame(candles)['mid'])) df = pd.concat([df1, df2], axis=1) df.rename(mapper={ 'o': 'open', 'h': 'high', 'l': 'low', 'c': 'close' }, inplace=True, axis=1) df['time'] = pd.to_datetime(df['time']) df[['open', 'high', 'low', 'close']] = df[['open', 'high', 'low', 'close']].apply(pd.to_numeric, errors='coerce') return df
def history(instrument, window, collection=False): instrument = instrument data = list() client = API(token) params = {"count": 500, "granularity": window} r = InstrumentsCandles(instrument, params) client.request(r) resp = r.response for candle in resp.get('candles'): dt = candle['time'] Open = candle['mid']['o'] High = candle['mid']['h'] Low = candle['mid']['l'] Close = candle['mid']['c'] Volume = candle['volume'] update = [dt, Open, High, Low, Close, Volume] data.append(update) df = pd.DataFrame(data, columns=['dt', 'Open', 'High', 'Low', 'Close', 'Volume']) # collect data, useful for research and weekends/holidays when the market isn't open if collection == True: title = 'data/%s_%s_history.csv' % (instrument, window) df.to_csv(title) return df
def TransactionsTransactionIDRange(access_token, accountID, params=None): # check 'Get a range of Transactions for an Account based on Transaction IDs.' r = transactions.TransactionIDRange(accountID=accountID, params=params) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def TradesTradeClientExtensions(access_token, accountID, tradeID, data=None): 'Update the Client Extensions for a Trade. Do not add, update or delete the Client Extensions if your account is associated with MT4.' r = trades.TradeClientExtensions(accountID=accountID, tradeID=tradeID, data=data) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def PositionsPositionClose(access_token, accountID, instrument, data=None): 'Closeout the open Position regarding instrument in an Account.' r = positions.PositionClose(accountID=accountID, instrument=instrument, data=data) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def TransactionsTransactionsSinceID(access_token, accountID, params=None): # check 'Get a range of Transactions for an Account starting at (but not including) a provided Transaction ID.' r = transactions.TransactionsSinceID(accountID=accountID, params=params) client = API(access_token=access_token) client.request(r) return readable_output(Munch(r.response)), Munch(r.response)
def order_long(instrument, units, take_profit=None, stop_loss=None): api = API(access_token=oanda_keys['access_token']) mkt_order_long = MarketOrderRequest(instrument=instrument, units=units, takeProfitOnFill=take_profit, stopLossOnFill=stop_loss) r = orders.OrderCreate(oanda_keys['account_id'], data=mkt_order_long.data) api.request(r) return r.response print("Trade Executed")
def PricingPricingStream(access_token, accountID, params=None): # check 'Get realtime pricing information for a specified list of Instruments.' # terminate(message='') to terminate r = pricing.PricingStream(accountID=accountID, params=params) client = API(access_token=access_token) client.request(r) maxrecs = 100 for ticks in r.response: print(dumps(ticks, indent=4, separators=(',', ': '))) if maxrecs == 0: r.terminate("maxrecs records received")
def __init__(self, days=10, read_file=False): # request用パラメータ設定 num_candles = int(days * 24 * 12) # 24h * 60min / 5分刻み minutes = num_candles * 720 # 60 = 12 * 5 分 now = datetime.datetime.now() - datetime.timedelta(hours=9) # 標準時に合わせる start_time = now - datetime.timedelta(minutes=minutes) start_time = start_time.strftime("%Y-%m-%dT%H:%M:00.000000Z") params = { "alignmentTimezone": "Japan", "from": start_time, "count": 5000, "granularity": "H1" # per 1h } access_token = "4122baed289c346a74b193c9bee3937a-b0772f2526c6f7c81eae4e3fc708e66a" api = API(access_token=access_token, environment="practice") request = oandapy.InstrumentsCandles(instrument="USD_JPY", params=params) if read_file == False: # request処理 api.request(request) # request結果データの整形 / クラス外から呼出し可能にする candle = pd.DataFrame.from_dict( [row['mid'] for row in request.response['candles']]) # astype による cast を複数列へ https://qiita.com/driller/items/af1369a5c0fc2ec61af3 candle = candle.astype({ 'c': 'float64', 'l': 'float64', 'h': 'float64', 'o': 'float64' }) candle.columns = ['close', 'high', 'low', 'open'] candle['time'] = [ row['time'] for row in request.response['candles'] ] # 冗長な日時データを短縮整形 https://note.nkmk.me/python-pandas-datetime-timestamp/ candle['time'] = pd.to_datetime(candle['time']).astype(str) FXBase.candles = candle # 読んだファイルを保存しておく f = open('FXBase.candles.binaryfile', 'wb') pickle.dump(FXBase.candles, f) f.close else: f = open('FXBase.candles.binaryfile', 'rb') FXBase.candles = pickle.load(f) # 表示可能な最大行数を設定 pd.set_option("display.max_rows", num_candles)
class Oanda(Broker): def connect(self, access_token, account_id): self.client = API(access_token=access_token) self.account_id = account_id def available(self, type_info): endpoint = AccountInstruments(accountID=self.account_id) rows = self.client.request(endpoint) for row in rows['instruments']: yield itemgetter(*type_info)(row) def iter_price(self, since, to, instrument, ohlc, granularity, volume, abm): dt_format = '%Y-%m-%d %H:%M:%S' rfc3339 = '%Y-%m-%dT%H:%M:%S.%f000Z' iso_since = datetime.strptime(since, dt_format).isoformat() iso_to = None if to: iso_to = datetime.strptime(to, dt_format).isoformat() params = { 'from': iso_since, 'to': iso_to, 'granularity': granularity, 'price': abm } components = { 'A': 'ask', 'B': 'bid', 'M': 'mid' } entrypoint = InstrumentsCandles(instrument=instrument, params=params) rows = self.client.request(entrypoint) instrument = rows['instrument'] for row in rows['candles']: dt = datetime.strptime(row['time'], rfc3339) abm_values = row[components[abm]] price = itemgetter(*ohlc)(abm_values) if volume: yield dt, price, row['volume'] else: yield dt, instrument, float(price)
def stream_prices(pair, config_file, count=0): """Stream price data. Parameters ---------- pair: str The instrument pair in which to fetch prices. config_file : str Location of configuration file. count: int The number of price bars to get; infinite bars if count=0. """ conf = get_config(config_file) api = API(access_token=conf['token'], environment=conf['environment']) r = PricingStream(accountID=conf['account'], params={'instruments': pair}) api.request(r) if 'JPY' in pair: spread_multiplier = 100 else: spread_multiplier = 10000 n = 0 print('\n{}'.format(pair)) while True: try: for _ in api.request(r): if _['type'] == 'PRICE': d = dict(bid=_['bids'][0]['price'], ask=_['asks'][0]['price']) d['spread'] = round(float(d['ask']) * spread_multiplier - float(d['bid']) * spread_multiplier, 1) print('Bid: {}'.format(d['bid'])) print('Ask: {}'.format(d['ask'])) print('Spread: {}\n'.format(d['spread'])) if count: n += 1 else: # Keep looping if no count was specified n = -1 if n >= count: break break except KeyboardInterrupt: break
def oanda_rest_api(account, instrument, action, count, granularity): from oandapyV20 import API import oandapyV20.endpoints.instruments as instruments params = {"count": count, "granularity": granularity} api = API(access_token=account.token) # APIから為替レートのストリーミングを取得 r = instruments.InstrumentsCandles(instrument=instrument, params=params) api.request(r) # 為替レートのdictをDataFrameへ変換 return [action(rate) for rate in r.response['candles']]
def oanda_market(side, lot): # lotが買いか売りを判定する if side == "BUY": units = lot if side == "SELL": units = -1 * lot # 注文内容 order = { 'order': { "instrument": currency, "units": units, "type": "MARKET", "positionFill": "DEFAULT" } } while True: try: # API取得 api = API(access_token=token) order = orders.OrderCreate(accountID, data=order) position = positions.OpenPositions(accountID=accountID) # 注文実行 api.request(order) # API元にrequestを送る(order) position = api.request(position) # API元にrequestを送る(position) time.sleep(20) if units > 0: average_price = position['positions'][0]['long'][ 'averagePrice'] print_log("チケットID : " + position['lastTransactionID'] + "ロングポジションです") print_log( "\nすべての成行注文が執行されました\n執行価格は平均 {}円です".format(average_price)) return float(average_price) elif units < 0: average_price = position['positions'][0]['short'][ 'averagePrice'] print_log("チケットID : " + position['lastTransactionID'] + "ショートポジションです") print_log( "\nすべての成行注文が執行されました\n執行価格は平均 {}円です".format(average_price)) return float(average_price) except V20Error as e: print_log("\nOANDAのAPIで問題発生\n" + str(e) + "\n20秒待機してやり直します") time.sleep(20)
class APIClient(object): def __init__(self, access_token, account_id, environment='practice'): self.access_token = access_token self.account_id = account_id self.client = API(access_token=access_token, environment=environment) def get_balance(self) -> Balance: req = accounts.AccountSummary(accountID=self.account_id) try: resp = self.client.request(req) except V20Error as e: logger.error(f'action=get_balance error={e}') raise available = float(resp['account']['balance']) currency = resp['account']['currency'] return Balance(currency, available) def get_ticker(self, product_code) -> Ticker: params = {'instruments': product_code} req = PricingInfo(accountID=self.account_id, params=params) try: resp = self.client.request(req) except V20Error as e: logger.error(f'action=get_ticker error={e}') raise timestamp = datetime.timestamp(dateutil.parser.parse(resp['time'])) price = resp['prices'][0] instrument = price['instrument'] bid = float(price['bids'][0]['price']) ask = float(price['asks'][0]['price']) volume = self.get_candle_volume() return Ticker(instrument, timestamp, bid, ask, volume) def get_candle_volume(self, count=1, granularity=constants.TRADE_MAP[ settings.trade_duration]['granularity']): params = {'count': count, 'granularity': granularity} req = instruments.InstrumentsCandles(instrument=settings.product_code, params=params) try: resp = self.client.request(req) except V20Error as e: logger.error(f'action=get_candle_volume error={e}') raise return int(resp['candles'][0]['volume'])
def test2(): params = {"count": 10, "granularity": "D"} api = API(access_token=access_token, environment="practice") r = instruments.InstrumentsCandles(instrument="USD_JPY", params=params) rv = api.request(r) print(rv) p0 = rv['candles'][0]['mid']['c'] p1 = rv['candles'][1]['mid']['c'] p2 = rv['candles'][2]['mid']['c'] p3 = rv['candles'][3]['mid']['c'] p4 = rv['candles'][4]['mid']['c'] p5 = rv['candles'][5]['mid']['c'] p6 = rv['candles'][6]['mid']['c'] p7 = rv['candles'][7]['mid']['c'] p8 = rv['candles'][8]['mid']['c'] p9 = rv['candles'][9]['mid']['c'] print (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) if p0 < p1: print ('↑') else: print ('↓')
def __init__(self, _from, _to, gran, instr): '''2017-01-01T00:00:00Z 2017-06-30T00:00:00Z H4 EUR_USD''' client = API(access_token=config['account']['token']) instrument = instr params = {"granularity": gran, "from": _from, "to": _to} for res in InstrumentsCandlesFactory(instrument=instr, params=params): self.rv = client.request(res)
def get_account_info(api: API): """ Get information about your account """ r = accounts.AccountSummary(accountID) return api.request(r)
def get_currency_info(currency_pair: str, api: API): """ Get the designated currency pair's information (e.g.minimum tradable unit, split rate, and so on) Parameters ---------- currency_pair : str currency pair you want to get information e.g. "USD_JPY" api : API Returns ------- r : JSON information of currency pair you designated """ if type(currency_pair) != str: raise Exception('please set currency pair with String.') params = {"instruments": currency_pair} try: r = accounts.AccountInstruments(accountID=accountID, params=params) except Exception: traceback.print_exc() print( 'exception was throwned when app tries to fetch currency info from API.' ) return api.request(r)
def test1(): params ={"instruments": "EUR_USD,EUR_JPY"} # OANDAのデモ口座へのAPI接続 api = API(access_token=access_token, environment="practice") r = pricing.PricingInfo(accountID=accountID, params=params) rv = api.request(r) print(rv['prices'][0]['bids'][0]['price'])
def test__requests_exception(self): """force a requests exception.""" from requests.exceptions import RequestException import oandapyV20.endpoints.accounts as accounts setattr(sys.modules["oandapyV20.oandapyV20"], "TRADING_ENVIRONMENTS", {"practice": { "stream": "ttps://test.com", "api": "ttps://test.com", }}) api = API(environment=environment, access_token=access_token, headers={"Content-Type": "application/json"}) text = "No connection " \ "adapters were found for 'ttps://test.com/v3/accounts'" r = accounts.AccountList() with self.assertRaises(RequestException) as oErr: api.request(r) self.assertEqual("{}".format(oErr.exception), text)