示例#1
0
def test_last_time(cl_object):
    '''
    Test 'last_time' function from HArea
    '''

    resist = HArea(price=0.70151,
                   pips=5,
                   instrument='AUD_USD',
                   granularity='D',
                   settingf='../../data/settings.ini')

    lt = resist.last_time(clist=cl_object.clist, position='above')

    assert lt == datetime.datetime(2019, 7, 21, 21, 0)
示例#2
0
def test_get_cross_time(cl_object, clist_ix, price, dt):
    '''
    Test 'get_cross_time' function from HArea
    for a single candle that crosses the 'resist' object
    '''

    resist = HArea(price=price,
                   pips=5,
                   instrument='AUD_USD',
                   granularity='D',
                   settingf='../../data/settings.ini')

    cross_time = resist.get_cross_time(candle=cl_object.clist[clist_ix])

    assert cross_time == dt
示例#3
0
def hlist_factory():
    '''Returns a list of HArea objects'''

    hlist = []
    for p in np.arange(0.67116, 0.82877, 0.042):
        area = HArea(price=p,
                     pips=30,
                     instrument=instrument,
                     granularity=granularity,
                     settingf='../../data/settings.ini')
        hlist.append(area)

    return hlist
    def set_lasttime(self):
        '''
        Function to set the lasttime class attribute

        returns
        -------
        Nothing
        '''
        c_logger.debug("Running set_lasttime")

        # instantiate an HArea object representing the self.SR in order to calculate the lasttime
        # price has been above/below SR
        resist = HArea(price=self.trade.SR,
                       pips=self.settings.getint('harea', 'hr_pips'),
                       instrument=self.trade.pair,
                       granularity=self.trade.timeframe,
                       settings=self.settings)

        self.lasttime = self.clist_period.get_lasttime(resist)

        c_logger.debug("Done set_lasttime")
示例#5
0
def test_get_lasttime():
    oanda = OandaAPI(instrument='AUD_CHF',
                     granularity='H12',
                     settingf='../../data/settings.ini')

    resist = HArea(price=1.00721,
                   pips=45,
                   instrument='AUD_CHF',
                   granularity='H12',
                   settingf='../../data/settings.ini')

    oanda.run(start='2004-11-07T10:00:00', end='2010-04-30T09:00:00')

    candle_list = oanda.fetch_candleset()
    cl = CandleList(candle_list,
                    instrument='AUD_CHF',
                    id='test_AUD_CHF_clist',
                    granularity='H12',
                    type='short',
                    settingf='../../data/settings.ini')

    lasttime = cl.get_lasttime(resist)
    assert lasttime == datetime.datetime(2007, 11, 9, 10, 0)
    def run_trade(self, expires=None):
        '''
        Run the trade until conclusion from a start date
        '''

        t_logger.info("Run run_trade with id: {0}".format(self.id))

        entry = HArea(price=self.entry,
                      instrument=self.pair,
                      pips=self.settings.getint('trade', 'hr_pips'),
                      granularity=self.timeframe,
                      ser_data_obj=None,
                      settings=self.settings)
        SL = HArea(price=self.SL,
                   instrument=self.pair,
                   pips=self.settings.getint('trade', 'hr_pips'),
                   granularity=self.timeframe,
                   ser_data_obj=None,
                   settings=self.settings)
        TP = HArea(price=self.TP,
                   instrument=self.pair,
                   pips=self.settings.getint('trade', 'hr_pips'),
                   granularity=self.timeframe,
                   ser_data_obj=None,
                   settings=self.settings)

        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.strptime(str(self.start), '%Y-%m-%d %H:%M:%S')
        numperiods = self.settings.getint('trade', 'numperiods')
        # date_list will contain a list with datetimes that will be used for running self
        date_list = [
            datetime.strptime(str(self.start.isoformat()), '%Y-%m-%dT%H:%M:%S')
            + timedelta(hours=x * period) for x in range(0, numperiods)
        ]

        count = 0
        self.entered = False

        for d in date_list:
            count += 1
            if expires is not None:
                if count > expires and self.entered is False:
                    self.outcome = 'n.a.'
                    break
            oanda = OandaAPI(instrument=self.pair,
                             granularity=self.timeframe,
                             settingf=self.settingf,
                             settings=self.settings)

            if self.ser_data_obj is None:
                t_logger.debug("Fetching data from API")
                oanda.run(start=d.isoformat(), count=1)
            else:
                t_logger.debug("Fetching data from File")
                oanda.data = self.ser_data_obj.slice(start=d, count=1)

            cl = oanda.fetch_candleset()[0]
            if self.entered is False:
                entry_time = entry.get_cross_time(
                    candle=cl,
                    granularity=self.settings.get('trade', 'granularity'))
                if entry_time != 'n.a.':
                    t_logger.info("Trade entered")
                    # modify self.start to the datetime
                    # that Trade has actually entered
                    self.start = d
                    self.entry_time = entry_time.isoformat()
                    self.entered = True
            if self.entered is True:
                # will be n.a. is cl does not cross SL
                failure_time = SL.get_cross_time(candle=cl,
                                                 granularity=self.settings.get(
                                                     'trade', 'granularity'))
                # sometimes there is a jump in the price and SL is not crossed
                is_gap = False
                if (self.type == "short" and cl.lowAsk > SL.price) or (
                        self.type == "long" and cl.highAsk < SL.price):
                    is_gap = True
                    failure_time = d
                if (failure_time is not None
                        and failure_time != 'n.a.') or is_gap is True:
                    self.outcome = 'failure'
                    self.end = failure_time
                    self.pips = float(
                        calculate_pips(self.pair,
                                       abs(self.SL - self.entry))) * -1
                    t_logger.info("S/L was hit")
                    break
                # will be n.a. if cl does not cross TP
                success_time = TP.get_cross_time(candle=cl,
                                                 granularity=self.settings.get(
                                                     'trade', 'granularity'))
                # sometimes there is a jump in the price and TP is not crossed
                is_gap = False
                if (self.type == "short" and cl.highAsk < TP.price) or (
                        self.type == "long" and cl.lowAsk > TP.price):
                    is_gap = True
                    success_time = d

                if (success_time is not None
                        and success_time != 'n.a.') or is_gap is True:
                    self.outcome = 'success'
                    t_logger.info("T/P was hit")
                    self.end = success_time
                    self.pips = float(
                        calculate_pips(self.pair, abs(self.TP - self.entry)))
                    break
        try:
            assert getattr(self, 'outcome')
        except:
            t_logger.warning("No outcome could be calculated")
            self.outcome = "n.a."
            self.pips = 0

        t_logger.info("Done run_trade")
示例#7
0
    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