def test_get_trade_type(start, end, type): conn = Connect(instrument='EUR_GBP', granularity='D') res = conn.query(start=start.isoformat(), end=end.isoformat()) cl = CandleList(res) assert type == get_trade_type(end, cl)
def test_validate_datetime(): log = logging.getLogger('test_validate_datetime') log.debug("Test for function with wrong datetime format") conn = Connect(instrument='AUD_USD', granularity='D') with pytest.raises(ValueError): conn.validate_datetime('2018-05-23T21', 'D')
def test_query_M30(): log = logging.getLogger('test_query_M30') log.debug("Test for 'query' function with granularity M30") conn = Connect(instrument='AUD_USD', granularity='M30') clO = conn.query(start='2018-05-21T21:00:00', end='2018-05-23T21:00:00') assert len(clO) == 97
def test_m_queries(i, g, s, e, l): log = logging.getLogger('test_query_ser') log.debug( "Test for 'query' function with a mix of instruments and different datetimes" ) conn = Connect(instrument=i, granularity=g) clO = conn.query(start=s, end=e) assert len(clO) == l
def test_indecision_c(pair, timeframe, time, is_it): '''Test function to check if a certain Candle has the typical indecission pattern''' conn = Connect(instrument=pair, granularity=timeframe) res = conn.query(start=time, count=1) cObj = res.candles[0] result = cObj.indecision_c() assert is_it == result
def test_calc_SR1(pair, start, end, n_areas, clean_tmp): """ Check 'calc_SR' function with different CandleLists """ conn = Connect(instrument=pair, granularity='D') res = conn.query(start=start, end=end) clO = CandleList(res) harealst = calc_SR(clO, outfile=DATA_DIR + "/imgs/srareas/calc_sr.png") assert len(harealst.halist) == n_areas
def conn_o(): log = logging.getLogger('connect_o') log.debug('Create a Connect object') # creating a Connect object conn = Connect(instrument="AUD_USD", granularity='D') return conn
def get_cross_time(self, candle, granularity='M30') -> datetime: ''' This function is used get the time that the candle crosses (go through) HArea Arguments: candle : Candle crossing the HArea granularity : To what granularity we should descend Returns: crossing time. n.a. if crossing time could not retrieved. This can happens when there is an artifactual jump in Oanda's data ''' if candle.l <= self.price <= candle.h: 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 conn = Connect(instrument=self.instrument, granularity=granularity) h_logger.debug("Fetching data from API") res = conn.query(start=cstart.isoformat(), end=cend.isoformat()) seen = False for c in res: if c.l <= self.price <= c.h: seen = True return c.time if seen is False: return 'n.a.' else: return 'n.a.'
def run(self, discard_sat=True): ''' This function will run the Bot from start to end one candle at a time Parameter --------- discard_sat : Bool If this is set to True, then the Trade wil not be taken if IC falls on a Saturday. Default: True Returns ------- TradeList object with Trades taken. None if no trades were taken ''' tb_logger.info("Running...") conn = Connect(instrument=self.pair, granularity=self.timeframe) ser_dir = None if CONFIG.has_option('general', 'ser_data_dir'): ser_dir = CONFIG.get('general', 'ser_data_dir') delta = nhours = None if self.timeframe == "D": nhours = 24 delta = timedelta(hours=24) else: p1 = re.compile('^H') m1 = p1.match(self.timeframe) if m1: nhours = int(self.timeframe.replace('H', '')) delta = timedelta(hours=int(nhours)) # convert to datetime the start and end for this TradeBot startO = pd.datetime.strptime(self.start, '%Y-%m-%d %H:%M:%S') endO = pd.datetime.strptime(self.end, '%Y-%m-%d %H:%M:%S') loop = 0 tlist = [] tend = SRlst = None # calculate the start datetime for the CList that will be used # for calculating the S/R areas delta_period = periodToDelta( CONFIG.getint('trade_bot', 'period_range'), self.timeframe) initc_date = startO - delta_period # Get now a CandleList from 'initc_date' to 'startO' which is the # total time interval for this TradeBot res = conn.query(start=initc_date.isoformat(), end=endO.isoformat(), indir=ser_dir) clO = CandleList(res) while startO <= endO: if tend is not None: # this means that there is currently an active trade if startO <= tend: startO = startO + delta loop += 1 continue else: tend = None tb_logger.info("Trade bot - analyzing candle: {0}".format( startO.isoformat())) sub_clO = clO.slice(initc_date, startO) dt_str = startO.strftime("%d_%m_%Y_%H_%M") if loop == 0: outfile_txt = "{0}/srareas/{1}.{2}.{3}.halist.txt".format( CONFIG.get("images", "outdir"), self.pair, self.timeframe, dt_str) outfile_png = "{0}/srareas/{1}.{2}.{3}.halist.png".format( CONFIG.get("images", "outdir"), self.pair, self.timeframe, dt_str) SRlst = calc_SR(sub_clO, outfile=outfile_png) f = open(outfile_txt, 'w') res = SRlst.print() # print SR report to file f.write(res) f.close() tb_logger.info("Identified HAreaList for time {0}:".format( startO.isoformat())) tb_logger.info("{0}".format(res)) elif loop >= CONFIG.getint('trade_bot', 'period'): # An entire cycle has occurred. Invoke .calc_SR outfile_txt = "{0}/srareas/{1}.{2}.{3}.halist.txt".format( CONFIG.get("images", "outdir"), self.pair, self.timeframe, dt_str) outfile_png = "{0}/srareas/{1}.{2}.{3}.halist.png".format( CONFIG.get("images", "outdir"), self.pair, self.timeframe, dt_str) SRlst = calc_SR(sub_clO, outfile=outfile_png) f = open(outfile_txt, 'w') res = SRlst.print() tb_logger.info("Identified HAreaList for time {0}:".format( startO.isoformat())) tb_logger.info("{0}".format(res)) # print SR report to file f.write(res) f.close() loop = 0 # fetch candle for current datetime res = conn.query(start=startO.isoformat(), count=1, indir=ser_dir) # this is the current candle that # is being checked c_candle = Candle(dict_data=res['candles'][0]) c_candle.time = datetime.strptime(c_candle.time, '%Y-%m-%dT%H:%M:%S.%fZ') # c_candle.time is not equal to startO # when startO is non-working day, for example delta1hr = timedelta(hours=1) if (c_candle.time != startO) and (abs(c_candle.time - startO) > delta1hr): loop += 1 tb_logger.info( "Analysed dt {0} is not the same than APIs returned dt {1}." " Skipping...".format(startO, c_candle.time)) startO = startO + delta continue #check if there is any HArea overlapping with c_candle HAreaSel, sel_ix = SRlst.onArea(candle=c_candle) if HAreaSel is not None: c_candle.set_candle_features() # guess the if trade is 'long' or 'short' newCl = clO.slice(start=initc_date, end=c_candle.time) type = get_trade_type(c_candle.time, newCl) SL = adjust_SL(type, newCl, CONFIG.getint('trade_bot', 'n_SL')) prepare = False if c_candle.indecision_c( ic_perc=CONFIG.getint('general', 'ic_perc')) is True: prepare = True elif type == 'short' and c_candle.colour == 'red': prepare = True elif type == 'long' and c_candle.colour == 'green': prepare = True # discard if IC falls on a Saturday if c_candle.time.weekday() == 5 and discard_sat is True: tb_logger.info( "Possible trade at {0} falls on Sat. Skipping...". format(c_candle.time)) prepare = False if prepare is True: t = prepare_trade(tb_obj=self, type=type, SL=SL, ic=c_candle, harea_sel=HAreaSel, delta=delta, add_pips=CONFIG.getint( 'trade', 'add_pips')) t.tot_SR = len(SRlst.halist) t.rank_selSR = sel_ix t.SRlst = SRlst tlist.append(t) startO = startO + delta loop += 1 tb_logger.info("Run done") if len(tlist) == 0: return None else: return tlist
def run(self): """ Run the bot from self.start Returns ------- Trade object or none """ tb_logger.info("Running...") conn = Connect(instrument=self.pair, granularity=self.timeframe) ser_dir = None if CONFIG.has_option('general', 'ser_data_dir'): ser_dir = CONFIG.get('general', 'ser_data_dir') delta = nhours = None if self.timeframe == "D": nhours = 24 delta = timedelta(hours=24) else: p1 = re.compile('^H') m1 = p1.match(self.timeframe) if m1: nhours = int(self.timeframe.replace('H', '')) delta = timedelta(hours=int(nhours)) # calculate the start datetime for the CList that will be used # for calculating the S/R areas delta_period = periodToDelta( CONFIG.getint('trade_bot', 'period_range'), self.timeframe) initc_date = self.start - delta_period # Get now a CandleList from 'initc_date' to 'startO' which is the # total time interval for this TradeBot res = conn.query(start=initc_date.strftime("%Y-%m-%dT%H:%M:%S"), end=self.start.strftime("%Y-%m-%dT%H:%M:%S"), indir=ser_dir) clO = CandleList(res) dt_str = self.start.strftime("%d_%m_%Y_%H_%M") outfile_png = "{0}/srareas/{1}.{2}.{3}.halist.png".format( CONFIG.get("images", "outdir"), self.pair, self.timeframe, dt_str) SRlst = calc_SR(clO, outfile=outfile_png) # fetch candle for current datetime res = conn.query(start=self.start.strftime("%Y-%m-%dT%H:%M:%S"), count=1, indir=ser_dir) # this is the current candle that # is being checked c_candle = Candle(dict_data=res['candles'][0]) c_candle.time = datetime.strptime(c_candle.time, '%Y-%m-%dT%H:%M:%S.%fZ') # check if there is any HArea overlapping with c_candle HAreaSel, sel_ix = SRlst.onArea(candle=c_candle) if HAreaSel is not None: c_candle.set_candle_features() # guess the if trade is 'long' or 'short' newCl = clO.slice(start=initc_date, end=c_candle.time) type = get_trade_type(c_candle.time, newCl) SL = adjust_SL(type, newCl, CONFIG.getint('trade_bot', 'n_SL')) prepare = False if c_candle.indecision_c( ic_perc=CONFIG.getint('general', 'ic_perc')) is True: prepare = True elif type == 'short' and c_candle.colour == 'red': prepare = True elif type == 'long' and c_candle.colour == 'green': prepare = True # discard if IC falls on a Saturday if c_candle.time.weekday() == 5 and discard_sat is True: tb_logger.info( "Possible trade at {0} falls on Sat. Skipping...".format( c_candle.time)) prepare = False t = None if prepare is True: t = prepare_trade(tb_obj=self, type=type, SL=SL, ic=c_candle, harea_sel=HAreaSel, delta=delta, add_pips=CONFIG.getint('trade', 'add_pips')) t.tot_SR = len(SRlst.halist) t.rank_selSR = sel_ix t.SRlst = SRlst return t tb_logger.info("Run done")