def backtest(self, prices, ref_prices, params):

        m = params["m"]
        x = params["x"]
        interval = params[Ct.interval_key()]

        mon_ret_df = Financials.pct_change(prices)
        p_return = IntradayResistanceBreakout.calculate(mon_ret_df, m, x)

        cagr_params = {Ct.interval_key(): interval}
        cagr = CAGR.get_cagr(p_return, cagr_params)
        sharpe_params = {"rf": 0.025, Ct.interval_key(): interval}
        sharpe = Sharpe.get_sharpe(p_return, sharpe_params)
        max_dd = MaxDrawdown.get_max_drawdown(p_return)

        # calculating overall strategy's KPIs

        mon_ret_df = Financials.pct_change(ref_prices)

        cagr_ref = CAGR.get_cagr(mon_ret_df, cagr_params)
        sharpe_params = {"rf": 0.025, Ct.interval_key(): interval}
        sharpe_ref = Sharpe.get_sharpe(mon_ret_df, sharpe_params)
        max_dd_ref = MaxDrawdown.get_max_drawdown(mon_ret_df)

        print("CAGR - Portfolio: {}".format(cagr[Ct.cagr_key()]["mon_ret"]))
        print("Sharpe - Portfolio: {}".format(
            sharpe[Ct.sharpe_key()]["mon_ret"]))
        print("MAX-Drawdown - Portfolio: {}".format(
            max_dd[Ct.max_drawdown_key()]["mon_ret"]))
        print("CAGR - Ref: {}".format(cagr_ref[Ct.cagr_key()]["^DJI"]))
        print("Sharpe - Ref: {}".format(sharpe_ref[Ct.sharpe_key()]["^DJI"]))
        print("MAX-Drawdown - Ref: {}".format(
            max_dd_ref[Ct.max_drawdown_key()]["^DJI"]))

        IntradayResistanceBreakout.plot(p_return, mon_ret_df)
Exemplo n.º 2
0
    def get_sortino(input_df, params=None):

        if params is None:
            params = {}

        if "rf" not in params.keys():
            # USA: risk free rate
            params = {"rf": 0.0144}

        rf = params["rf"]

        "function to calculate Sortino ratio ; rf is the risk free rate"

        cagr = CAGR.get_cagr(input_df, params)

        vol_params = params
        vol_params[Ct.neg_volatility_key()] = True
        neg_vol = Volatility.get_volatility(input_df, vol_params)

        result_df = pd.DataFrame()
        result_df[Sortino.kpi_name] = (cagr.loc[:, Ct.cagr_key()] -
                                       rf) / neg_vol.loc[:,
                                                         Ct.volatility_key()]

        result_df.rename(index={0: Sortino.kpi_name}, inplace=True)

        return result_df
Exemplo n.º 3
0
    def get_volatility(input_df, params=None):
        """function to calculate annualized volatility of a trading strategy"""

        if params is None:
            raise ValueError("Please set the corresponding Interval parameter"
                             "{interval:Ct.INTERVAL.MONTH|Ct.INTERVAL.DAY}")

        if Ct.neg_volatility_key() not in params.keys():
            params[Ct.neg_volatility_key()] = False

        reference_days = KPI.get_reference_days(params)
        negative = params[Ct.neg_volatility_key()]

        df = input_df.copy()

        df.columns = df.columns.droplevel(1)

        result_df = pd.DataFrame()
        # Whole volatility was calculated
        if negative is False:
            result_df[Volatility.kpi_name] = (df.std() *
                                              np.sqrt(reference_days))

        else:
            df_neg = df.where(df < 0, 0)
            result_df[Volatility.kpi_name] = (df_neg.std() *
                                              np.sqrt(reference_days))

        return result_df
Exemplo n.º 4
0
    def calculate(self):
        """function to calculate On Balance Volume"""

        super().calculate()

        daily_ret_key = Constants.get_key("daily_ret")
        direction_key = Constants.get_key("direction")
        volume_adjusted_key = Constants.get_key("vol_adj")

        df_result = []

        for ticker in self.tickers:

            df_data = self.df[ticker].copy()

            df_data[daily_ret_key] = df_data[self.prices_key].pct_change()
            df_data[direction_key] = np.where(df_data[daily_ret_key] >= 0, 1,
                                              -1)
            df_data.iloc[0].at[direction_key] = 0
            df_data[volume_adjusted_key] = df_data[
                self.volume_key] * df_data[direction_key]
            df_data[self.indicator_key] = df_data[volume_adjusted_key].cumsum()

            df_result.append(df_data.loc[:, [self.indicator_key]])

        self.df = pd.concat(df_result, axis=1, keys=self.tickers)

        return self.df
Exemplo n.º 5
0
    def set_input_data(self, df):
        super().set_input_data(df)

        # Set dataFrame keys
        self.low_key = Constants.get_low_key()
        self.high_key = Constants.get_high_key()
        self.indicator_key = Constants.get_key("ADX")

        prices_temp = pd.DataFrame()

        df_list = []
        for ticker in self.tickers:
            if ticker in df:
                df_list.append(
                    pd.concat([
                        df[ticker].
                        loc[:, [self.low_key, self.high_key, self.prices_key]],
                        prices_temp
                    ],
                              axis=1,
                              keys=[ticker]))

        df_indicator = pd.concat(df_list, axis=1)

        self.df = df_indicator.copy()
Exemplo n.º 6
0
    def get_calmar(input_df, params=None):
        """function to calculate Calmar"""
        if params is None:
            params = {}

        cagr = CAGR.get_cagr(input_df, params)
        max_dd = MaxDrawdown.get_max_drawdown(input_df)

        result_df = pd.DataFrame()
        result_df[Calmar.kpi_name] = (cagr[Ct.cagr_key()] /
                                      max_dd[Ct.max_drawdown_key()])

        return result_df
Exemplo n.º 7
0
    def set_input_data(self, df):
        super().set_input_data(df)

        self.low_key = Constants.get_low_key()
        self.high_key = Constants.get_high_key()
        self.open_key = Constants.get_open_key()

        # Set dataframe keys
        prices_temp = pd.DataFrame()

        df_list = []
        for ticker in self.tickers:
            if ticker in df:
                df_temp = df[ticker].loc[:, [
                    self.high_key, self.low_key, self.open_key, self.prices_key
                ]]

                df_list.append(
                    pd.concat([df_temp, prices_temp], axis=1, keys=[ticker]))

        df_indicator = pd.concat(df_list, axis=1)

        self.df = df_indicator.copy()

        prices_temp = pd.DataFrame()

        df_list = []
        for ticker in self.tickers:
            df_temp = df[ticker]
            df_temp.reset_index(level=0, inplace=True)
            df_temp = df_temp.loc[:, [
                self.date_key, self.high_key, self.low_key, self.open_key,
                self.prices_key
            ]]  # TODO: Is this rebundant???

            df_temp.rename(columns={
                "Date": "date",
                self.high_key: "high",
                self.low_key: "low",
                self.open_key: "open",
                self.prices_key: "close"
            },
                           inplace=True)

            df_list.append(
                pd.concat([df_temp, prices_temp], axis=1, keys=[ticker]))

        df_indicator = pd.concat(df_list, axis=1)

        self.df_renko_input = df_indicator.copy()
Exemplo n.º 8
0
class CAGR(KPI):
    kpi_name = Ct.cagr_key()

    def __init__(self, params=None):
        super().__init__(params)
        if not params:
            self.params = {}

    def calculate(self, df, params=None):
        """"function to calculate the Cumulative Annual Growth Rate of a trading strategy"""

        super().calculate(df, params)

        self.result = CAGR.get_cagr(df, self.params)
        return self.result

    # Params: {period:Ct.INTERVAL.MONTH|Ct.INTERVAL.DAY}
    # DF should be a percentage change
    @staticmethod
    def get_cagr(input_df, params=None):
        """"function to calculate the Cumulative Annual Growth Rate of a trading strategy"""

        reference_days = KPI.get_reference_days(params)
        df = input_df.copy()
        df.columns = df.columns.droplevel(1)

        cagr_data = (1 + df).cumprod()
        n = len(cagr_data) / reference_days
        result_df = pd.DataFrame()
        result_df[CAGR.kpi_name] = cagr_data.iloc[-1]**(1 / n) - 1

        return result_df
Exemplo n.º 9
0
    def calculate(self):
        """function to convert ohlc data into renko bricks"""

        super().calculate()

        df_result = []

        for ticker in self.tickers:

            df_data_atr = self.df[[ticker]].copy()
            atr = ATR(df_data_atr, 120)
            df_atr = atr.calculate()

            df_data = self.df_renko_input[ticker].copy()

            self.df_renko = Renko(df_data)

            atr_key = Constants.get_key("ATR")

            self.df_renko.brick_size = round(df_atr[ticker][atr_key][-1], 0)
            self.brick_size = self.df_renko.brick_size

            # renko_df = df2.get_bricks() #if get_bricks() does not work try using get_ohlc_data() instead
            self.renko_data = self.df_renko.get_ohlc_data()
            df_result.append(self.renko_data)

        self.df = pd.concat(df_result, axis=1, keys=self.tickers)

        return self.df
Exemplo n.º 10
0
class Calmar(KPI):
    kpi_name = Ct.calmar_key()

    def __init__(self, params=None):
        super().__init__(params)
        if not params:
            self.params = {}

    def calculate(self, df, params=None):
        super().calculate(df, params)
        self.result = Calmar.get_calmar(df, self.params)
        return self.result

    @staticmethod
    def get_calmar(input_df, params=None):
        """function to calculate Calmar"""
        if params is None:
            params = {}

        cagr = CAGR.get_cagr(input_df, params)
        max_dd = MaxDrawdown.get_max_drawdown(input_df)

        result_df = pd.DataFrame()
        result_df[Calmar.kpi_name] = (cagr[Ct.cagr_key()] /
                                      max_dd[Ct.max_drawdown_key()])

        return result_df
Exemplo n.º 11
0
class MaxDrawdown(KPI):
    kpi_name = Constants.max_drawdown_key()

    def __init__(self, params=None):
        super().__init__(params)
        if not params:
            self.params = {}

    def calculate(self, df, params=None):
        super().calculate(df)

        self.result = MaxDrawdown.get_max_drawdown(df)
        return self.result

    @staticmethod
    def get_max_drawdown(input_df):
        """ function to calculate max drawdown"        """

        df = input_df.copy()
        df.columns = df.columns.droplevel(1)

        cumprod_df = (1 + df).cumprod()
        cum_roll_max_df = cumprod_df.cummax()
        drawdown_df = cum_roll_max_df - cumprod_df
        drawdown_pct_df = drawdown_df / cum_roll_max_df
        result_df = pd.DataFrame()
        result_df[MaxDrawdown.kpi_name] = drawdown_pct_df.max()

        return result_df
Exemplo n.º 12
0
    def get_reference_days(params):
        if Ct.interval_key() in params.keys():
            period = params[Ct.interval_key()]
        else:
            raise ValueError(
                "Please set the corresponding Interval parameter"
                "{Ct.interval_key(): interval:Ct.INTERVAL.MONTH|Ct.INTERVAL.DAY}"
            )

        if period == Ct.INTERVAL.DAY:
            # 252 trading days
            reference_days = 252
        else:
            # 12 months
            reference_days = 12

        return reference_days
Exemplo n.º 13
0
    def get_standard_input_data(df):

        if df is None:
            raise ValueError("Error: Dataframe has not been provided, there is no data to calculate the requested KPI")

        input_data = {}

        # Set dataFrame keys
        adj_close_key = Constants.get_adj_close_key()
        close_key = Constants.get_close_key()

        if adj_close_key in df.columns is True:
            prices_key = adj_close_key

        else:
            prices_key = close_key

        prices_temp = pd.DataFrame()

        #TODO: Create a utilities class
        df.columns = pd.MultiIndex.from_tuples(df.columns.values)
        tickers = df.columns.levels[0]

        df_list = []
        for ticker in tickers:
            df_list.append(
                pd.concat(
                    [df[ticker].loc[:, [prices_key]], prices_temp],
                    axis=1,
                    keys=[ticker]
                )
            )

        input_df =\
            pd.concat(
                df_list,
                axis=1
            )

        input_data[Constants.get_prices_key()] = prices_key
        input_data[Constants.get_tickers_key()] = tickers
        input_data[Constants.get_input_df_key()] = input_df

        return input_data
Exemplo n.º 14
0
    def test_login(self, setup):
        self.logger.info(
            "******************** Test_003_AddCustomer ********************")
        self.driver = setup
        self.driver.get(self.baseURL)
        self.driver.maximize_window()

        self.loginPage = LoginPage(self.driver)
        self.loginPage.setUserName(self.username)
        self.loginPage.setPassword(self.password)
        self.loginPage.clickLogin()
        time.sleep(5)
        print("********** Login Successful **********")

        self.addCustomer = AddCustomer(self.driver)
        self.addCustomer.clickCustomers()
        self.addCustomer.clickSubMenuCustomers()
        self.addCustomer.clickAddNewCustomer()
        time.sleep(5)

        self.logger.info(
            "******************** Providing Customer Information ********************"
        )
        print("********** Providing Customer Information **********")

        self.email = Constants.random_email_generator()
        self.addCustomer.inputEmail(self.email)
        self.addCustomer.inputPassword("test123")
        self.addCustomer.inputFirstName("Bright")
        self.addCustomer.inputLastName("Brightest")
        self.addCustomer.selectGender(Constants.MALE)
        self.addCustomer.inputDateOfBirth("7/05/1985")
        self.addCustomer.inputCompanyName("NTTData GmbH")
        self.addCustomer.inputCustomerRoles(Constants.GUESTS)
        self.addCustomer.selectManagerVendor(Constants.VENDORS_TWO)
        self.addCustomer.inputAdminContent("This is for testing purposes only")
        self.driver.save_screenshot(".\\Screenshots\\" + "first_run.png")
        self.addCustomer.clickSaveButton()

        self.msg = self.driver.find_element_by_tag_name("body").text

        # print(self.msg)

        if 'customer has been added successfully.' in self.msg:
            assert True
            self.logger.info("********* Add customer Test Passed *********")
        else:
            self.driver.save_screenshot(
                ".\\Screenshots\\" + "test_addCustomer_scr.png")  # Screenshot
            self.logger.error(
                "********* Add customer Test Failed ************")
            assert False

        self.driver.close()
        self.logger.info("******* Ending Add customer test **********")
Exemplo n.º 15
0
    def get_sharpe(input_df, params):
        """ function to calculate sharpe """
        if params is None:
            params = {}

        if "rf" not in params.keys():
            # USA: risk free rate
            params["rf"] = 0.0144

        rf = params["rf"]

        "function to calculate sharpe ratio ; rf is the risk free rate"
        cagr = CAGR.get_cagr(input_df, params)
        volatility = Volatility.get_volatility(input_df, params)

        result_df = pd.DataFrame()
        result_df[Sharpe.kpi_name] = (cagr.loc[:, Ct.cagr_key()] -
                                      rf) / volatility.loc[:,
                                                           Ct.volatility_key()]

        return result_df
Exemplo n.º 16
0
    def set_input_data(self, df):
        super().set_input_data(df)

        # Set dataFrame keys
        self.bb_up_key = Constants.get_key("BB_up")
        self.bb_down_key = Constants.get_key("BB_down")
        self.bb_width_key = Constants.get_key("BB_width")

        prices_temp = pd.DataFrame()

        df_list = []
        for ticker in self.tickers:
            if ticker in df:
                df_list.append(
                    pd.concat(
                        [df[ticker].loc[:, [self.prices_key]], prices_temp],
                        axis=1,
                        keys=[ticker]))

        df_indicator = pd.concat(df_list, axis=1)

        self.df = df_indicator.copy()
Exemplo n.º 17
0
    def calculate(self):
        """function to calculate RSI
           typical values n=14"""

        super().calculate()

        delta_key = Constants.get_key("delta")
        gain_key = Constants.get_key("gain")
        loss_key = Constants.get_key("loss")
        avg_gain_key = Constants.get_key("avg_gain")
        avg_loss_key = Constants.get_key("avg_loss")
        rs_key = Constants.get_key("RS")

        df_result = []

        for ticker in self.tickers:

            df_data = self.df[ticker].copy()

            df_data[delta_key] = df_data[self.prices_key] - df_data[
                self.prices_key].shift(1)
            df_data[gain_key] = np.where(df_data[delta_key] >= 0,
                                         df_data[delta_key], 0)
            df_data[loss_key] = np.where(df_data[delta_key] < 0,
                                         abs(df_data[delta_key]), 0)
            avg_gain = []
            avg_loss = []
            gain = df_data[gain_key].tolist()
            loss = df_data[loss_key].tolist()

            for i in range(len(df_data)):
                if i < self.n:
                    avg_gain.append(np.NaN)
                    avg_loss.append(np.NaN)
                elif i == self.n:
                    avg_gain.append(df_data[gain_key].rolling(
                        self.n).mean().tolist()[self.n])
                    avg_loss.append(df_data[loss_key].rolling(
                        self.n).mean().tolist()[self.n])
                elif i > self.n:
                    avg_gain.append(
                        ((self.n - 1) * avg_gain[i - 1] + gain[i]) / self.n)
                    avg_loss.append(
                        ((self.n - 1) * avg_loss[i - 1] + loss[i]) / self.n)

            df_data[avg_gain_key] = np.array(avg_gain)
            df_data[avg_loss_key] = np.array(avg_loss)
            df_data[rs_key] = df_data[avg_gain_key] / df_data[avg_loss_key]
            df_data[self.indicator_key] = 100 - (100 / (1 + df_data[rs_key]))

            df_result.append(df_data.loc[:, [self.indicator_key]])

        self.df = pd.concat(df_result, axis=1, keys=self.tickers)

        return self.df
Exemplo n.º 18
0
class Sortino(KPI):
    kpi_name = Ct.sortino_key()

    # RF is risk free rate
    def __init__(self, params=None):
        super().__init__(params)
        if not params:
            self.params = {}

    def calculate(self, df, params=None):
        super().calculate(df, params)

        self.result = Sortino.get_sortino(df, self.params)
        return self.result

    @staticmethod
    def get_sortino(input_df, params=None):

        if params is None:
            params = {}

        if "rf" not in params.keys():
            # USA: risk free rate
            params = {"rf": 0.0144}

        rf = params["rf"]

        "function to calculate Sortino ratio ; rf is the risk free rate"

        cagr = CAGR.get_cagr(input_df, params)

        vol_params = params
        vol_params[Ct.neg_volatility_key()] = True
        neg_vol = Volatility.get_volatility(input_df, vol_params)

        result_df = pd.DataFrame()
        result_df[Sortino.kpi_name] = (cagr.loc[:, Ct.cagr_key()] -
                                       rf) / neg_vol.loc[:,
                                                         Ct.volatility_key()]

        result_df.rename(index={0: Sortino.kpi_name}, inplace=True)

        return result_df
Exemplo n.º 19
0
    def get_prices_data(self, keys=None):

        if keys is None or len(keys) == 0:
            print("No keys has been specified. All keys were selected. ")

            keys = {
                Ct.high_key(): True,
                Ct.low_key(): True,
                Ct.open_key(): True,
                Ct.close_key(): True,
                Ct.adj_close_key(): True,
                Ct.volume_key(): True
            }

        method_tag = "get_prices_data"

        if self.data_source_historical is not None:
            if self.data_source_historical.prices is None or self.data_source_historical.prices.empty is True:
                raise ValueError(
                    "No historical data available, call method self.get_historical_data() first"
                )

            key_titles = self.get_key_titles(keys)

            if len(key_titles) > 0:

                prices = self.data_source_historical.get_prices(
                    self.tickers, key_titles)

            else:
                print("{} - There are no prices information, for ticker:{}".
                      format(method_tag, self.tickers))
                raise ValueError

        else:
            print("There has been an error in {}".format(method_tag))
            raise ValueError

        # Validate Price dataframe
        if prices.empty == True:
            print("There has been an error in {}".format(method_tag))
            raise ValueError

        self.price_info = prices
        return prices
Exemplo n.º 20
0
class Sharpe(KPI):
    kpi_name = Ct.sharpe_key()

    # rf = Risk free rate
    def __init__(self, params=None):
        super().__init__(params)
        if not params:
            self.params = {}

    def calculate(self, df, params=None):
        super().calculate(df, params)
        self.result = Sharpe.get_sharpe(df, self.params)
        return self.result

    @staticmethod
    def get_sharpe(input_df, params):
        """ function to calculate sharpe """
        if params is None:
            params = {}

        if "rf" not in params.keys():
            # USA: risk free rate
            params["rf"] = 0.0144

        rf = params["rf"]

        "function to calculate sharpe ratio ; rf is the risk free rate"
        cagr = CAGR.get_cagr(input_df, params)
        volatility = Volatility.get_volatility(input_df, params)

        result_df = pd.DataFrame()
        result_df[Sharpe.kpi_name] = (cagr.loc[:, Ct.cagr_key()] -
                                      rf) / volatility.loc[:,
                                                           Ct.volatility_key()]

        return result_df
Exemplo n.º 21
0
    def calculate(self):
        """function to calculate Bollinger Bands"""

        super().calculate()

        # Set temp dataframe keys
        ma_key = Constants.get_key("MA")

        df_data = pd.DataFrame()
        df_result = []

        for ticker in self.tickers:
            df_data = self.df[ticker].copy()

            #df_data.rename(columns={self.ticker: self.prices_key}, inplace=True) #TODO: what happens with this

            df_data[ma_key] = \
                df_data[self.prices_key].rolling(self.n).mean()

            # ddof=0 is required since we want to take the standard deviation of the population and not sample
            df_data[self.bb_up_key] = \
                df_data[ma_key] + 2 * df_data[self.prices_key].rolling(self.n).std(ddof=0)

            # ddof=0 is required since we want to take the standard deviation of the population and not sample
            df_data[self.bb_down_key] = \
                df_data[ma_key] - 2 * df_data[self.prices_key].rolling(self.n).std(ddof=0)
            df_data[self.bb_width_key] = df_data[self.bb_up_key] - df_data[
                self.bb_down_key]
            df_data.dropna(inplace=True)

            df_result.append(df_data.loc[:,
                                         [self.bb_up_key, self.bb_down_key]])

        self.df = pd.concat(df_result, axis=1, keys=self.tickers)

        return df_data
Exemplo n.º 22
0
    def calculate(self):
        """"function to calculate ADX"""
        super().calculate()

        tr_key = Constants.get_key("TR")
        trn_key = Constants.get_key("TRn")

        dm_plus_key = Constants.get_key("DMplus")
        dm_plus_n_key = Constants.get_key("DMplusN")

        dm_minus_key = Constants.get_key("DMminus")
        dm_minus_n_key = Constants.get_key("DMminusN")
        di_plus_n_key = Constants.get_key("DIplusN")
        di_minus_n_key = Constants.get_key("DIminusN")
        di_diff_key = Constants.get_key("DIdiff")
        di_sum_key = Constants.get_key("DIsum")
        dx_key = Constants.get_key("DX")

        df_result = []

        for ticker in self.tickers:

            df_data_atr = self.df[[ticker]].copy()
            atr_ind = ATR(df=df_data_atr, n=14)

            df_data = self.df[ticker].copy()
            # the period parameter of ATR function does not matter because period does not influence TR calculation
            df_data[tr_key] = atr_ind.calculate()[ticker][[tr_key]]

            df_data[dm_plus_key] = \
                np.where(
                    (df_data[self.high_key] - df_data[self.high_key].shift(1)) >
                    (df_data[self.low_key].shift(1) - df_data[self.low_key]),
                    df_data[self.high_key] - df_data[self.high_key].shift(1),
                    0)

            df_data[dm_plus_key] = \
                np.where(
                    df_data[dm_plus_key] < 0,
                    0,
                    df_data[dm_plus_key])

            df_data[dm_minus_key] = \
                np.where((df_data[self.low_key].shift(1) - df_data[self.low_key]) >
                         (df_data[self.high_key] - df_data[self.high_key].shift(1)),
                         df_data[self.low_key].shift(1) - df_data[self.low_key],
                         0)

            df_data[dm_minus_key] = np.where(df_data[dm_minus_key] < 0, 0,
                                             df_data[dm_minus_key])

            TRn = []
            DMplusN = []
            DMminusN = []
            TR = df_data[tr_key].tolist()
            DMplus = df_data[dm_plus_key].tolist()
            DMminus = df_data[dm_minus_key].tolist()

            for i in range(len(df_data)):
                if i < self.n:
                    TRn.append(np.NaN)
                    DMplusN.append(np.NaN)
                    DMminusN.append(np.NaN)
                elif i == self.n:
                    TRn.append(df_data[tr_key].rolling(
                        self.n).sum().tolist()[self.n])
                    DMplusN.append(df_data[dm_plus_key].rolling(
                        self.n).sum().tolist()[self.n])
                    DMminusN.append(df_data[dm_minus_key].rolling(
                        self.n).sum().tolist()[self.n])
                elif i > self.n:
                    TRn.append(TRn[i - 1] - (TRn[i - 1] / 14) + TR[i])
                    DMplusN.append(DMplusN[i - 1] - (DMplusN[i - 1] / 14) +
                                   DMplus[i])
                    DMminusN.append(DMminusN[i - 1] - (DMminusN[i - 1] / 14) +
                                    DMminus[i])

            df_data[trn_key] = np.array(TRn)
            df_data[dm_plus_n_key] = np.array(DMplusN)
            df_data[dm_minus_n_key] = np.array(DMminusN)
            df_data[di_plus_n_key] = 100 * (df_data[dm_plus_n_key] /
                                            df_data[trn_key])
            df_data[di_minus_n_key] = 100 * (df_data[dm_minus_n_key] /
                                             df_data[trn_key])
            df_data[di_diff_key] = abs(df_data[di_plus_n_key] -
                                       df_data[di_minus_n_key])
            df_data[
                di_sum_key] = df_data[di_plus_n_key] + df_data[di_minus_n_key]
            df_data[dx_key] = 100 * (df_data[di_diff_key] /
                                     df_data[di_sum_key])
            ADX = []
            DX = df_data[dx_key].tolist()
            for j in range(len(df_data)):
                if j < 2 * self.n - 1:
                    ADX.append(np.NaN)
                elif j == 2 * self.n - 1:
                    ADX.append(df_data[dx_key][j - self.n + 1:j + 1].mean())
                elif j > 2 * self.n - 1:
                    ADX.append(((self.n - 1) * ADX[j - 1] + DX[j]) / self.n)
            df_data[self.indicator_key] = np.array(ADX)

            df_result.append(df_data.loc[:, [self.indicator_key]])

        self.df = pd.concat(df_result, axis=1, keys=self.tickers)

        return self.df
Exemplo n.º 23
0
    def get_atr(input_df, params=None):

        n = params["n"]

        # Set temp dataframe keys
        h_l_key = Ct.get_key("H-L")
        h_pc_key = Ct.get_key("H-PC")
        l_pc_key = Ct.get_key("L-PC")
        tr_key = Ct.get_key("TR")

        df_data = input_df.copy()
        df_data.columns = df_data.columns.droplevel(1)

        df_data[h_l_key] = abs(df_data[Ct.high_key()] - df_data[Ct.low_key()])
        df_data[h_pc_key] = abs(df_data[Ct.high_key()] -
                                df_data[Ct.prices_key()].shift(1))
        df_data[l_pc_key] = abs(df_data[Ct.low_key()] -
                                df_data[Ct.prices_key()].shift(1))
        df_data[tr_key] = df_data[[h_l_key, h_pc_key,
                                   l_pc_key]].max(axis=1, skipna=False)
        df_data[Ct.atr_key()] = df_data[tr_key].rolling(n).mean()
        # df[Ct.atr_key()] = df[tr_key].ewm(span=n,adjust=False,min_periods=n).mean()
        # df_data.dropna(inplace=True, axis=0)

        df_data.drop([h_l_key, h_pc_key, l_pc_key], axis=1, inplace=True)

        result_df = pd.DataFrame()
        result_df.append(df_data.loc[:, [Ct.atr_key(), tr_key]])

        return result_df
Exemplo n.º 24
0
    def test_intra_day(self):
        #  DJI constituent stocks
        tickers = ["MMM", "AXP", "T", "BA", "CAT", "CSCO", "KO", "XOM", "GE",
                   "GS", "HD", "IBM", "INTC", "JNJ", "JPM", "MCD", "MRK", "MSFT",
                   "NKE", "PFE", "PG", "TRV", "UNH", "VZ", "V", "WMT", "DIS"]

        ref_tickers = ["^DJI"]

        end_date = dt.datetime.now()  # dt.datetime(2021, 3, 7)
        interval = Ct.INTERVAL.MONTH

        conf = {
            Ct.tickers_key(): tickers,
            Ct.historical_type_key(): DATASOURCETYPE.YFINANCE,
            Ct.fundamentals_type_key(): None,
            Ct.fundamentals_options_key(): [],
            Ct.force_fundamentals_key(): False,
            Ct.indicators_key(): [],
            Ct.start_date_key(): end_date - dt.timedelta(3650),
            Ct.end_date_key(): end_date,
            Ct.interval_key(): interval,
            Ct.period_key(): None,
            Ct.bulk_key(): True
        }

        stocks = \
            StocksFactory.create_stocks(
                conf=conf
            )

        conf[Ct.tickers_key()] = ref_tickers

        stocks_ref = \
            StocksFactory.create_stocks(
                conf=conf
            )

        prices_df = stocks[0].get_prices_data(keys={Ct.adj_close_key(): True})
        ref_prices_df = stocks_ref[0].get_prices_data(keys={Ct.adj_close_key(): True})

        pr = PortfolioRebalance()
        params = {"m": 6, "x": 3, Ct.interval_key(): conf[Ct.interval_key()]}
        pr.backtest(prices_df, ref_prices_df, params)
Exemplo n.º 25
0
    def create_stocks(conf):

        tickers = conf[Ct.tickers_key()]

        data_source_historical = None
        data_source_fundamentals = None

        data_sources = \
            DataCollector.get_data_sources(
                conf[Ct.historical_type_key()],
                conf[Ct.fundamentals_type_key()]
            )

        if DataCollector.HISTORICAL_KEY in data_sources.keys():
            data_source_historical = data_sources[DataCollector.HISTORICAL_KEY]

            if data_source_historical is not None:
                data_source_historical.extract_historical_data(
                    tickers=tickers,
                    start_date=conf[Ct.start_date_key()],
                    end_date=conf[Ct.end_date_key()],
                    period=conf[Ct.period_key()],
                    interval=conf[Ct.interval_key()])

        if DataCollector.FUNDAMENTALS_KEY in data_sources.keys():
            data_source_fundamentals = data_sources[
                DataCollector.FUNDAMENTALS_KEY]

            if data_source_fundamentals is not None:
                data_source_fundamentals.extract_fundamentals(
                    tickers=tickers,
                    date=conf[Ct.start_date_key],
                    required_elements=conf[Ct.fundamentals_options_key()],
                    force_server_data=conf[Ct.force_fundamentals_key()])

        stocks = StocksFactory.load_stocks(
            tickers=tickers,
            data_source_historical=data_source_historical,
            data_source_fundamentals=data_source_fundamentals,
            bulk=conf[Ct.bulk_key()],
            indicators=conf[Ct.indicators_key()])

        return stocks
Exemplo n.º 26
0
    def plot_stock(self, stock, tickers=None, collapse_indicators=False):

        Plotter.legend_id = 0
        Plotter.current_color_indicator = 0

        if stock is None:
            print("There is no ticker Information, nothing to be plot")
            return

        if tickers is None:
            tickers = stock.tickers

        elif isinstance(tickers, list) is True:
            tickers = tickers

        else:
            tickers = [tickers]

        if self.fig is None or self.axes_main is None or self.axes_indicators is None:

            if stock.price_info is None or stock.price_info[tickers].empty:
                raise ValueError(
                    "There is no price information for this stock")

            adj_close_key = Constants.get_adj_close_key()
            volume_key = Constants.get_volume_key()

            self.price_series = {}
            self.volume_series = {}

            self.x_series = {}

            for ticker in tickers:
                if (adj_close_key in stock.price_info[ticker]) == False:
                    adj_close_key = Constants.get_close_key()

                self.x_series[ticker] = stock.price_info[ticker].iloc[
                    -self.period:, :].index

                self.price_series[ticker] = stock.price_info[ticker].iloc[
                    -self.period:, :][adj_close_key]
                self.volume_series[ticker] = stock.price_info[ticker].iloc[
                    -self.period:, :][volume_key]

                self.axes_main = dict()
                self.axes_indicators = dict()

                if len(stock.indicators) == 0:
                    subplots = 1

                elif len(stock.indicators) > 0 and collapse_indicators is True:

                    extra = len(
                        list(
                            filter(
                                lambda x: x.collapse is False or x.in_main_plot
                                is False, stock.indicators)))
                    no_collapse = len(
                        list(
                            filter(
                                lambda x: x.collapse is False and x.
                                in_main_plot is False, stock.indicators)))
                    if no_collapse > 0:
                        no_collapse = no_collapse - 1

                    fixed = 2
                    if extra == 0:
                        fixed = 1

                    subplots = fixed + no_collapse

                else:
                    subplots = len(
                        list(
                            filter(lambda x: x.in_main_plot is False,
                                   stock.indicators))) + 1

                heights_list = [2 for i in range(subplots - 1)]
                if subplots == 1:
                    heights_list.insert(0, 2)
                else:
                    heights_list.insert(0, 3)

                self.fig = plt.figure(figsize=(8, 6), dpi=80)
                gridspec = self.fig.add_gridspec(ncols=1,
                                                 nrows=subplots,
                                                 height_ratios=heights_list)

                # gridspec_kw = {'height_ratios': heights_list}

                self.axes_main[Constants.volume_axis] = self.fig.add_subplot(
                    gridspec[0, 0])

                self.set_volume(ticker=ticker)

                self.set_stock_price(ticker=ticker, color=self.stock_color)

                i = 1  # Indicator axis begins in 2

                indicator_axis = None

                Plotter.legend_id = 0
                for indicator in stock.indicators:

                    if indicator.in_main_plot is False:
                        if collapse_indicators == True:

                            if i > 1:
                                if indicator.collapse is False:
                                    self.axes_indicators = self.fig.add_subplot(
                                        gridspec[i, 0])
                                    indicator_axis = self.axes_indicators

                                else:
                                    indicator_axis = indicator_axis.twinx()

                            else:  # Executed first
                                self.axes_indicators = \
                                    self.fig.add_subplot(
                                        gridspec[i, 0],
                                        sharex=self.axes_main[Constants.prices_axis])

                                indicator_axis = self.axes_indicators

                        else:
                            Plotter.legend_id = 0

                            sharex = None
                            if indicator.collapse is True:
                                sharex = self.axes_main[Constants.prices_axis]

                            self.axes_indicators = \
                                self.fig.add_subplot(
                                    gridspec[i, 0],
                                    sharex=sharex)

                            indicator_axis = self.axes_indicators

                        if indicator_axis is None:
                            indicator_axis = self.axes_indicators

                        i += 1

                    else:
                        indicator_axis = self.axes_main[Constants.prices_axis]

                    self.set_plot_indicator(indicator=indicator,
                                            ticker=ticker,
                                            axis=indicator_axis)

        plt.tight_layout()
Exemplo n.º 27
0
    def test_KPI_calmar(self):
        tickers = ["TSLA", "SPY"]
        interval = Ct.INTERVAL.DAY

        conf = {
            Ct.tickers_key(): tickers,
            Ct.historical_type_key(): DATASOURCETYPE.YFINANCE,
            Ct.fundamentals_type_key(): None,
            Ct.fundamentals_options_key(): [],
            Ct.force_fundamentals_key(): False,
            Ct.indicators_key(): [],
            Ct.start_date_key(): dt.datetime(2021, 3, 7) - dt.timedelta(1825),
            Ct.end_date_key(): dt.datetime(2021, 3, 7),
            Ct.interval_key(): interval,
            Ct.period_key(): None,
            Ct.bulk_key(): True
        }

        stocks = \
            StocksFactory.create_stocks(
                conf=conf
            )

        prices_df = stocks[0].get_prices_data(keys={Ct.adj_close_key(): True})

        df = Financials.pct_change(prices_df)

        params = {Ct.interval_key(): interval}
        calmar = Calmar()
        result = calmar.calculate(df, params)

        self.assertEqual(1.1700790532917946, result[Ct.calmar_key()]['TSLA'])
Exemplo n.º 28
0
    def test_KPI_max_drawdown(self):
        tickers = ["TSLA", "SPY"]
        interval = Ct.INTERVAL.DAY

        conf = {
            Ct.tickers_key(): tickers,
            Ct.historical_type_key(): DATASOURCETYPE.YFINANCE,
            Ct.fundamentals_type_key(): None,
            Ct.fundamentals_options_key(): [],
            Ct.force_fundamentals_key(): False,
            Ct.indicators_key(): [],
            Ct.start_date_key(): dt.datetime(2021, 3, 7) - dt.timedelta(1825),
            Ct.end_date_key(): dt.datetime(2021, 3, 7),
            Ct.interval_key(): interval,
            Ct.period_key(): None,
            Ct.bulk_key(): True
        }

        stocks = \
            StocksFactory.create_stocks(
                conf=conf
            )

        prices_df = stocks[0].get_prices_data(keys={Ct.adj_close_key(): True})

        df = Financials.pct_change(prices_df)

        md = MaxDrawdown()
        result = md.calculate(df)

        self.assertEqual(0.6062653645917145,
                         result[Ct.max_drawdown_key()]['TSLA'])
        self.assertEqual(0.3371725544013077,
                         result[Ct.max_drawdown_key()]['SPY'])