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)
Example #2
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'])
Example #3
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'])
Example #4
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
    def test_portfolio_rebalance(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)
Example #6
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