def estimate_bounces(price, plist): ''' Function to estimate the bounces at 'price' Parameters ---------- price: float Price used to identify bounces plist: PivotList object Returns ------- list List with bounces ''' hr = HArea(price=price, pips=hr_extension, instrument=args.instrument, granularity=args.granularity) print("upper: {0} - lower: {1}".format(hr.upper, hr.lower)) inarea_bounces = hr.inarea_bounces(plist=plist) if len(inarea_bounces) > 1: inarea_cl = CandleList(inarea_bounces, instrument=args.instrument, granularity=args.granularity) inarea_bounces = inarea_cl.improve_resolution(part='openAsk', price=price, min_dist=5) return inarea_bounces
def test_slice_with_start_end(trend_oanda_object): candle_list = trend_oanda_object.fetch_candleset() cl = CandleList(candle_list, instrument='AUD_USD', granularity='D') startdatetime = datetime.datetime(2017, 12, 20, 22, 0) endatetime = datetime.datetime(2018, 1, 20, 22, 0) cl.slice(start=startdatetime, end=endatetime)
def get_first_bounce(self, part='closeAsk'): ''' Function that uses the the Zigzag algorithm to identify the first bounce (most recent) of the CounterDoubleTop pattern Parameters ---------- part: str Candle part used for the calculation. Default='closeAsk' Returns ------- It will set the self.bounce_1st attribute ''' # get sliced CandleList from datetime defined by self.period1st_bounce period start_clist = self.clist_period.slice( start=self.__period1st_bounce_point) pivotlist = start_clist.get_pivotlist( th_up=config.CTDBT['threshold_1st_2nd_bounces'], th_down=-config.CTDBT['threshold_1st_2nd_bounces']) bounces = pivotlist.plist arr = np.array(start_clist.clist) # consider type of trade in order to select peaks or valleys if self.type == 'short': bounce_candles = arr[bounces == 1] elif self.type == 'long': bounce_candles = arr[bounces == -1] in_area_list = self.__inarea_bounces(bounce_candles, part=part, HRpips=self.HR_pips) HRpips = self.HR_pips while len(in_area_list) == 0 and HRpips <= config.CTDBT['max_HRpips']: HRpips = HRpips + config.CTDBT['step_pips'] in_area_list = self.__inarea_bounces(bounce_candles, part=part, HRpips=HRpips) # keep running the improve_resolution function until a single bounce is obtained while len(in_area_list) > 1: inarea_cl = CandleList(in_area_list, instrument=self.pair, granularity=self.timeframe) in_area_list = inarea_cl.improve_resolution(part=part, price=self.SR) assert len(in_area_list) == 1, "Exactly one single bounce is needed" self.bounce_1st = in_area_list[0]
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_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 __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 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 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
def get_second_bounce(self, part='closeAsk'): ''' Function that uses the the Zigzag algorithm to identify the second bounce of the CounterDoubleTop pattern Parameters ---------- part: str Candle part used for the calculation. Default='closeAsk' Returns ------- It will set the self.bounce_2nd attribute ''' # timepoint cutoff that the defines the period from which the second bounce needs to be # located start = self.__get_time4candles(n=self.period2nd_bounce, anchor_point=self.bounce_1st.time) # get sliced CandleList from datetime defined by self.period1st_bounce period start_clist = self.clist_period.slice(start=start, end=self.bounce_1st.time) pivotlist = start_clist.get_pivotlist( th_up=config.CTDBT['threshold_1st_2nd_bounces'], th_down=-config.CTDBT['threshold_1st_2nd_bounces']) bounces = pivotlist.plist arr = np.array(start_clist.clist) # consider type of trade in order to select peaks or valleys if self.type == 'short': bounce_candles = arr[bounces == 1] elif self.type == 'long': bounce_candles = arr[bounces == -1] #if distance between 1st bounce and last detected bounce is less than self.min_dist candles #then remove last detected bounce progressively diff = abs(self.bounce_1st.time - bounce_candles[-1].time) min_distDelta = periodToDelta(ncandles=self.min_dist, timeframe=self.timeframe) while diff <= min_distDelta: bounce_candles = bounce_candles[:-1] diff = abs(self.bounce_1st.time - bounce_candles[-1].time) in_area_list = self.__inarea_bounces( bounce_candles, part=part, HRpips=config.CTDBT['HR_pips_2nd']) HRpips = config.CTDBT['HR_pips_2nd'] while len(in_area_list) == 0 and HRpips <= config.CTDBT['max_HRpips']: HRpips = HRpips + config.CTDBT['step_pips'] in_area_list = self.__inarea_bounces(bounce_candles, part=part, HRpips=HRpips) # keep running the improve_resolution function until a single bounce is obtained while len(in_area_list) > 1: inarea_cl = CandleList(in_area_list, instrument=self.pair, granularity=self.timeframe) in_area_list = inarea_cl.improve_resolution(part=part, price=self.SR) assert len(in_area_list) == 1, "Exactly one single bounce is needed" self.bounce_2nd = in_area_list[0]
def calc_surr_lengths(b_list): ''' Function to calculate the number of candles of segments around each bounce Parameters ---------- blist: List of candles representing each bounce Returns ------- Dict of dicts: Each key will be the datetime of the bounce and each value will be the number of candles of the SegmentList before and after the bounce ''' if len(b_list) == 0: warnings.warn("No bounces in area. Skipping...") return 0 bounce_lengths = {} delta_period = periodToDelta(100, args.granularity) for b in b_list: bounce_lengths[b.time] = {} # get 50 candles after and before the bounce start = b.time - delta_period end = b.time + delta_period # run api query with new period oanda.run(start=start.isoformat(), end=end.isoformat(), roll=True) candle_list = oanda.fetch_candleset() sub_cl = CandleList(clist=candle_list, instrument=args.instrument, granularity=args.instrument) sub_pl = sub_cl.get_pivotlist(outfile='test_subcl.png', th_up=0.02, th_down=-0.02) slist = sub_pl.slist mslist = slist.merge_segments(min_n_candles=10, diff_in_pips=200, outfile="test_subcl1.png") diff = None pr_ms = None max_pr_ms = None c_ms = None for ms in mslist: if diff is None: pr_ms = ms diff = abs(ms.start - b.time) else: 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
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, granularity=args.instrument) plist = cl.get_pivotlist( th_down=config.SRarea['th_down'], th_up=-config.SRarea['th_up'], outfile="/Users/ernesto/PycharmProjects/FOREX/scripts/test.png") bounce_dict = {} hr_extension = 30 increment_price = 0.006 # the increment of price in number of pips is double the hr_extension for p in np.arange(0.67985, 0.72219, increment_price): print("Price: {0}".format(p)) inarea_bs = estimate_bounces(price=p, plist=plist) print("Length: {0}".format(len(inarea_bs)))
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) cl.calc_binary_seq(merge=True) cl.calc_number_of_0s(norm=True) cl.calc_number_of_doubles0s(norm=True) cl.calc_longest_stretch() for k in cl.seq: print("\t{0}: {1}".format(k, cl.seq[k])) print("Number of 0s (merged): %.2f" % cl.number_of_0s['merge']) print("Double0s (highlow): {0}".format(cl.highlow_double0s)) print("Double0s (openclose): {0}".format(cl.openclose_double0s)) print("Stretch:") for k in cl.longest_stretch: print("\t{0}: {1}".format(k, cl.longest_stretch[k]))