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

Add support for different datafeed in cloud #359

Conversation

Marinovsky
Copy link
Collaborator

Closes #81

Description

So far just lean live deploy supports different datafeed. With this change, the method get_price_data_handler() from cloud_brokerage.py can now parse the datafeed selected in the user input to the expected name in the QC API. In order to make this, the file modules-1.11.json was also modified to accept one choice from the available datafeed's for certain brokerage. For example, for IB brokerage:

{
                    "id": "ib-data-feed",
                    "type": "input",
                    "value": "",
                    "filters": [
                        {
                            "condition": {
                                "type": "exact-match",
                                "pattern": "CloudBrokerage",
                                "dependent-config-id": "module-type"
                            }
                        }
                    ],
                    "input-method": "choice",
                    "input-choices": [
                        "QuantConnect",
                        "Interactive Brokers",
                        "QuantConnect + InteractiveBrokers"
                    ],
                    "prompt-info": "Which one do you want to use: the Interactive Brokers price data feed, QuantConnect price data feed or QuantConnect + InteractiveBrokers price data feed",
                    "help": "The available price data feeds are: Interactive Brokers price data feed, QuantConnect price data feed or QuantConnect + InteractiveBrokers price data feed"
                },

In the same way, the method get_price_data_handler() was modified to work for other brokerages in the future. Below, it's shown a unit test made to assert this:

@pytest.mark.parametrize("brokerage, datafeed, expected", [
                                                ("Binance", "Binance", "Binance"),
                                                ("Binance", "QuantConnect + Binance", "quantconnecthandler+binancehandler"),
                                                ("Bitfinex", "QuantConnect", "QuantConnect"),
                                                ("Bitfinex", "Bitfinex", "Bitfinex"),
                                                ("Bitfinex", "QuantConnect + Bitfinex", "quantconnecthandler+bitfinexhandler"),
                                                ("Coinbase Pro", "QuantConnect", "QuantConnect"),
                                                ("Coinbase Pro", "Coinbase Pro", "CoinbasePro"),
                                                ("Coinbase Pro", "QuantConnect + CoinbasePro", "quantconnecthandler+coinbaseprohandler"),
                                                ("Interactive Brokers", "QuantConnect", "QuantConnect"),
                                                ("Interactive Brokers", "Interactive Brokers", "InteractiveBrokers"),
                                                ("Interactive Brokers", "QuantConnect + InteractiveBrokers", "quantconnecthandler+interactivebrokershandler"),
                                                ("Kraken",  "QuantConnect", "QuantConnect"),
                                                ("Kraken", "Kraken", "Kraken"),
                                                ("Kraken", "QuantConnect + Kraken", "quantconnecthandler+krakenhandler"),
                                                ("OANDA",  "QuantConnect", "QuantConnect"),
                                                ("OANDA", "Oanda", "Oanda"),
                                                ("OANDA", "QuantConnect + Oanda", "quantconnecthandler+oandahandler"),
                                                ("Samco", "QuantConnect", "QuantConnect"),
                                                ("Samco", "Samco", "Samco"),
                                                ("Samco", "QuantConnect + Samco", "quantconnecthandler+samcohandler"),
                                                ("Tradier", "QuantConnect", "QuantConnect"),
                                                ("Tradier", "Tradier Brokerage", "TradierBrokerage"),
                                                ("Zerodha", "QuantConnect", "QuantConnect"),
                                                ("Zerodha", "Zerodha", "Zerodha"),
                                                ("Zerodha", "QuantConnect + Zerodha", "quantconnecthandler+zerodhahandler"),
                                                ("TDAmeritrade", "QuantConnect", "QuantConnect"),
                                                ("TDAmeritrade", "TDAmeritrade", "TDAmeritrade"),
                                                ("TDAmeritrade", "QuantConnect + TDAmeritrade", "quantconnecthandler+tdameritradehandler")])
def test_cloud_live_deploy_with_live_holdings(brokerage: str, datafeed: str, expected: str) -> None:
    create_fake_lean_cli_directory()

    cloud_project_manager = mock.Mock()
    container.cloud_project_manager = cloud_project_manager

    api_client = mock.Mock()
    api_client.nodes.get_all.return_value = create_qc_nodes()
    api_client.get.return_value = {'live': [], 'portfolio': {}}
    container.api_client = api_client

    cloud_runner = mock.Mock()
    container.cloud_runner = cloud_runner

    options = []
    for key, value in brokerage_required_options[brokerage].items():
        if "organization" not in key and key != "ib-enable-delayed-streaming-data":
            options.extend([f"--{key}", value])

    if brokerage == "Trading Technologies":
        options.extend(["--live-cash-balance", "USD:100"])
    elif brokerage == "Interactive Brokers":
        options.extend(["--ib-data-feed", datafeed])
    elif brokerage == "Tradier":
        options.extend(["--tradier-data-feed", datafeed])
    elif brokerage == "OANDA":
        options.extend(["--oanda-data-feed", datafeed])
    elif brokerage == "Binance":
        options.extend(["--binance-data-feed", datafeed])
    elif brokerage == "Bitfinex":
        options.extend(["--bitfinex-data-feed", datafeed])
    elif brokerage == "Coinbase Pro":
        options.extend(["--cp-data-feed", datafeed])
    elif brokerage == "Zerodha":
        options.extend(["--zerodha-data-feed", datafeed])
    elif brokerage == "Samco":
        options.extend(["--samco-data-feed", datafeed])
    elif brokerage == "Terminal Link":
        options.extend(["--tl-data-feed", datafeed])
    elif brokerage == "Kraken":
        options.extend(["--kraken-data-feed", datafeed])
    elif brokerage == "TDAmeritrade":
        options.extend(["--tdameritrade-data-feed", datafeed])

    result = CliRunner().invoke(lean, ["cloud", "live", "Python Project", "--brokerage", brokerage,
                                       "--node", "live", "--auto-restart", "yes", "--notify-order-events", "no",
                                       "--notify-insights", "no", *options])

    assert result.exit_code == 0
    assert f"Data provider: {expected}" in result.output.split("\n")

imagen
Finally, unit tests for InteractiveBrokers and Tradier brokerages were made to cover these changes.

After debugging the logs from the strategies deployed in the cloud, it
was found the configuration name used by the API to use QC + IB data
feed. Therefore, only the method which returned the data handler name
was changed.
Copy link
Member

@Martin-Molinero Martin-Molinero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 🚀

@Martin-Molinero Martin-Molinero merged commit 92e5987 into QuantConnect:master Sep 11, 2023
23 checks passed
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

Successfully merging this pull request may close these issues.

The hybrid QC-IB data feed isn't supported
2 participants