Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Did an upgrade, I believe there is a bug in the _strategy.py regarding polygone api key. #518

Open
ghzgod opened this issue Aug 10, 2024 · 5 comments

Comments

@ghzgod
Copy link

ghzgod commented Aug 10, 2024

I did a pip upgrade and now If I run YahooDataBackTest for my strategy I get an error

Here is my code:

from login import get_api_key
from lumibot.traders import Trader
from lumibot.brokers import Alpaca
from datetime import datetime, timedelta
from lumibot.strategies.strategy import Strategy
from lumibot.backtesting import YahooDataBacktesting
from datetime import datetime


ALPACA_CONFIG = {
    # Put your own Alpaca key here:
    "API_KEY": get_api_key("alpaca_paper_api_key"),
    # Put your own Alpaca secret here:
    "API_SECRET": get_api_key("alpaca_paper_api_secret"),
    # Set this to False to use a live account
    "PAPER": True
}


class MyStrategy(Strategy):
    parameters = {
        "symbol": None,
        "quantity": 1,
        "side": "buy"
    }

    def initialize(self, symbol=""):
        self.sleeptime = "60M"

    def on_trading_iteration(self):
        symbol = self.parameters["symbol"]
        quantity = self.parameters["quantity"]
        side = self.parameters["side"]
        order = self.create_order(symbol, quantity, side)
        self.submit_order(order)


if __name__ == "__main__":
    trade = False
    if trade:
        broker = Alpaca(ALPACA_CONFIG)
        strategy = MyStrategy(broker=broker, parameters={"symbol": "NVDA"})
        trader = Trader()
        trader.add_strategy(strategy)
        trader.run_all()
    else:
        years_to_backest = 1 # Number of years before today
        end = datetime.today() - timedelta(days=1)
        start = end - timedelta(days=365 * years_to_backest)
        MyStrategy.backtest(
            YahooDataBacktesting,
            start,
            end,
            parameters={"symbol": "GME"}
        )


Here is my error

 File "python/stocks/profitprophet/archive/lumibot/lumibot_backtests.py", line 50, in <module>
    MyStrategy.backtest(
  File "python3.12/site-packages/lumibot/strategies/_strategy.py", line 1361, in backtest
    results, strategy = cls.run_backtest(
                        ^^^^^^^^^^^^^^^^^
  File "python3.12/site-packages/lumibot/strategies/_strategy.py", line 1050, in run_backtest
    data_source = datasource_class(
                  ^^^^^^^^^^^^^^^^^
  File "python3.12/site-packages/lumibot/backtesting/yahoo_backtesting.py", line 11, in __init__
    YahooData.__init__(self, datetime_start, datetime_end, **kwargs)
  File "python3.12/site-packages/lumibot/data_sources/yahoo_data.py", line 22, in __init__
    super().__init__(*args, **kwargs)
TypeError: DataSourceBacktesting.__init__() got an unexpected keyword argument 'polygon_api_key'

If I edit the _strategy.py file and comment out the polygone data (in the below example) it begins to work as intended. Is this a bug? Hopefully this is useful information.

        results, strategy = cls.run_backtest(
            *args,
            minutes_before_closing=minutes_before_closing,
            minutes_before_opening=minutes_before_opening,
            sleeptime=sleeptime,
            stats_file=stats_file,
            risk_free_rate=risk_free_rate,
            logfile=logfile,
            config=config,
            auto_adjust=auto_adjust,
            name=name,
            budget=budget,
            benchmark_asset=benchmark_asset,
            plot_file_html=plot_file_html,
            trades_file=trades_file,
            settings_file=settings_file,
            pandas_data=pandas_data,
            quote_asset=quote_asset,
            starting_positions=starting_positions,
            show_plot=show_plot,
            tearsheet_file=tearsheet_file,
            save_tearsheet=save_tearsheet,
            show_tearsheet=show_tearsheet,
            parameters=parameters,
            buy_trading_fees=buy_trading_fees,
            sell_trading_fees=sell_trading_fees,
            api_key=api_key,
            # polygon_api_key=polygon_api_key,  <------- HERE
            # polygon_has_paid_subscription=polygon_has_paid_subscription, <------- AND HERE
            indicators_file=indicators_file,
            show_indicators=show_indicators,
            save_logfile=save_logfile,
            **kwargs,
        )
@ghzgod
Copy link
Author

ghzgod commented Aug 10, 2024

I believe I fixed it by checking the datasource_class first and then adding polygone keys if needed

@classmethod
    def backtest(
        cls,
        datasource_class,  # Ensure datasource_class is passed as an argument
        *args,
        minutes_before_closing=1,
        minutes_before_opening=60,
        sleeptime=1,
        stats_file=None,
        risk_free_rate=None,
        logfile=None,
        config=None,
        auto_adjust=False,
        name=None,
        budget=None,
        benchmark_asset="SPY",
        plot_file_html=None,
        trades_file=None,
        settings_file=None,
        pandas_data=None,
        quote_asset=Asset(symbol="USD", asset_type="forex"),
        starting_positions=None,
        show_plot=True,
        tearsheet_file=None,
        save_tearsheet=True,
        show_tearsheet=True,
        parameters={},
        buy_trading_fees=[],
        sell_trading_fees=[],
        api_key=None,
        polygon_api_key=None,
        polygon_has_paid_subscription=None,  # Deprecated, remove in future versions.
        indicators_file=None,
        show_indicators=True,
        save_logfile=False,
        **kwargs,
    ):
        """Backtest a strategy.

        Parameters
        ----------
        datasource_class : class
            The datasource class to use. For example, if you want to use the yahoo finance datasource, then you
            would pass YahooDataBacktesting as the datasource_class.
        backtesting_start : datetime
            The start date of the backtesting period.
        backtesting_end : datetime
            The end date of the backtesting period.
        minutes_before_closing : int
            The number of minutes before closing that the minutes_before_closing strategy method will be called.
        minutes_before_opening : int
            The number of minutes before opening that the minutes_before_opening strategy method will be called.
        sleeptime : int
            The number of seconds to sleep between each iteration of the backtest.
        stats_file : str
            The file to write the stats to.
        risk_free_rate : float
            The risk free rate to use.
        logfile : str
            The file to write the log to.
        config : dict
            The config to use to set up the brokers in live trading.
        auto_adjust : bool
            Whether or not to automatically adjust the strategy.
        name : str
            The name of the strategy.
        budget : float
            The initial budget to use for the backtest.
        benchmark_asset : str or Asset
            The benchmark asset to use for the backtest to compare to. If it is a string then it will be converted
            to a stock Asset object.
        plot_file_html : str
            The file to write the plot html to.
        trades_file : str
            The file to write the trades to.
        pandas_data : list
            A list of Data objects that are used when the datasource_class object is set to PandasDataBacktesting.
            This contains all the data that will be used in backtesting.
        quote_asset : Asset (crypto)
            An Asset object for the crypto currency that will get used
            as a valuation asset for measuring overall porfolio values.
            Usually USDT, USD, USDC.
        starting_positions : dict
            A dictionary of starting positions for each asset. For example,
            if you want to start with $100 of SPY, and $200 of AAPL, then you
            would pass in starting_positions={'SPY': 100, 'AAPL': 200}.
        show_plot : bool
            Whether to show the plot.
        show_tearsheet : bool
            Whether to show the tearsheet.
        save_tearsheet : bool
            Whether to save the tearsheet.
        parameters : dict
            A dictionary of parameters to pass to the strategy. These parameters
            must be set up within the initialize() method.
        buy_trading_fees : list of TradingFee objects
            A list of TradingFee objects to apply to the buy orders during backtests.
        sell_trading_fees : list of TradingFee objects
            A list of TradingFee objects to apply to the sell orders during backtests.
        api_key : str
            The polygon api key to use for polygon data. Only required if you are using PolygonDataBacktesting as
            the datasource_class.
        polygon_api_key : str
            The polygon api key to use for polygon data. Only required if you are using PolygonDataBacktesting as
            the datasource_class. Depricated, please use 'api_key' instead.
        indicators_file : str
            The file to write the indicators to.
        show_indicators : bool
            Whether to show the indicators plot.
        save_logfile : bool
            Whether to save the logs to a file. If True, the logs will be saved to the logs directory. Defaults to False.
            Turning on this option will slow down the backtest.

        Returns
        -------
        result : dict
            A dictionary of the backtest results. Eg.

        Examples
        --------

        >>> from datetime import datetime
        >>> from lumibot.backtesting import YahooDataBacktesting
        >>> from lumibot.strategies import Strategy
        >>>
        >>> # A simple strategy that buys AAPL on the first day
        >>> class MyStrategy(Strategy):
        >>>    def on_trading_iteration(self):
        >>>        if self.first_iteration:
        >>>            order = self.create_order("AAPL", quantity=1, side="buy")
        >>>            self.submit_order(order)
        >>>
        >>> # Create a backtest
        >>> backtesting_start = datetime(2018, 1, 1)
        >>> backtesting_end = datetime(2018, 1, 31)
        >>>
        >>> # The benchmark asset to use for the backtest to compare to
        >>> benchmark_asset = Asset(symbol="QQQ", asset_type="stock")
        >>>
        >>> backtest = MyStrategy.backtest(
        >>>     datasource_class=YahooDataBacktesting,
        >>>     backtesting_start=backtesting_start,
        >>>     backtesting_end=backtesting_end,
        >>>     benchmark_asset=benchmark_asset,
        >>> )
        """
        """Backtest a strategy."""

        # Create a dictionary of keyword arguments to pass to the run_backtest method
        run_backtest_kwargs = {
            "minutes_before_closing": minutes_before_closing,
            "minutes_before_opening": minutes_before_opening,
            "sleeptime": sleeptime,
            "stats_file": stats_file,
            "risk_free_rate": risk_free_rate,
            "logfile": logfile,
            "config": config,
            "auto_adjust": auto_adjust,
            "name": name,
            "budget": budget,
            "benchmark_asset": benchmark_asset,
            "plot_file_html": plot_file_html,
            "trades_file": trades_file,
            "settings_file": settings_file,
            "pandas_data": pandas_data,
            "quote_asset": quote_asset,
            "starting_positions": starting_positions,
            "show_plot": show_plot,
            "tearsheet_file": tearsheet_file,
            "save_tearsheet": save_tearsheet,
            "show_tearsheet": show_tearsheet,
            "parameters": parameters,
            "buy_trading_fees": buy_trading_fees,
            "sell_trading_fees": sell_trading_fees,
            "api_key": api_key,
            "indicators_file": indicators_file,
            "show_indicators": show_indicators,
            "save_logfile": save_logfile,
            **kwargs,
        }

        # Include Polygon-specific arguments if the datasource_class is PolygonDataBacktesting
        if datasource_class == PolygonDataBacktesting:
            run_backtest_kwargs["polygon_api_key"] = polygon_api_key
            run_backtest_kwargs["polygon_has_paid_subscription"] = polygon_has_paid_subscription

        results, strategy = cls.run_backtest(
            datasource_class,  # Pass the datasource_class here
            *args,
            **run_backtest_kwargs,
        )

        return results, strategy

@Al4ise
Copy link
Collaborator

Al4ise commented Aug 10, 2024

Hey, polygon_api_key and polygon_has_paid subscription are deprecated either way. Could you try what I've done in the PR and see if it works for you?

@ghzgod
Copy link
Author

ghzgod commented Aug 10, 2024

Seems to be working! Thanks for the quick commit. Just discovered this tool and it's pretty rad!

@Al4ise
Copy link
Collaborator

Al4ise commented Aug 10, 2024

No worries :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@ghzgod @Al4ise and others