def analyze(self): ''' Analyze each of the Trade objects in TradeList depending on value of settings.get('counter', 'strats') and add the calculated attributes to Trade :returns TradeList ''' #these are the strategies that will be analysed using the Counter pattern strats = self.settings.get('counter', 'strats').split(",") trade_list = [] for t in self.tlist: tl_logger.info("Processing trade: {0}-{1}".format(t.pair, t.start)) if t.strat in strats: if t.entered is False and not getattr(t, 'outcome'): t.run_trade() c = Counter(trade=t, settingf=self.settingf, settings=self.settings, init_feats=True) attrb_ls = self.settings.get('counter', 'attrbs').split(",") for a in attrb_ls: # add 'a' attribute to Trade object setattr(t, a, getattr(c, a)) trade_list.append(t) tl_logger.info("Done") tl = TradeList(settingf=self.settingf, settings=self.settings, tlist=trade_list) return tl
def test_set_pivots_lasttime(pair, id, start, type, SR, SL, TP, entry, dates, clean_tmp): """ Check that self.pivots_lasttime class attribute has been initialized """ t = Trade(id=id, start=start, pair=pair, timeframe='D', type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, period=1000, settingf='../../data/settings.ini') c.set_lasttime() c.set_pivots() c.set_pivots_lasttime() times = [] for p in c.pivots_lasttime.plist: times.append(p.candle.time) assert dates == times
def test_set_pivots_4h(pair, timeframe, id, start, type, SR, SL, TP, entry, pllen, settings_obj, clean_tmp): """ Check that self.pivots class attribute is correctly set using a H4 timeframe """ settings_obj.set('pivots', 'th_bounces', '0.01') t = Trade(id=id, start=start, pair=pair, timeframe=timeframe, type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settings=settings_obj) c = Counter(trade=t, settings=settings_obj) c.set_pivots() assert len(c.pivots.plist) == pllen
def analyze(self): ''' Analyze each of the Trade objects in TradeList depending on value of settings.get('counter', 'strats') and add the calculated attributes to Trade :returns TradeList ''' #these are the strategies that will be analysed using the Counter pattern tl_logger.info("Strategies that will be analysed: {0}".format( self.settings.get('counter', 'strats'))) strats = self.settings.get('counter', 'strats').split(",") trade_list = [] for t in self.tlist: tl_logger.info("Processing trade: {0}-{1}".format(t.pair, t.start)) if t.strat in strats: if t.entered is False and (not hasattr(t, 'outcome') or math.isnan(t.outcome) is True): t.run_trade() c = Counter(trade=t, settingf=self.settingf, settings=self.settings, ser_data_obj=self.ser_data_obj, init_feats=True) tl_logger.debug("Counter attributes analysed:{0}".format( self.settings.get('counter', 'attrbs').split(","))) attrb_ls = self.settings.get('counter', 'attrbs').split(",") for a in attrb_ls: if hasattr(c, a) is True: # add 'a' attribute to Trade object setattr(t, a, getattr(c, a)) else: tl_logger.warn( "Attribute {0} is not defined in Counter object. Skipping..." .format(a)) setattr(t, a, "n.a.") else: tl_logger.debug( "Trade.strat ({0}) is not within list of trades to analyse. Skipping..." .format(t.strat)) trade_list.append(t) tl_logger.info("Done") tl = TradeList(settingf=self.settingf, settings=self.settings, tlist=trade_list) return tl
def ct_object(): '''Returns Counter object''' t = Trade(id='EUR_GBP_13AUG2019D', start='2019-08-12 22:00:00', pair='EUR_GBP', timeframe='D', type='short', SR=0.92909, SL=0.93298, TP=0.90366, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, settingf='../../data/settings.ini') return c
def test_max_min_rsi(pair, timeframe, id, start, type, SR, SL, TP, entry, avalue): t = Trade(id=id, start=start, pair=pair, timeframe=timeframe, type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, settingf='../../data/settings.ini') assert avalue == c.max_min_rsi()
def test_is_entry_onrsi(pair, id, timeframe, start, type, SR, SL, TP, entry, entry_onrsi, clean_tmp): t = Trade(id=id, start=start, pair=pair, timeframe=timeframe, type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, settingf='../../data/settings.ini', init_feats=True) assert entry_onrsi == c.is_entry_onrsi()
def test_set_pips_c_trend(pair, id, timeframe, start, type, SR, SL, TP, entry, pips_c_trend, clean_tmp): t = Trade(id=id, start=start, pair=pair, timeframe=timeframe, type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, settingf='../../data/settings.ini', init_feats=True) assert pips_c_trend == c.pips_c_trend
def test_set_trend_i(pair, id, timeframe, start, type, SR, SL, TP, entry, trend_i, clean_tmp): t = Trade(id=id, start=start, pair=pair, timeframe=timeframe, type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, settingf='../../data/settings.ini') c.set_trend_i() assert trend_i == c.trend_i
def test_ctobject_notype(start, SR, SL, TP, entry, clean_tmp): """ Check that Counter object without a type defined is correctly instantiated """ t = Trade(id='test', start=start, pair='EUR_AUD', timeframe='D', SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, period=1000, settingf='../../data/settings.ini') assert 0
def test_set_lasttime(start, type, SR, SL, TP, entry, lasttime, clean_tmp): """ Check that self.lasttime class attribute has been initialized """ t = Trade(id='test', start=start, pair='EUR_AUD', timeframe='D', type=type, SR=SR, SL=SL, TP=TP, entry=entry, strat='counter_b1', settingf="../../data/settings.ini") c = Counter(trade=t, period=1000, settingf='../../data/settings.ini') c.set_lasttime() assert c.lasttime == lasttime
def calc_SR(self, adateObj): ''' Function to calculate S/R lines Parameters ---------- datetime object used for identifying S/R areas Return ------ HAreaList object ''' # calculate price range for calculating S/R ul, ll = self.get_max_min(adateObj) tb_logger.info("Running calc_SR for estimated range: {0}-{1}".format( ll, ul)) prices = [] bounces = [] # contains the number of pivots per price level score_per_bounce = [] tot_score = [] # the increment of price in number of pips is double the hr_extension prev_p = None p = float(ll) while p <= float(ul): tb_logger.debug("Processing S/R at {0}".format(round(p, 4))) # each of 'p' will become a S/R that will be tested for bounces # set entry to price+self.settings.getint('trade_bot','i_pips') entry = add_pips2price(self.pair, p, self.settings.getint('trade_bot', 'i_pips')) # set S/L to price-self.settings.getint('trade_bot','i_pips') SL = substract_pips2price( self.pair, p, self.settings.getint('trade_bot', 'i_pips')) t = Trade(id='{0}.{1}.detect_sr.{2}'.format( self.pair, adateObj.isoformat(), round(p, 5)), start=adateObj.strftime('%Y-%m-%d %H:%M:%S'), pair=self.pair, timeframe=self.timeframe, type='short', entry=entry, SR=p, SL=SL, RR=1.5, strat='counter_b1', settingf=self.settingf, settings=self.settings) # reduce period that Counter uses so the S/R # are calculated with the most recent pivots newperiod = self.settings.get('trade_bot', 'period_range') self.settings.set('counter', 'period', newperiod) c = Counter(trade=t, init_feats=True, settings=self.settings) if len(c.pivots.plist) == 0: mean_pivot = 0 else: mean_pivot = round(c.score_pivot, 2) prices.append(round(p, 5)) bounces.append(len(c.pivots.plist)) tot_score.append(c.total_score) score_per_bounce.append(mean_pivot) # increment price to following price. # Because the increment is made in pips # it does not suffer of the JPY pairs # issue p = add_pips2price(self.pair, p, 2 * self.settings.getint('trade_bot', 'i_pips')) if prev_p is None: prev_p = p else: increment_price = round(p - prev_p, 5) prev_p = p data = { 'price': prices, 'bounces': bounces, 'scores': score_per_bounce, 'tot_score': tot_score } df = pd.DataFrame(data=data) ### establishing bounces threshold as the args.th quantile # selecting only rows with at least one pivot and tot_score>0, # so threshold selection considers only these rows # and selection is not biased when range of prices is wide dfgt1 = df.loc[(df['bounces'] > 0)] dfgt2 = df.loc[(df['tot_score'] > 0)] bounce_th = dfgt1.bounces.quantile( self.settings.getfloat('trade_bot', 'th')) score_th = dfgt2.tot_score.quantile( self.settings.getfloat('trade_bot', 'th')) print("Selected number of pivot threshold: {0}".format(bounce_th)) print("Selected tot score threshold: {0}".format(score_th)) # selecting records over threshold dfsel = df.loc[(df['bounces'] > bounce_th) | (df['tot_score'] > score_th)] # repeat until no overlap between prices ret = self.__calc_diff(dfsel, increment_price) dfsel = ret[0] tog_seen = ret[1] while tog_seen is True: ret = self.__calc_diff(dfsel, increment_price) dfsel = ret[0] tog_seen = ret[1] # iterate over DF with selected SR to create a HAreaList halist = [] for index, row in dfsel.iterrows(): resist = HArea(price=row['price'], pips=self.settings.getint('pivots', 'hr_pips'), instrument=self.pair, granularity=self.timeframe, no_pivots=row['bounces'], tot_score=row['tot_score'], settingf=self.settingf, settings=self.settings) halist.append(resist) halist = HAreaList(halist=halist, settingf="data/settings.ini", settings=self.settings) tb_logger.info("Run done") return halist
entry = add_pips2price(args.instrument, p, 30) # set S/L to price-30pips SL = substract_pips2price(args.instrument, p, 30) t = Trade(id='{0}.detect_sr.{1}'.format(args.instrument, round(p, 5)), start=args.start, pair=args.instrument, timeframe='D', type='short', entry=entry, SR=p, SL=SL, RR=1.5, strat='counter_b1', settingf=args.settingf) c = Counter(trade=t, init_feats=True, settingf=args.settingf) ratio = None if len(c.pivots.plist) == 0: ratio = 0 mean_pivot = 0 else: mean_pivot = round(c.score_pivot, 2) file.write("{0}\t{1}\t{2}\t{3}\n".format(round(p, 5), len(c.pivots.plist), c.total_score, mean_pivot)) prices.append(round(p, 5)) bounces.append(len(c.pivots.plist)) tot_scores.append(c.total_score) score_per_bounce.append(mean_pivot) p = add_pips2price(args.instrument, p, 60)