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)
Пример #2
0
    def test_KPI_cagr(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}
        cagr = CAGR()
        result = cagr.calculate(df, params)

        self.assertEqual(0.7093784038450781, result[Ct.cagr_key()]['TSLA'])
        self.assertEqual(0.1608091728848835, result[Ct.cagr_key()]['SPY'])
Пример #3
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
Пример #4
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
Пример #5
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
Пример #6
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