def __initclist(self): ''' Private function to initialize the CandleList object that goes from self.start to self.period This will set the self.clist_period class attribute ''' delta_period = periodToDelta(self.period, self.timeframe) delta_1 = periodToDelta(1, self.timeframe) start = self.start - delta_period # get the start datetime for this CandleList period end = self.start + delta_1 # increase self.start by one candle to include self.start oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) oanda.run(start=start.isoformat(), end=end.isoformat(), roll=True) candle_list = oanda.fetch_candleset(vol_cutoff=0) cl = CandleList(candle_list, self.pair, granularity=self.timeframe, id=self.id, type=self.type) self.clist_period = cl
def fetch_candlelist(self): ''' This function returns a CandleList object for this Trade Returns ------- A CandleList object ''' oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], start=datetime.datetime.strptime(self.start, '%Y-%m-%dT%H:%M:%S').isoformat(), dailyAlignment=config.OANDA_API['dailyAlignment'], end=datetime.datetime.strptime(self.end, '%Y-%m-%dT%H:%M:%S').isoformat()) candle_list = oanda.fetch_candleset() cl = CandleList(candle_list, type=self.type) return cl
def __init__(self): self.log = LogWrapper("TradingBot") self.tech_log = LogWrapper("TechnicalsBot") self.trade_pairs = Settings.get_pairs() self.settings = Settings.load_settings() self.api = OandaAPI() self.timings = { p: Timing(self.api.last_complete_candle(p, GRANULARITY)) for p in self.trade_pairs } self.log_message(f"Bot started with\n{pprint.pformat(self.settings)}") self.log_message(f"Bot Timings\n{pprint.pformat(self.timings)}")
class TradingBot(): def __init__(self): self.log = LogWrapper("Bot") self.tech_log = LogWrapper("Technicals") self.trade_log = LogWrapper("Trade") self.trade_pairs = Settings.get_pairs() self.settings = Settings.load_settings() self.api = OandaAPI() self.trade_manager = TradeManager(self.api, self.settings, self.trade_log) self.timings = { p: Timing(self.api.last_complete_candle(p, GRANULARITY)) for p in self.trade_pairs } self.log_message(f"Bot started with\n{pprint.pformat(self.settings)}") self.log_message(f"Bot Timings\n{pprint.pformat(self.timings)}") def log_message(self, msg): self.log.logger.debug(msg) def update_timings(self): for pair in self.trade_pairs: current = self.api.last_complete_candle(pair, GRANULARITY) self.timings[pair].ready = False if current > self.timings[pair].last_candle: self.timings[pair].ready = True self.timings[pair].last_candle = current self.log_message(f"{pair} new candle {current}") def process_pairs(self): trades_to_make = [] for pair in self.trade_pairs: if self.timings[pair].ready == True: self.log_message(f"Ready to trade {pair}") techs = Technicals(self.settings[pair], self.api, pair, GRANULARITY, log=self.tech_log) decision = techs.get_trade_decision( self.timings[pair].last_candle) units = decision * self.settings[pair].units if units != 0: trades_to_make.append({'pair': pair, 'units': units}) if len(trades_to_make) > 0: print(trades_to_make) self.trade_manager.place_trades(trades_to_make) def run(self): while True: self.update_timings() self.process_pairs() time.sleep(SLEEP)
def oanda_object(): '''Returns an oanda object''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='EUR_AUD', granularity='D', dailyAlignment=22, alignmentTimezone='Europe/London') oanda.run(start='2015-08-26T22:00:00', end='2016-08-15T22:00:00') return oanda
def trend_oanda_object(): '''Returns an oanda object for a candlelist representing a trend''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='D', alignmentTimezone='Europe/London', dailyAlignment=22) oanda.run(start='2017-12-08T22:00:00', end='2018-01-29T22:00:00', roll=True) return oanda
def __get_time4candles(self, n, anchor_point, roll=True): ''' This private function takes a a number of candles and returns a Datetime corresponding to this number of candles Parameters ---------- n : int Number of candles anchor_point : datetime Datetime used as the anchor (end point from which it will go back 'n' candles) for calculation roll : boolean if True, then if will try to go back in time in order to get exactly 'n' number of candles. Default: True Returns ------- Datetime.datetime ''' delta_from_start = None delta_one = None if self.timeframe == "D": delta_from_start = datetime.timedelta(hours=24 * n) delta_one = datetime.timedelta(hours=24) else: fgran = self.timeframe.replace('H', '') delta_from_start = datetime.timedelta(hours=int(fgran) * n) delta_one = datetime.timedelta(hours=int(fgran)) # calculate the cutoff for the first threshold using the number of candles oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) start = anchor_point - delta_from_start if roll is True: if start < config.START_HIST[self.pair]: #return the first candle in the record if start goes back before the start of the record return config.START_HIST[self.pair] else: end = anchor_point.isoformat() oanda.run(start=start.isoformat(), end=end, roll=True) candle_list = oanda.fetch_candleset() # if len of candle_list is below n then go back one candle at a time while len(candle_list) < n: start = start - delta_one oanda.run(start=start.isoformat(), end=end, roll=True) candle_list = oanda.fetch_candleset() return start else: return start
def test_OandaAPI13(): ''' :return: ''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='H6', alignmentTimezone='Europe/London', dailyAlignment=22) oanda.run(start='2007-05-29T16:00:00', end='2014-04-01T15:00:00', roll=True)
def run_collection(): pair_list = "GBP,EUR,USD,CAD,JPY,NZD,CHF" api = OandaAPI() for g in INCREMENTS.keys(): for i in Instrument.get_pairs_from_string(pair_list): print(g, i) create_file(i, g, api)
def __init_clist_period(self): ''' Private function to initialise self.clist_period class attribute This function process the candlelist going from self.start-self.period to self.start ''' warnings.warn("[INFO] Run __init_clist_period") delta_period = None delta_1 = None if self.timeframe == "D": delta_period = datetime.timedelta(hours=24 * self.period) delta_1 = datetime.timedelta(hours=24) else: fgran = self.timeframe.replace('H', '') delta_period = datetime.timedelta(hours=int(fgran) * self.period) delta_1 = datetime.timedelta(hours=int(fgran)) start = self.start - delta_period end = self.start + delta_1 oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) oanda.run(start=start.isoformat(), end=end.isoformat(), roll=True) candle_list = oanda.fetch_candleset(vol_cutoff=0) cl = CandleList(candle_list, self.pair, granularity=self.timeframe, id=self.id) warnings.warn("[INFO] Run cl.calc_rsi") cl.calc_rsi() warnings.warn("[INFO] Done cl.calc_rsi") self.clist_period = cl
def get_cross_time(self, candle, granularity='M30'): ''' This function is used get the time that the candle crosses (go through) HArea Parameters ---------- candle : Candle object that crosses the HArea granularity : To what granularity we should descend Returns ------ datetime object with crossing time. n.a. if crossing time could not retrieved. This can happens when there is an artifactual jump in the Oanda data ''' if candle.lowAsk <= self.price <= candle.highAsk: delta = None if self.granularity == "D": delta = timedelta(hours=24) else: fgran = self.granularity.replace('H', '') delta = timedelta(hours=int(fgran)) cstart = candle.time cend = cstart + delta oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.instrument, granularity=granularity, dailyAlignment=config.OANDA_API['dailyAlignment'], alignmentTimezone=config.OANDA_API['alignmentTimezone']) oanda.run(start=cstart.isoformat(), end=cend.isoformat(), roll=True) candle_list = oanda.fetch_candleset() for c in candle_list: if c.lowAsk <= self.price <= c.highAsk: return c.time else: return 'n.a.'
def cl_object(): '''Returns CandleList object''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='D', alignmentTimezone='Europe/London', dailyAlignment=22) oanda.run(start='2018-01-25T22:00:00', end='2018-10-12T22:00:00', roll=True) candle_list = oanda.fetch_candleset() cl = CandleList(candle_list, instrument='AUD_USD', type='long') return cl
class TradingBot(): def __init__(self): self.log = LogWrapper("TradingBot") self.tech_log = LogWrapper("TechnicalsBot") self.trade_pairs = Settings.get_pairs() self.settings = Settings.load_settings() self.api = OandaAPI() self.timings = { p: Timing(self.api.last_complete_candle(p, GRANULARITY)) for p in self.trade_pairs } self.log_message(f"Bot started with\n{pprint.pformat(self.settings)}") self.log_message(f"Bot Timings\n{pprint.pformat(self.timings)}") def log_message(self, msg): self.log.logger.debug(msg) def update_timings(self): for pair in self.trade_pairs: current = self.api.last_complete_candle(pair, GRANULARITY) self.timings[pair].ready = False if current > self.timings[pair].last_candle: self.timings[pair].ready = True self.timings[pair].last_candle = current self.log_message(f"{pair} new candle {current}") def process_pairs(self): for pair in self.trade_pairs: if self.timings[pair].ready == True: self.log_message(f"Ready to trade {pair}") techs = Technicals(self.settings[pair], self.api, pair, GRANULARITY, log=self.tech_log) decision = techs.get_trade_decision(self.timings[pair].last_candle) units = decision * self.settings[pair].units if units != 0: self.log_message(f"we would trade {units} units") def run(self): while True: print('update_timings()...') self.update_timings() print('process_pairs()...') self.process_pairs() print('sleep()...') time.sleep(SLEEP)
def __init_clist_trend(self): ''' Private function to initialise self.clist_trend class attribute This function process the candlelist going from self.trend_i to self.start ''' warnings.warn("[INFO] Run __init_clist_trend") # if trend_i is not defined then calculate it if hasattr(self, 'trend_i'): self.trend_i = datetime.datetime.strptime(self.trend_i, '%Y-%m-%d %H:%M:%S') else: self.calc_itrend() self.__init_clist_trend() # checking for feats in trend before 1st bounce oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) oanda.run(start=self.trend_i.isoformat(), end=self.start.isoformat(), roll=True) candle_list = oanda.fetch_candleset(vol_cutoff=0) cl = CandleList(candle_list, instrument=self.pair, granularity=self.timeframe, id=self.id) warnings.warn("[INFO] Run cl.calc_rsi") cl.calc_rsi() warnings.warn("[INFO] Done cl.calc_rsi") self.clist_trend = cl
def oanda_object(): '''Returns an oanda object''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='D', alignmentTimezone='Europe/London', dailyAlignment=22) return oanda
def oanda_object(): '''Returns an oanda object''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='D', alignmentTimezone='Europe/London', start='2015-01-25T22:00:00', end='2015-01-26T22:00:00') return oanda
def prepare_data(): api = OandaAPI() data = [] for p in PAIRS: row = get_pair_data(p, api) if row is not None: data.append(row) final_df = pd.concat(data) final_df['time'] = [dt.datetime.strftime(x, "%Y-%m-%d %H:%M:%S") for x in final_df.time] return json.dumps(final_df.to_dict(orient='records'))
def pl_object2(): '''Returns PivotList object''' oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument='AUD_USD', granularity='D', alignmentTimezone='Europe/London', dailyAlignment=22) oanda.run(start='2016-01-15T22:00:00', end='2016-08-17T22:00:00', roll=True) candle_list = oanda.fetch_candleset() cl = CandleList(candle_list, instrument='AUD_USD', type='long') pl = cl.get_pivotlist(outfile='test.png', th_up=0.02, th_down=-0.02) return pl
def set_valley(self): ''' Function to calculate the length of the valley between bounce_1st & bounce_2nd Returns ------- It will set the 'valley' attribute of the class ''' oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) oanda.run(start=self.bounce_2nd.time.isoformat(), end=self.bounce_1st.time.isoformat()) candle_list = oanda.fetch_candleset(vol_cutoff=0) self.valley = len(candle_list)
from oanda_api import OandaAPI import logging logging.basicConfig(level=logging.INFO) logging.info("Program started") #loanda=OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?',instrument='EUR_USD',granularity='H8',alignmentTimezone='Europe/London',dailyAlignment=22,start='2016-09-13T06:00:00',count=40) oanda=OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?',instrument='EUR_USD',granularity='H8',alignmentTimezone='Europe/London',dailyAlignment=22,start='2016-10-24T22:00:00',count=1) print(oanda.print_url()) candlelist=oanda.fetch_candleset() for c in candlelist: c.set_candle_features() c.set_candle_formation() print("%s %s" % (c.representation,c.time)) logging.info("Done!")
from oanda_api import OandaAPI, Reversal import pandas as pd from pandas.tseries.offsets import BDay import logging logging.basicConfig(level=logging.INFO) logging.info("Program started") oanda = OandaAPI() list = oanda.fetch_candles_from_file( "/Users/ernesto/projects/FOREX/data/21_04_15.txt") ic = "2015-04-20" r = Reversal(list, True) p_highBid = 0.0 p_lowBid = 0.0 middle = (len(list) / 2) for k, i in enumerate(list): if (k == 0): p_highBid = float(i.highBid) p_lowBid = float(i.lowBid) else: c_highBid = float(i.highBid) - p_highBid c_lowBid = float(i.lowBid) - p_lowBid print "highBid:%s lowBid:%s time:%s" % (c_highBid, c_lowBid, i.time) p_highBid = float(i.highBid) p_lowBid = float(i.lowBid) print "h"
from oanda_api import OandaAPI api = OandaAPI() while True: command = input("Enter command:") if command == "T": print("Make a trade") trade_id, ok = api.place_trade("EUR_USD", 1000) print('trade_id', trade_id) if command == "C": print('Closing', trade_id) print(api.close_trade(trade_id)) if command == "Q": break
help= 'End time. If defined, do the analysis for time period between start and end' ) parser.add_argument('--trade_type', type=str, required=True, help='Type of trade. Possible values are short, long') args = parser.parse_args() oanda = None if args.end is not None: oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument=args.instrument, granularity=args.granularity, alignmentTimezone='Europe/London', dailyAlignment=22, start=args.start, end=args.end) else: oanda = OandaAPI(url='https://api-fxtrade.oanda.com/v1/candles?', instrument=args.instrument, granularity=args.granularity, alignmentTimezone='Europe/London', dailyAlignment=22, start=args.start) candle_list = oanda.fetch_candleset() trade_type = str(args.trade_type) cl = CandleList(candle_list, type=trade_type)
def run_trade(self): ''' Run the trade until conclusion from a start date ''' print("[INFO] Run run_trade with id: {0}".format(self.id)) entry = HArea(price=self.entry, pips=1, instrument=self.pair, granularity=self.timeframe) SL = HArea(price=self.SL, pips=1, instrument=self.pair, granularity=self.timeframe) TP = HArea(price=self.TP, pips=1, instrument=self.pair, granularity=self.timeframe) period = None if self.timeframe == "D": period = 24 else: period = int(self.timeframe.replace('H', '')) # generate a range of dates starting at self.start and ending numperiods later in order to assess the outcome # of trade and also the entry time self.start = datetime.datetime.strptime(str(self.start), '%Y-%m-%d %H:%M:%S') numperiods = 300 date_list = [ datetime.datetime.strptime(str(self.start.isoformat()), '%Y-%m-%dT%H:%M:%S') + datetime.timedelta(hours=x * period) for x in range(0, numperiods) ] entered = False for d in date_list: oanda = OandaAPI( url=config.OANDA_API['url'], instrument=self.pair, granularity=self.timeframe, dailyAlignment=config.OANDA_API['dailyAlignment'], alignmentTimezone=config.OANDA_API['alignmentTimezone']) oanda.run(start=d.isoformat(), count=1, roll=True) cl = oanda.fetch_candleset()[0] if entered is False: entry_time = entry.get_cross_time(candle=cl) warnings.warn("\t[INFO] Trade entered") if entry_time != 'n.a.': self.entry_time = entry_time.isoformat() else: warnings.warn( "No entry time was identified for this trade") entry_time = self.start self.entry_time = entry_time if entry_time is not None and entry_time != 'n.a.': entered = True if entered is True: failure_time = SL.get_cross_time(candle=cl) if failure_time is not None and failure_time != 'n.a.': self.outcome = 'failure' self.end = failure_time self.pips = float( calculate_pips(self.pair, abs(self.SL - self.entry))) * -1 warnings.warn("\t[INFO] S/L was hit") break if entered is True: success_time = TP.get_cross_time(candle=cl) if success_time is not None and success_time != 'n.a.': self.outcome = 'success' warnings.warn("\t[INFO] T/P was hit") self.end = success_time self.pips = float( calculate_pips(self.pair, abs(self.TP - self.entry))) break assert getattr(self, 'outcome') warnings.warn("[INFO] Done run_trade")
from oanda_api import OandaAPI api = OandaAPI() while True: command = input("Enter command:") if command == "T": print("Make a trade") trade_id = api.place_trade("EUR_USD", 1000) print('trade_id', trade_id) if command == "Q": break
def get_price_data(p): data = OandaAPI.pricing_api(p) return jsonify(data)
def calc_rsi(self, period=2000, rsi_period=14): ''' Calculate the RSI for a certain candle list Parameters ---------- period : int Number of candles before this CandleList start for which close price data will be fetched. The larger the number of candles the more accurate the ewm calculation will be, as the exponential moving average calculated for each of the windows (of size=rsi_period) will be directly affected by the previous windows in the series. Default=2000 rsi_period : int Number of candles used for calculating the RSI. Default=14 Returns ------- Nothing ''' start_time=self.clist[0].time end_time=self.clist[-1].time delta_period = None if self.granularity == "D": delta_period = datetime.timedelta(hours=24 * period) else: fgran = self.granularity.replace('H', '') delta_period = datetime.timedelta(hours=int(fgran) * period) start_calc_time = start_time - delta_period #fetch candle set from start_calc_time oanda = OandaAPI(url=config.OANDA_API['url'], instrument=self.instrument, granularity=self.granularity, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) ''' Get candlelist from start_calc_time to (start_time-1) This 2-step API call is necessary in order to avoid maximum number of candles errors ''' oanda.run(start=start_calc_time.isoformat(), end=start_time.isoformat(), roll=True) cl1 = oanda.fetch_candleset() '''Get candlelist from start_time to end_time''' oanda.run(start=start_time.isoformat(), end=end_time.isoformat(), roll=True) cl2 = oanda.fetch_candleset() if cl1[-1].time == cl2[0].time: del cl1[-1] candle_list = cl1 + cl2 series=[] series = [c.closeAsk for c in candle_list] df = pd.DataFrame({'close': series}) chg = df['close'].diff(1) gain = chg.mask(chg < 0, 0) loss = chg.mask(chg > 0, 0) avg_gain = gain.ewm(com=rsi_period - 1, min_periods=rsi_period).mean() avg_loss = loss.ewm(com=rsi_period - 1, min_periods=rsi_period).mean() rs = abs(avg_gain / avg_loss) rsi = 100 - (100 / (1 + rs)) rsi4cl=rsi[-len(self.clist):] # set rsi attribute in each candle of the CandleList ix=0 for c,v in zip(self.clist,rsi4cl): self.clist[ix].rsi=v ix+=1
from oanda_api import OandaAPI api = OandaAPI() while True: command = input("Enter command:") if command == "T": print("Make a trade") trade_id = api.place_trade("EUR_USD", 1000, stop_loss=1.174, take_profit=1.194) print('trade_id', trade_id) if command == "Q": break
if abs(ms.start - b.time) < diff: max_pr_ms = pr_ms c_ms = ms diff = abs(ms.start - b.time) pr_ms = ms bounce_lengths[b.time] = { 'pre': max_pr_ms.length(), 'after': c_ms.length() } return bounce_lengths oanda = OandaAPI(url=config.OANDA_API['url'], instrument=args.instrument, granularity=args.granularity, alignmentTimezone=config.OANDA_API['alignmentTimezone'], dailyAlignment=config.OANDA_API['dailyAlignment']) delta_period = periodToDelta(config.SRarea['period'], args.granularity) startObj = datetime.datetime.strptime(args.start, "%Y-%m-%d %H:%M:%S") start = startObj - delta_period # get the start datetime for this CandleList period end = startObj oanda.run(start=start.isoformat(), end=end.isoformat(), roll=True) candle_list = oanda.fetch_candleset() cl = CandleList(clist=candle_list, instrument=args.instrument,
self.api = api self.pairs_list = pairs_list ok, instruments_raw = api.fetch_instruments(pairs_list) self.marginRates = { x['name']: float(x['marginRate']) for x in instruments_raw['instruments'] } ok, self.prices = api.fetch_prices(pairs_list) def get_trade_margin_for_units(self, units, pair): marginRate = self.marginRates[pair] price = self.prices[pair] trade_margin = price.mid * marginRate * price.mid_conv * units return trade_margin def get_units_for_margin(self, margin, pair): marginRate = self.marginRates[pair] price = self.prices[pair] units = margin / (price.mid * marginRate * price.mid_conv) return int(units) if __name__ == "__main__": api = OandaAPI() pairs = ['EUR_USD', 'GBP_JPY', 'AUD_NZD', 'SGD_CHF'] r = TradeUnitCalculator(api, pairs) for p in pairs: print(p, round(r.get_trade_margin_for_units(10000, p), 2), r.get_units_for_margin(2000, p))