From 1cc1644945585ac9fb060c9e288151eacae9b195 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Tue, 18 Jan 2022 22:49:02 +0300 Subject: [PATCH 01/14] add skeleton --- README.md | 10 +- announcements.json | 4 + lean/commands/live.py | 40 +++++++- lean/constants.py | 3 + lean/models/brokerages/cloud/__init__.py | 4 +- lean/models/brokerages/cloud/ftxus.py | 55 +++++++++++ lean/models/brokerages/local/__init__.py | 10 +- lean/models/brokerages/local/ftxus.py | 121 +++++++++++++++++++++++ 8 files changed, 238 insertions(+), 9 deletions(-) create mode 100644 lean/models/brokerages/cloud/ftxus.py create mode 100644 lean/models/brokerages/local/ftxus.py diff --git a/README.md b/README.md index c793a5a1..6d69d3f5 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ Usage: lean cloud live [OPTIONS] PROJECT events and --notify-insights. Options: - --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Kraken|FTX] + --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Kraken|FTX|FTXUS] The brokerage to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -720,9 +720,9 @@ Options: -d, --detach Run the live deployment in a detached Docker container and return immediately --gui Enable monitoring and controlling of the deployment via the local GUI --gui-organization TEXT The name or id of the organization with the local GUI module subscription - --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Atreyu|Trading Technologies|Kraken|FTX] + --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Atreyu|Trading Technologies|Kraken|FTX|FTXUS] The brokerage to use - --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTX|IQFeed] + --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTX|FTXUSIQFeed] The data feed to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -832,6 +832,10 @@ Options: --ftx-api-key TEXT Your FTX API key --ftx-api-secret TEXT Your FTX API secret --ftx-account-tier TEXT Your FTX Account Tier + --ftxus-organization TEXT The name or id of the organization with the FTX.US module subscription + --ftxus-api-key TEXT Your FTX.US API key + --ftxus-api-secret TEXT Your FTX.US API secret + --ftxus-account-tier TEXT Your FTX.US Account Tier --release Compile C# projects in release configuration instead of debug --image TEXT The LEAN engine image to use (defaults to quantconnect/lean:latest) --update Pull the LEAN engine image before starting live trading diff --git a/announcements.json b/announcements.json index 736d39d7..a63813a5 100644 --- a/announcements.json +++ b/announcements.json @@ -1,5 +1,9 @@ { "announcements": [ + { + "date": "2022-01-26", + "message": "We've added support for FTX.US Exchange" + }, { "date": "2022-01-25", "message": "We've added support for Samco brokerage for India Market" diff --git a/lean/commands/live.py b/lean/commands/live.py index b9367982..faa6f2bd 100644 --- a/lean/commands/live.py +++ b/lean/commands/live.py @@ -38,6 +38,7 @@ from lean.models.brokerages.local.samco import SamcoBrokerage, SamcoDataFeed from lean.models.brokerages.local.kraken import KrakenBrokerage, KrakenDataFeed from lean.models.brokerages.local.ftx import FTXBrokerage, FTXDataFeed +from lean.models.brokerages.local.ftxus import FTXUSBrokerage, FTXUSDataFeed from lean.models.errors import MoreInfoError from lean.models.logger import Option @@ -65,7 +66,8 @@ "tt-order-routing-host", "tt-order-routing-port", "tt-log-fix-messages"], "KrakenBrokerage": ["kraken-api-key", "kraken-api-secret", "kraken-verification-tier"], - "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier"] + "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier"], + "FTXUSBrokerage": ["ftxus-api-key", "ftxus-api-secret", "ftxus-account-tier"] } # Data queue handler -> required configuration properties @@ -83,7 +85,8 @@ "TradingTechnologiesBrokerage": _required_brokerage_properties["TradingTechnologiesBrokerage"], "QuantConnect.ToolBox.IQFeed.IQFeedDataQueueHandler": ["iqfeed-iqconnect", "iqfeed-productName", "iqfeed-version"], "KrakenBrokerage": _required_brokerage_properties["KrakenBrokerage"], - "FTXBrokerage": _required_brokerage_properties["FTXBrokerage"] + "FTXBrokerage": _required_brokerage_properties["FTXBrokerage"], + "FTXUSBrokerage": _required_brokerage_properties["FTXUSBrokerage"] } _environment_skeleton = { @@ -591,6 +594,22 @@ def _get_default_value(key: str) -> Optional[Any]: type=str, default=lambda: _get_default_value("ftx-account-tier"), help="Your FTX Account Tier") +@click.option("--ftxus-organization", + type=str, + default=lambda: _get_default_value("job-organization-id"), + help="The name or id of the organization with the FTX.US module subscription") +@click.option("--ftxus-api-key", + type=str, + default=lambda: _get_default_value("ftxus-api-key"), + help="Your FTX.US API key") +@click.option("--ftxus-api-secret", + type=str, + default=lambda: _get_default_value("ftxus-api-secret"), + help="Your FTX.US API secret") +@click.option("--ftxus-account-tier", + type=str, + default=lambda: _get_default_value("ftxus-account-tier"), + help="Your FTX.US Account Tier") @click.option("--release", is_flag=True, default=False, @@ -690,6 +709,10 @@ def live(project: Path, ftx_api_key: Optional[str], ftx_api_secret: Optional[str], ftx_account_tier: Optional[str], + ftxus_organization: Optional[str], + ftxus_api_key: Optional[str], + ftxus_api_secret: Optional[str], + ftxus_account_tier: Optional[str], release: bool, image: Optional[str], update: bool) -> None: @@ -870,6 +893,12 @@ def live(project: Path, ftx_api_key, ftx_api_secret, ftx_account_tier) + elif brokerage == FTXUSBrokerage.get_name(): + ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) + brokerage_configurer = FTXUSBrokerage(_get_organization_id(ftxus_organization, "FTX.US"), + ftxus_api_key, + ftxus_api_secret, + ftxus_account_tier) if data_feed == InteractiveBrokersDataFeed.get_name(): ensure_options(["ib_user_name", "ib_account", "ib_password", "ib_enable_delayed_streaming_data"]) @@ -1001,6 +1030,13 @@ def live(project: Path, ftx_api_key, ftx_api_secret, ftx_account_tier)) + elif data_feed == FTXUSDataFeed.get_name(): + ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) + data_feed_configurer = FTXUSDataFeed( + FTXUSBrokerage(_get_organization_id(ftx_organization, "FTX.US"), + ftxus_api_key, + ftxus_api_secret, + ftxus_account_tier)) environment_name = "lean-cli" lean_config = lean_config_manager.get_complete_lean_config(environment_name, algorithm_file, None) diff --git a/lean/constants.py b/lean/constants.py index 4d3253aa..f499902a 100644 --- a/lean/constants.py +++ b/lean/constants.py @@ -87,6 +87,9 @@ # The product id of the FTX module FTX_PRODUCT_ID = 138 +# The product id of the FTX.US module +FTXUS_PRODUCT_ID = 138 + # The product id of the SAMCO module SAMCO_PRODUCT_ID = 173 diff --git a/lean/models/brokerages/cloud/__init__.py b/lean/models/brokerages/cloud/__init__.py index e80b5830..04e80839 100644 --- a/lean/models/brokerages/cloud/__init__.py +++ b/lean/models/brokerages/cloud/__init__.py @@ -20,6 +20,7 @@ from lean.models.brokerages.cloud.tradier import TradierBrokerage from lean.models.brokerages.cloud.kraken import KrakenBrokerage from lean.models.brokerages.cloud.ftx import FTXBrokerage +from lean.models.brokerages.cloud.ftxus import FTXUSBrokerage all_cloud_brokerages = [ PaperTradingBrokerage, @@ -30,5 +31,6 @@ CoinbaseProBrokerage, BinanceBrokerage, KrakenBrokerage, - FTXBrokerage + FTXBrokerage, + FTXUSBrokerage ] diff --git a/lean/models/brokerages/cloud/ftxus.py b/lean/models/brokerages/cloud/ftxus.py new file mode 100644 index 00000000..e71b3010 --- /dev/null +++ b/lean/models/brokerages/cloud/ftxus.py @@ -0,0 +1,55 @@ +# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. +# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Dict + +import click + +from lean.components.util.logger import Logger +from lean.models.brokerages.cloud.base import CloudBrokerage + + +class FTXUSBrokerage(CloudBrokerage): + """A CloudBrokerage implementation for FTX.US brokerage.""" + + def __init__(self, api_key: str, secret_key: str, account_tier: str) -> None: + self._api_key = api_key + self._secret_key = secret_key + self._account_tier = account_tier + + @classmethod + def get_id(cls) -> str: + return "FTXUSBrokerage" + + @classmethod + def get_name(cls) -> str: + return "FTX.US" + + @classmethod + def build(cls, logger: Logger) -> CloudBrokerage: + logger.info(""" +Create an API key by logging in and accessing the FTX.US Profile page (https://ftx.us/profile). + """.strip()) + + api_key = click.prompt("API key") + secret_key = logger.prompt_password("Secret key") + account_tier = click.prompt("Account Tier") + + return FTXUSBrokerage(api_key, secret_key, account_tier) + + def _get_settings(self) -> Dict[str, str]: + return { + "key": self._api_key, + "secret": self._secret_key, + "accountTier": self._account_tier + } diff --git a/lean/models/brokerages/local/__init__.py b/lean/models/brokerages/local/__init__.py index 30ffcd90..74a8f761 100644 --- a/lean/models/brokerages/local/__init__.py +++ b/lean/models/brokerages/local/__init__.py @@ -32,6 +32,7 @@ from lean.models.brokerages.local.samco import SamcoBrokerage, SamcoDataFeed from lean.models.brokerages.local.kraken import KrakenBrokerage, KrakenDataFeed from lean.models.brokerages.local.ftx import FTXBrokerage, FTXDataFeed +from lean.models.brokerages.local.ftxus import FTXUSBrokerage, FTXUSDataFeed from lean.models.config import LeanConfigConfigurer all_local_brokerages = [ @@ -48,7 +49,8 @@ AtreyuBrokerage, TradingTechnologiesBrokerage, KrakenBrokerage, - FTXBrokerage + FTXBrokerage, + FTXUSBrokerage ] all_local_data_feeds = [ @@ -64,7 +66,8 @@ TradingTechnologiesDataFeed, CustomDataOnlyDataFeed, KrakenDataFeed, - FTXDataFeed + FTXDataFeed, + FTXUSDataFeed ] local_brokerage_data_feeds: Dict[Type[LocalBrokerage], List[Type[LeanConfigConfigurer]]] = { @@ -81,7 +84,8 @@ AtreyuBrokerage: [x for x in all_local_data_feeds if x != CustomDataOnlyDataFeed], TradingTechnologiesBrokerage: [TradingTechnologiesDataFeed], KrakenBrokerage: [KrakenDataFeed], - FTXBrokerage: [FTXDataFeed] + FTXBrokerage: [FTXDataFeed], + FTXUSBrokerage: [FTXUSDataFeed] } if container.platform_manager().is_host_windows() or os.environ.get("__README__", "false") == "true": diff --git a/lean/models/brokerages/local/ftxus.py b/lean/models/brokerages/local/ftxus.py new file mode 100644 index 00000000..6da76fd8 --- /dev/null +++ b/lean/models/brokerages/local/ftxus.py @@ -0,0 +1,121 @@ +# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. +# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any, Dict + +import click + +from lean.components.util.logger import Logger +from lean.constants import FTXUS_PRODUCT_ID +from lean.container import container +from lean.models.brokerages.local.base import LocalBrokerage +from lean.models.config import LeanConfigConfigurer +from lean.models.logger import Option + + +class FTXUSBrokerage(LocalBrokerage): + """A LocalBrokerage implementation for the FTX.US brokerage.""" + + _is_module_installed = False + + def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: + self._api_key = api_key + self._api_secret = api_secret + self._account_tier = account_tier + self._organization_id = organization_id + + @classmethod + def get_name(cls) -> str: + return "FTX.US" + + @classmethod + def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: + api_client = container.api_client() + + organizations = api_client.organizations.get_all() + options = [Option(id=organization.id, label=organization.name) for organization in organizations] + + organization_id = logger.prompt_list( + "Select the organization with the FTX.US module subscription", + options + ) + + logger.info(""" +Create an API key by logging in and accessing the FTX.US Profile page (https://ftx.us/profile). + """.strip()) + + api_key = click.prompt("API key", cls._get_default(lean_config, "ftxus-api-key")) + api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "ftxus-api-secret")) + + account_tier = logger.prompt_list( + "Select the Account Tier", + [Option(id="Tier1", label="Tier1"), + Option(id="Tier2", label="Tier2"), + Option(id="Tier3", label="Tier3"), + Option(id="Tier4", label="Tier4"), + Option(id="Tier5", label="Tier5"), + Option(id="Tier6", label="Tier6"), + Option(id="Tier7", label="Tier7"), + Option(id="Tier8", label="Tier8"), + Option(id="Tier9", label="Tier9"), + Option(id="VIP1", label="VIP1"), + Option(id="VIP2", label="VIP2"), + Option(id="MM1", label="MM1"), + Option(id="MM2", label="MM2"), + Option(id="MM3", label="MM3")], + cls._get_default(lean_config, "ftxus-account-tier") + ) + + return FTXUSBrokerage(organization_id, api_key, api_secret, account_tier) + + def _configure_environment(self, lean_config: Dict[str, Any], environment_name: str) -> None: + self.ensure_module_installed() + + lean_config["environments"][environment_name]["live-mode-brokerage"] = "FTXUSBrokerage" + lean_config["environments"][environment_name]["transaction-handler"] = \ + "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler" + + def configure_credentials(self, lean_config: Dict[str, Any]) -> None: + lean_config["ftxus-api-key"] = self._api_key + lean_config["ftxus-api-secret"] = self._api_secret + lean_config["ftxus-account-tier"] = self._account_tier + lean_config["job-organization-id"] = self._organization_id + + self._save_properties(lean_config, ["job-organization-id", "ftxus-api-key", "ftxus-api-secret", "ftxus-account-tier"]) + + def ensure_module_installed(self) -> None: + if not self._is_module_installed: + container.module_manager().install_module(FTXUS_PRODUCT_ID, self._organization_id) + self._is_module_installed = True + +class FTXUSDataFeed(LeanConfigConfigurer): + """A LeanConfigConfigurer implementation for the FTX.US data feed.""" + + def __init__(self, brokerage: FTXUSBrokerage) -> None: + self._brokerage = brokerage + + @classmethod + def get_name(cls) -> str: + return FTXUSBrokerage.get_name() + + @classmethod + def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigurer: + return FTXUSDataFeed(FTXUSBrokerage.build(lean_config, logger)) + + def configure(self, lean_config: Dict[str, Any], environment_name: str) -> None: + self._brokerage.ensure_module_installed() + + lean_config["environments"][environment_name]["data-queue-handler"] = "FTXUSBrokerage" + lean_config["environments"][environment_name]["history-provider"] = "BrokerageHistoryProvider" + + self._brokerage.configure_credentials(lean_config) From e41805eae3c894b56e43d899fdf18475cfb25ef4 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Thu, 20 Jan 2022 22:12:21 +0300 Subject: [PATCH 02/14] re-use ftx for cloud --- lean/models/brokerages/cloud/ftx.py | 12 +++++++++-- lean/models/brokerages/cloud/ftxus.py | 30 ++++++++------------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index c38cd3a9..05896d44 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -35,16 +35,24 @@ def get_id(cls) -> str: def get_name(cls) -> str: return "FTX" + @classmethod + def get_domain(cls) -> str: + return "ftx.com" + @classmethod def build(cls, logger: Logger) -> CloudBrokerage: logger.info(""" -Create an API key by logging in and accessing the FTX Profile page (https://ftx.com/profile). - """.strip()) +Create an API key by logging in and accessing the {} Profile page (https://{}/profile). + """.format(cls.get_name(), cls.get_domain()).strip()) api_key = click.prompt("API key") secret_key = logger.prompt_password("Secret key") account_tier = click.prompt("Account Tier") + return cls.create_brokerage(api_key, secret_key, account_tier) + + @classmethod + def create_brokerage(api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: return FTXBrokerage(api_key, secret_key, account_tier) def _get_settings(self) -> Dict[str, str]: diff --git a/lean/models/brokerages/cloud/ftxus.py b/lean/models/brokerages/cloud/ftxus.py index e71b3010..cae4913d 100644 --- a/lean/models/brokerages/cloud/ftxus.py +++ b/lean/models/brokerages/cloud/ftxus.py @@ -17,15 +17,14 @@ from lean.components.util.logger import Logger from lean.models.brokerages.cloud.base import CloudBrokerage +from lean.models.brokerages.cloud.ftx import FTXBrokerage -class FTXUSBrokerage(CloudBrokerage): +class FTXUSBrokerage(FTXBrokerage): """A CloudBrokerage implementation for FTX.US brokerage.""" def __init__(self, api_key: str, secret_key: str, account_tier: str) -> None: - self._api_key = api_key - self._secret_key = secret_key - self._account_tier = account_tier + super().__init__(api_key, secret_key, account_tier) @classmethod def get_id(cls) -> str: @@ -36,20 +35,9 @@ def get_name(cls) -> str: return "FTX.US" @classmethod - def build(cls, logger: Logger) -> CloudBrokerage: - logger.info(""" -Create an API key by logging in and accessing the FTX.US Profile page (https://ftx.us/profile). - """.strip()) - - api_key = click.prompt("API key") - secret_key = logger.prompt_password("Secret key") - account_tier = click.prompt("Account Tier") - - return FTXUSBrokerage(api_key, secret_key, account_tier) - - def _get_settings(self) -> Dict[str, str]: - return { - "key": self._api_key, - "secret": self._secret_key, - "accountTier": self._account_tier - } + def get_domain(cls) -> str: + return "ftx.us" + + @classmethod + def create_brokerage(api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: + return FTXUSBrokerage(api_key, secret_key, account_tier) \ No newline at end of file From aee829134d560e48ea9eecc942b6a3eea374fb67 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Fri, 21 Jan 2022 00:26:38 +0300 Subject: [PATCH 03/14] ftx.us for local --- lean/models/brokerages/local/ftx.py | 84 +++++++++++++++++-------- lean/models/brokerages/local/ftxus.py | 88 ++++++++------------------- 2 files changed, 84 insertions(+), 88 deletions(-) diff --git a/lean/models/brokerages/local/ftx.py b/lean/models/brokerages/local/ftx.py index 107ba3d2..afe4435e 100644 --- a/lean/models/brokerages/local/ftx.py +++ b/lean/models/brokerages/local/ftx.py @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Any, Dict +from typing import Any, Dict, List import click @@ -27,6 +27,7 @@ class FTXBrokerage(LocalBrokerage): """A LocalBrokerage implementation for the FTX brokerage.""" _is_module_installed = False + def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: self._api_key = api_key @@ -38,66 +39,91 @@ def __init__(self, organization_id: str, api_key: str, api_secret: str, account_ def get_name(cls) -> str: return "FTX" + @classmethod + def get_module_id(cls) -> int: + return FTX_PRODUCT_ID + + @classmethod + def get_domain(cls) -> str: + return "ftx.com" + + @classmethod + def data_queue_handler_name(cls) -> str: + return "FTXBrokerage" + + @classmethod + def property_prefix(cls) -> str: + return "ftx" + + @classmethod + def account_tier_options(cls) -> List[Option]: + return [Option(id="Tier1", label="Tier1"), + Option(id="Tier2", label="Tier2"), + Option(id="Tier3", label="Tier3"), + Option(id="Tier4", label="Tier4"), + Option(id="Tier5", label="Tier5"), + Option(id="Tier6", label="Tier6"), + Option(id="VIP1", label="VIP1"), + Option(id="VIP2", label="VIP2"), + Option(id="VIP3", label="VIP3"), + Option(id="MM1", label="MM1"), + Option(id="MM2", label="MM2"), + Option(id="MM3", label="MM3")] + @classmethod def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: + prefix = cls.property_prefix() + api_client = container.api_client() organizations = api_client.organizations.get_all() options = [Option(id=organization.id, label=organization.name) for organization in organizations] organization_id = logger.prompt_list( - "Select the organization with the FTX module subscription", + "Select the organization with the {} module subscription".format(cls.get_name()), options ) logger.info(""" -Create an API key by logging in and accessing the FTX Profile page (https://ftx.com/profile). - """.strip()) +Create an API key by logging in and accessing the {} Profile page (https://{}/profile). + """.format(cls.get_name(), cls.get_domain()).strip()) - api_key = click.prompt("API key", cls._get_default(lean_config, "ftx-api-key")) - api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "ftx-api-secret")) + api_key = click.prompt("API key", cls._get_default(lean_config, "{prefix}-api-key")) + api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "{prefix}-api-secret")) account_tier = logger.prompt_list( "Select the Account Tier", - [Option(id="Tier1", label="Tier1"), - Option(id="Tier2", label="Tier2"), - Option(id="Tier3", label="Tier3"), - Option(id="Tier4", label="Tier4"), - Option(id="Tier5", label="Tier5"), - Option(id="Tier6", label="Tier6"), - Option(id="VIP1", label="VIP1"), - Option(id="VIP2", label="VIP2"), - Option(id="VIP3", label="VIP3"), - Option(id="MM1", label="MM1"), - Option(id="MM2", label="MM2"), - Option(id="MM3", label="MM3")], - cls._get_default(lean_config, "ftx-account-tier") + cls.account_tier_options(), + cls._get_default(lean_config, "{prefix}-account-tier") ) - return FTXBrokerage(organization_id, api_key, api_secret, account_tier) + return cls(organization_id, api_key, api_secret, account_tier) def _configure_environment(self, lean_config: Dict[str, Any], environment_name: str) -> None: self.ensure_module_installed() - lean_config["environments"][environment_name]["live-mode-brokerage"] = "FTXBrokerage" + lean_config["environments"][environment_name]["live-mode-brokerage"] = self.__class__.data_queue_handler_name() lean_config["environments"][environment_name]["transaction-handler"] = \ "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler" def configure_credentials(self, lean_config: Dict[str, Any]) -> None: - lean_config["ftx-api-key"] = self._api_key - lean_config["ftx-api-secret"] = self._api_secret - lean_config["ftx-account-tier"] = self._account_tier + prefix = self.__class__.property_prefix() + + lean_config["{prefix}-api-key"] = self._api_key + lean_config["{prefix}-api-secret"] = self._api_secret + lean_config["{prefix}-account-tier"] = self._account_tier lean_config["job-organization-id"] = self._organization_id - self._save_properties(lean_config, ["job-organization-id", "ftx-api-key", "ftx-api-secret", "ftx-account-tier"]) + self._save_properties(lean_config, ["job-organization-id", "{prefix}-api-key", "{prefix}-api-secret", "{prefix}-account-tier"]) def ensure_module_installed(self) -> None: if not self._is_module_installed: - container.module_manager().install_module(FTX_PRODUCT_ID, self._organization_id) + container.module_manager().install_module(self.__class__.get_module_id(), self._organization_id) self._is_module_installed = True class FTXDataFeed(LeanConfigConfigurer): """A LeanConfigConfigurer implementation for the FTX data feed.""" + _brokerage: Any def __init__(self, brokerage: FTXBrokerage) -> None: self._brokerage = brokerage @@ -110,10 +136,14 @@ def get_name(cls) -> str: def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigurer: return FTXDataFeed(FTXBrokerage.build(lean_config, logger)) + @classmethod + def data_queue_handler_name(cls) -> str: + return "FTXBrokerage" + def configure(self, lean_config: Dict[str, Any], environment_name: str) -> None: self._brokerage.ensure_module_installed() - lean_config["environments"][environment_name]["data-queue-handler"] = "FTXBrokerage" + lean_config["environments"][environment_name]["data-queue-handler"] = self.__class__.data_queue_handler_name() lean_config["environments"][environment_name]["history-provider"] = "BrokerageHistoryProvider" self._brokerage.configure_credentials(lean_config) diff --git a/lean/models/brokerages/local/ftxus.py b/lean/models/brokerages/local/ftxus.py index 6da76fd8..8d84ae3e 100644 --- a/lean/models/brokerages/local/ftxus.py +++ b/lean/models/brokerages/local/ftxus.py @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Any, Dict +from typing import Any, Dict, List import click @@ -19,47 +19,41 @@ from lean.constants import FTXUS_PRODUCT_ID from lean.container import container from lean.models.brokerages.local.base import LocalBrokerage +from lean.models.brokerages.local.ftx import FTXBrokerage +from lean.models.brokerages.local.ftx import FTXDataFeed from lean.models.config import LeanConfigConfigurer from lean.models.logger import Option -class FTXUSBrokerage(LocalBrokerage): +class FTXUSBrokerage(FTXBrokerage): """A LocalBrokerage implementation for the FTX.US brokerage.""" - _is_module_installed = False - def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: - self._api_key = api_key - self._api_secret = api_secret - self._account_tier = account_tier - self._organization_id = organization_id + super().__init__(organization_id, api_key, api_secret, account_tier) @classmethod def get_name(cls) -> str: return "FTX.US" @classmethod - def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: - api_client = container.api_client() - - organizations = api_client.organizations.get_all() - options = [Option(id=organization.id, label=organization.name) for organization in organizations] - - organization_id = logger.prompt_list( - "Select the organization with the FTX.US module subscription", - options - ) + def get_module_id(cls) -> int: + return FTXUS_PRODUCT_ID - logger.info(""" -Create an API key by logging in and accessing the FTX.US Profile page (https://ftx.us/profile). - """.strip()) + @classmethod + def get_domain(cls) -> str: + return "ftx.us" - api_key = click.prompt("API key", cls._get_default(lean_config, "ftxus-api-key")) - api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "ftxus-api-secret")) + @classmethod + def data_queue_handler_name(cls) -> str: + return "FTXUSBrokerage" + + @classmethod + def property_prefix(cls) -> str: + return "ftxus" - account_tier = logger.prompt_list( - "Select the Account Tier", - [Option(id="Tier1", label="Tier1"), + @classmethod + def account_tier_options(cls) -> List[Option]: + return [Option(id="Tier1", label="Tier1"), Option(id="Tier2", label="Tier2"), Option(id="Tier3", label="Tier3"), Option(id="Tier4", label="Tier4"), @@ -72,37 +66,17 @@ def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: Option(id="VIP2", label="VIP2"), Option(id="MM1", label="MM1"), Option(id="MM2", label="MM2"), - Option(id="MM3", label="MM3")], - cls._get_default(lean_config, "ftxus-account-tier") - ) - - return FTXUSBrokerage(organization_id, api_key, api_secret, account_tier) - - def _configure_environment(self, lean_config: Dict[str, Any], environment_name: str) -> None: - self.ensure_module_installed() + Option(id="MM3", label="MM3")] - lean_config["environments"][environment_name]["live-mode-brokerage"] = "FTXUSBrokerage" - lean_config["environments"][environment_name]["transaction-handler"] = \ - "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler" - - def configure_credentials(self, lean_config: Dict[str, Any]) -> None: - lean_config["ftxus-api-key"] = self._api_key - lean_config["ftxus-api-secret"] = self._api_secret - lean_config["ftxus-account-tier"] = self._account_tier - lean_config["job-organization-id"] = self._organization_id - - self._save_properties(lean_config, ["job-organization-id", "ftxus-api-key", "ftxus-api-secret", "ftxus-account-tier"]) - - def ensure_module_installed(self) -> None: - if not self._is_module_installed: - container.module_manager().install_module(FTXUS_PRODUCT_ID, self._organization_id) - self._is_module_installed = True - -class FTXUSDataFeed(LeanConfigConfigurer): +class FTXUSDataFeed(FTXDataFeed): """A LeanConfigConfigurer implementation for the FTX.US data feed.""" def __init__(self, brokerage: FTXUSBrokerage) -> None: - self._brokerage = brokerage + super().__init__(brokerage) + + @classmethod + def data_queue_handler_name(cls) -> str: + return "FTXUSBrokerage" @classmethod def get_name(cls) -> str: @@ -111,11 +85,3 @@ def get_name(cls) -> str: @classmethod def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigurer: return FTXUSDataFeed(FTXUSBrokerage.build(lean_config, logger)) - - def configure(self, lean_config: Dict[str, Any], environment_name: str) -> None: - self._brokerage.ensure_module_installed() - - lean_config["environments"][environment_name]["data-queue-handler"] = "FTXUSBrokerage" - lean_config["environments"][environment_name]["history-provider"] = "BrokerageHistoryProvider" - - self._brokerage.configure_credentials(lean_config) From fbf2945b53e7d3fecacacc4703c1aef58de5ba14 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Fri, 21 Jan 2022 16:31:40 +0300 Subject: [PATCH 04/14] Market Name should be consistent --- README.md | 8 ++++---- lean/commands/live.py | 12 ++++++------ lean/constants.py | 2 +- lean/models/brokerages/cloud/ftxus.py | 4 ++-- lean/models/brokerages/local/ftxus.py | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6d69d3f5..157c7a49 100644 --- a/README.md +++ b/README.md @@ -832,10 +832,10 @@ Options: --ftx-api-key TEXT Your FTX API key --ftx-api-secret TEXT Your FTX API secret --ftx-account-tier TEXT Your FTX Account Tier - --ftxus-organization TEXT The name or id of the organization with the FTX.US module subscription - --ftxus-api-key TEXT Your FTX.US API key - --ftxus-api-secret TEXT Your FTX.US API secret - --ftxus-account-tier TEXT Your FTX.US Account Tier + --ftxus-organization TEXT The name or id of the organization with the FTXUS module subscription + --ftxus-api-key TEXT Your FTXUS API key + --ftxus-api-secret TEXT Your FTXUS API secret + --ftxus-account-tier TEXT Your FTXUS Account Tier --release Compile C# projects in release configuration instead of debug --image TEXT The LEAN engine image to use (defaults to quantconnect/lean:latest) --update Pull the LEAN engine image before starting live trading diff --git a/lean/commands/live.py b/lean/commands/live.py index faa6f2bd..dff3882b 100644 --- a/lean/commands/live.py +++ b/lean/commands/live.py @@ -597,19 +597,19 @@ def _get_default_value(key: str) -> Optional[Any]: @click.option("--ftxus-organization", type=str, default=lambda: _get_default_value("job-organization-id"), - help="The name or id of the organization with the FTX.US module subscription") + help="The name or id of the organization with the FTXUS module subscription") @click.option("--ftxus-api-key", type=str, default=lambda: _get_default_value("ftxus-api-key"), - help="Your FTX.US API key") + help="Your FTXUS API key") @click.option("--ftxus-api-secret", type=str, default=lambda: _get_default_value("ftxus-api-secret"), - help="Your FTX.US API secret") + help="Your FTXUS API secret") @click.option("--ftxus-account-tier", type=str, default=lambda: _get_default_value("ftxus-account-tier"), - help="Your FTX.US Account Tier") + help="Your FTXUS Account Tier") @click.option("--release", is_flag=True, default=False, @@ -895,7 +895,7 @@ def live(project: Path, ftx_account_tier) elif brokerage == FTXUSBrokerage.get_name(): ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) - brokerage_configurer = FTXUSBrokerage(_get_organization_id(ftxus_organization, "FTX.US"), + brokerage_configurer = FTXUSBrokerage(_get_organization_id(ftxus_organization, "FTXUS"), ftxus_api_key, ftxus_api_secret, ftxus_account_tier) @@ -1033,7 +1033,7 @@ def live(project: Path, elif data_feed == FTXUSDataFeed.get_name(): ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) data_feed_configurer = FTXUSDataFeed( - FTXUSBrokerage(_get_organization_id(ftx_organization, "FTX.US"), + FTXUSBrokerage(_get_organization_id(ftx_organization, "FTXUS"), ftxus_api_key, ftxus_api_secret, ftxus_account_tier)) diff --git a/lean/constants.py b/lean/constants.py index f499902a..6f1860d9 100644 --- a/lean/constants.py +++ b/lean/constants.py @@ -87,7 +87,7 @@ # The product id of the FTX module FTX_PRODUCT_ID = 138 -# The product id of the FTX.US module +# The product id of the FTXUS module FTXUS_PRODUCT_ID = 138 # The product id of the SAMCO module diff --git a/lean/models/brokerages/cloud/ftxus.py b/lean/models/brokerages/cloud/ftxus.py index cae4913d..6899a282 100644 --- a/lean/models/brokerages/cloud/ftxus.py +++ b/lean/models/brokerages/cloud/ftxus.py @@ -21,7 +21,7 @@ class FTXUSBrokerage(FTXBrokerage): - """A CloudBrokerage implementation for FTX.US brokerage.""" + """A CloudBrokerage implementation for FTXUS brokerage.""" def __init__(self, api_key: str, secret_key: str, account_tier: str) -> None: super().__init__(api_key, secret_key, account_tier) @@ -32,7 +32,7 @@ def get_id(cls) -> str: @classmethod def get_name(cls) -> str: - return "FTX.US" + return "FTXUS" @classmethod def get_domain(cls) -> str: diff --git a/lean/models/brokerages/local/ftxus.py b/lean/models/brokerages/local/ftxus.py index 8d84ae3e..cdcaab2b 100644 --- a/lean/models/brokerages/local/ftxus.py +++ b/lean/models/brokerages/local/ftxus.py @@ -26,14 +26,14 @@ class FTXUSBrokerage(FTXBrokerage): - """A LocalBrokerage implementation for the FTX.US brokerage.""" + """A LocalBrokerage implementation for the FTXUS brokerage.""" def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: super().__init__(organization_id, api_key, api_secret, account_tier) @classmethod def get_name(cls) -> str: - return "FTX.US" + return "FTXUS" @classmethod def get_module_id(cls) -> int: @@ -69,7 +69,7 @@ def account_tier_options(cls) -> List[Option]: Option(id="MM3", label="MM3")] class FTXUSDataFeed(FTXDataFeed): - """A LeanConfigConfigurer implementation for the FTX.US data feed.""" + """A LeanConfigConfigurer implementation for the FTXUS data feed.""" def __init__(self, brokerage: FTXUSBrokerage) -> None: super().__init__(brokerage) From a41add0d473794de1fb4d2bbfa0428f3d4827e95 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Fri, 21 Jan 2022 22:30:02 +0300 Subject: [PATCH 05/14] add missing parameters --- lean/models/brokerages/cloud/ftx.py | 2 +- lean/models/brokerages/cloud/ftxus.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index 05896d44..afb58b05 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -52,7 +52,7 @@ def build(cls, logger: Logger) -> CloudBrokerage: return cls.create_brokerage(api_key, secret_key, account_tier) @classmethod - def create_brokerage(api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: + def create_brokerage(cls, api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: return FTXBrokerage(api_key, secret_key, account_tier) def _get_settings(self) -> Dict[str, str]: diff --git a/lean/models/brokerages/cloud/ftxus.py b/lean/models/brokerages/cloud/ftxus.py index 6899a282..a48e6c6c 100644 --- a/lean/models/brokerages/cloud/ftxus.py +++ b/lean/models/brokerages/cloud/ftxus.py @@ -39,5 +39,5 @@ def get_domain(cls) -> str: return "ftx.us" @classmethod - def create_brokerage(api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: + def create_brokerage(cls, api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: return FTXUSBrokerage(api_key, secret_key, account_tier) \ No newline at end of file From dab3a20c3ddba145c43d2062bdf6b101304eea8d Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Sat, 22 Jan 2022 00:26:23 +0300 Subject: [PATCH 06/14] fix f-string format --- lean/models/brokerages/local/ftx.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lean/models/brokerages/local/ftx.py b/lean/models/brokerages/local/ftx.py index afe4435e..a6580755 100644 --- a/lean/models/brokerages/local/ftx.py +++ b/lean/models/brokerages/local/ftx.py @@ -88,13 +88,13 @@ def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: Create an API key by logging in and accessing the {} Profile page (https://{}/profile). """.format(cls.get_name(), cls.get_domain()).strip()) - api_key = click.prompt("API key", cls._get_default(lean_config, "{prefix}-api-key")) - api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "{prefix}-api-secret")) + api_key = click.prompt("API key", cls._get_default(lean_config, f'{prefix}-api-key')) + api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, f'{prefix}-api-secret')) account_tier = logger.prompt_list( "Select the Account Tier", cls.account_tier_options(), - cls._get_default(lean_config, "{prefix}-account-tier") + cls._get_default(lean_config, f'{prefix}-account-tier') ) return cls(organization_id, api_key, api_secret, account_tier) @@ -109,12 +109,12 @@ def _configure_environment(self, lean_config: Dict[str, Any], environment_name: def configure_credentials(self, lean_config: Dict[str, Any]) -> None: prefix = self.__class__.property_prefix() - lean_config["{prefix}-api-key"] = self._api_key - lean_config["{prefix}-api-secret"] = self._api_secret - lean_config["{prefix}-account-tier"] = self._account_tier + lean_config[f'{prefix}-api-key'] = self._api_key + lean_config[f'{prefix}-api-secret'] = self._api_secret + lean_config[f'{prefix}-account-tier'] = self._account_tier lean_config["job-organization-id"] = self._organization_id - self._save_properties(lean_config, ["job-organization-id", "{prefix}-api-key", "{prefix}-api-secret", "{prefix}-account-tier"]) + self._save_properties(lean_config, ["job-organization-id", f'{prefix}-api-key', f'{prefix}-api-secret', f'{prefix}-account-tier']) def ensure_module_installed(self) -> None: if not self._is_module_installed: From c79771517fa5240f0a4daf93687aa01079ba61d4 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Mon, 24 Jan 2022 23:35:35 +0300 Subject: [PATCH 07/14] fix setting keys --- README.md | 10 ++++++++++ lean/models/brokerages/cloud/ftx.py | 3 ++- lean/models/brokerages/cloud/kraken.py | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 157c7a49..a355c703 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,16 @@ Options: --binance-api-secret TEXT Your Binance API secret --binance-environment [demo|real] The environment to run in, demo for testnet, real for the production environment + --ftx-api-key TEXT Your FTX API key + --ftx-api-secret TEXT Your FTX API secret + --ftx-account-tier TEXT Your FTX Account Tier + --ftxus-api-key TEXT Your FTXUS API key + --ftxus-api-secret TEXT Your FTXUS API secret + --ftxus-account-tier TEXT Your FTXUS Account Tier + --kraken-api-key TEXT Your Kraken API key + --kraken-api-secret TEXT Your Kraken API secret + --kraken-verification-tier TEXT + Your Kraken Verification Tier --node TEXT The name or id of the live node to run on --auto-restart BOOLEAN Whether automatic algorithm restarting must be enabled --notify-order-events BOOLEAN Whether notifications must be sent for order events diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index afb58b05..4464d579 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -59,5 +59,6 @@ def _get_settings(self) -> Dict[str, str]: return { "key": self._api_key, "secret": self._secret_key, - "accountTier": self._account_tier + "tier": self._account_tier, + "environment": "live" } diff --git a/lean/models/brokerages/cloud/kraken.py b/lean/models/brokerages/cloud/kraken.py index 82b7365e..0875900a 100644 --- a/lean/models/brokerages/cloud/kraken.py +++ b/lean/models/brokerages/cloud/kraken.py @@ -51,5 +51,6 @@ def _get_settings(self) -> Dict[str, str]: return { "key": self._api_key, "secret": self._secret_key, - "verificationTier": self._verification_tier + "verificationTier": self._verification_tier, + "environment": "live" } From 6e8aaf33142a1db0f6790b6d57f4067b1522fe26 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Tue, 25 Jan 2022 22:11:39 +0300 Subject: [PATCH 08/14] choose FTX as exchange rather than separate brokerage --- README.md | 15 +++---- lean/commands/live.py | 53 ++++++------------------ lean/constants.py | 3 -- lean/models/brokerages/cloud/__init__.py | 5 +-- lean/models/brokerages/cloud/ftx.py | 15 +++---- lean/models/brokerages/cloud/ftxus.py | 43 ------------------- lean/models/brokerages/local/__init__.py | 10 ++--- 7 files changed, 26 insertions(+), 118 deletions(-) delete mode 100644 lean/models/brokerages/cloud/ftxus.py diff --git a/README.md b/README.md index a355c703..39c8e87e 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ Usage: lean cloud live [OPTIONS] PROJECT events and --notify-insights. Options: - --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Kraken|FTX|FTXUS] + --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Kraken|FTX] The brokerage to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -234,9 +234,7 @@ Options: --ftx-api-key TEXT Your FTX API key --ftx-api-secret TEXT Your FTX API secret --ftx-account-tier TEXT Your FTX Account Tier - --ftxus-api-key TEXT Your FTXUS API key - --ftxus-api-secret TEXT Your FTXUS API secret - --ftxus-account-tier TEXT Your FTXUS Account Tier + --ftx-exchange-name TEXT Your FTX Exchange [FTX|FTX.US] --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret --kraken-verification-tier TEXT @@ -730,9 +728,9 @@ Options: -d, --detach Run the live deployment in a detached Docker container and return immediately --gui Enable monitoring and controlling of the deployment via the local GUI --gui-organization TEXT The name or id of the organization with the local GUI module subscription - --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Atreyu|Trading Technologies|Kraken|FTX|FTXUS] + --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Atreyu|Trading Technologies|Kraken|FTX] The brokerage to use - --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTX|FTXUSIQFeed] + --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTXIQFeed] The data feed to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -842,10 +840,7 @@ Options: --ftx-api-key TEXT Your FTX API key --ftx-api-secret TEXT Your FTX API secret --ftx-account-tier TEXT Your FTX Account Tier - --ftxus-organization TEXT The name or id of the organization with the FTXUS module subscription - --ftxus-api-key TEXT Your FTXUS API key - --ftxus-api-secret TEXT Your FTXUS API secret - --ftxus-account-tier TEXT Your FTXUS Account Tier + --ftx-exchange-name TEXT Your FTX Exchange [FTX|FTX.US] --release Compile C# projects in release configuration instead of debug --image TEXT The LEAN engine image to use (defaults to quantconnect/lean:latest) --update Pull the LEAN engine image before starting live trading diff --git a/lean/commands/live.py b/lean/commands/live.py index dff3882b..b5361034 100644 --- a/lean/commands/live.py +++ b/lean/commands/live.py @@ -38,7 +38,6 @@ from lean.models.brokerages.local.samco import SamcoBrokerage, SamcoDataFeed from lean.models.brokerages.local.kraken import KrakenBrokerage, KrakenDataFeed from lean.models.brokerages.local.ftx import FTXBrokerage, FTXDataFeed -from lean.models.brokerages.local.ftxus import FTXUSBrokerage, FTXUSDataFeed from lean.models.errors import MoreInfoError from lean.models.logger import Option @@ -66,8 +65,7 @@ "tt-order-routing-host", "tt-order-routing-port", "tt-log-fix-messages"], "KrakenBrokerage": ["kraken-api-key", "kraken-api-secret", "kraken-verification-tier"], - "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier"], - "FTXUSBrokerage": ["ftxus-api-key", "ftxus-api-secret", "ftxus-account-tier"] + "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier", "ftx-exchange-name"] } # Data queue handler -> required configuration properties @@ -85,8 +83,7 @@ "TradingTechnologiesBrokerage": _required_brokerage_properties["TradingTechnologiesBrokerage"], "QuantConnect.ToolBox.IQFeed.IQFeedDataQueueHandler": ["iqfeed-iqconnect", "iqfeed-productName", "iqfeed-version"], "KrakenBrokerage": _required_brokerage_properties["KrakenBrokerage"], - "FTXBrokerage": _required_brokerage_properties["FTXBrokerage"], - "FTXUSBrokerage": _required_brokerage_properties["FTXUSBrokerage"] + "FTXBrokerage": _required_brokerage_properties["FTXBrokerage"] } _environment_skeleton = { @@ -594,22 +591,10 @@ def _get_default_value(key: str) -> Optional[Any]: type=str, default=lambda: _get_default_value("ftx-account-tier"), help="Your FTX Account Tier") -@click.option("--ftxus-organization", +@click.option("--ftx-exchange-name", type=str, - default=lambda: _get_default_value("job-organization-id"), - help="The name or id of the organization with the FTXUS module subscription") -@click.option("--ftxus-api-key", - type=str, - default=lambda: _get_default_value("ftxus-api-key"), - help="Your FTXUS API key") -@click.option("--ftxus-api-secret", - type=str, - default=lambda: _get_default_value("ftxus-api-secret"), - help="Your FTXUS API secret") -@click.option("--ftxus-account-tier", - type=str, - default=lambda: _get_default_value("ftxus-account-tier"), - help="Your FTXUS Account Tier") + default=lambda: _get_default_value("ftx-exchange-name"), + help="FTX exchange name [FTX, FTXUS]") @click.option("--release", is_flag=True, default=False, @@ -709,10 +694,7 @@ def live(project: Path, ftx_api_key: Optional[str], ftx_api_secret: Optional[str], ftx_account_tier: Optional[str], - ftxus_organization: Optional[str], - ftxus_api_key: Optional[str], - ftxus_api_secret: Optional[str], - ftxus_account_tier: Optional[str], + ftx_exchange_name: Optional[str], release: bool, image: Optional[str], update: bool) -> None: @@ -888,17 +870,12 @@ def live(project: Path, kraken_api_secret, kraken_verification_tier) elif brokerage == FTXBrokerage.get_name(): - ensure_options(["ftx_api_key", "ftx_api_secret", "ftx_account_tier"]) + ensure_options(["ftx_api_key", "ftx_api_secret", "ftx_account_tier", "ftx_exchange_name"]) brokerage_configurer = FTXBrokerage(_get_organization_id(ftx_organization, "FTX"), ftx_api_key, ftx_api_secret, - ftx_account_tier) - elif brokerage == FTXUSBrokerage.get_name(): - ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) - brokerage_configurer = FTXUSBrokerage(_get_organization_id(ftxus_organization, "FTXUS"), - ftxus_api_key, - ftxus_api_secret, - ftxus_account_tier) + ftx_account_tier, + ftx_exchange_name) if data_feed == InteractiveBrokersDataFeed.get_name(): ensure_options(["ib_user_name", "ib_account", "ib_password", "ib_enable_delayed_streaming_data"]) @@ -1024,19 +1001,13 @@ def live(project: Path, kraken_api_secret, kraken_verification_tier)) elif data_feed == FTXDataFeed.get_name(): - ensure_options(["ftx_api_key", "ftx_api_secret", "ftx_account_tier"]) + ensure_options(["ftx_api_key", "ftx_api_secret", "ftx_account_tier", "ftx_echange_name"]) data_feed_configurer = FTXDataFeed( FTXBrokerage(_get_organization_id(ftx_organization, "FTX"), ftx_api_key, ftx_api_secret, - ftx_account_tier)) - elif data_feed == FTXUSDataFeed.get_name(): - ensure_options(["ftxus_api_key", "ftxus_api_secret", "ftxus_account_tier"]) - data_feed_configurer = FTXUSDataFeed( - FTXUSBrokerage(_get_organization_id(ftx_organization, "FTXUS"), - ftxus_api_key, - ftxus_api_secret, - ftxus_account_tier)) + ftx_account_tier, + ftx_exchange_name)) environment_name = "lean-cli" lean_config = lean_config_manager.get_complete_lean_config(environment_name, algorithm_file, None) diff --git a/lean/constants.py b/lean/constants.py index 6f1860d9..4d3253aa 100644 --- a/lean/constants.py +++ b/lean/constants.py @@ -87,9 +87,6 @@ # The product id of the FTX module FTX_PRODUCT_ID = 138 -# The product id of the FTXUS module -FTXUS_PRODUCT_ID = 138 - # The product id of the SAMCO module SAMCO_PRODUCT_ID = 173 diff --git a/lean/models/brokerages/cloud/__init__.py b/lean/models/brokerages/cloud/__init__.py index 04e80839..482f87e3 100644 --- a/lean/models/brokerages/cloud/__init__.py +++ b/lean/models/brokerages/cloud/__init__.py @@ -20,8 +20,6 @@ from lean.models.brokerages.cloud.tradier import TradierBrokerage from lean.models.brokerages.cloud.kraken import KrakenBrokerage from lean.models.brokerages.cloud.ftx import FTXBrokerage -from lean.models.brokerages.cloud.ftxus import FTXUSBrokerage - all_cloud_brokerages = [ PaperTradingBrokerage, InteractiveBrokersBrokerage, @@ -31,6 +29,5 @@ CoinbaseProBrokerage, BinanceBrokerage, KrakenBrokerage, - FTXBrokerage, - FTXUSBrokerage + FTXBrokerage ] diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index 4464d579..0677d1a8 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -22,10 +22,11 @@ class FTXBrokerage(CloudBrokerage): """A CloudBrokerage implementation for FTX.""" - def __init__(self, api_key: str, secret_key: str, account_tier: str) -> None: + def __init__(self, api_key: str, secret_key: str, account_tier: str, exchange_name: str) -> None: self._api_key = api_key self._secret_key = secret_key self._account_tier = account_tier + self._exchange_name = exchange_name @classmethod def get_id(cls) -> str: @@ -35,12 +36,9 @@ def get_id(cls) -> str: def get_name(cls) -> str: return "FTX" - @classmethod - def get_domain(cls) -> str: - return "ftx.com" - @classmethod def build(cls, logger: Logger) -> CloudBrokerage: + exchange_name = click.prompt("FTX Exchange [FTX|FTXUS]") logger.info(""" Create an API key by logging in and accessing the {} Profile page (https://{}/profile). """.format(cls.get_name(), cls.get_domain()).strip()) @@ -49,16 +47,13 @@ def build(cls, logger: Logger) -> CloudBrokerage: secret_key = logger.prompt_password("Secret key") account_tier = click.prompt("Account Tier") - return cls.create_brokerage(api_key, secret_key, account_tier) - - @classmethod - def create_brokerage(cls, api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: - return FTXBrokerage(api_key, secret_key, account_tier) + return FTXBrokerage(api_key, secret_key, account_tier, exchange_name) def _get_settings(self) -> Dict[str, str]: return { "key": self._api_key, "secret": self._secret_key, "tier": self._account_tier, + "exchange": self._exchange_name, "environment": "live" } diff --git a/lean/models/brokerages/cloud/ftxus.py b/lean/models/brokerages/cloud/ftxus.py deleted file mode 100644 index a48e6c6c..00000000 --- a/lean/models/brokerages/cloud/ftxus.py +++ /dev/null @@ -1,43 +0,0 @@ -# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. -# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Dict - -import click - -from lean.components.util.logger import Logger -from lean.models.brokerages.cloud.base import CloudBrokerage -from lean.models.brokerages.cloud.ftx import FTXBrokerage - - -class FTXUSBrokerage(FTXBrokerage): - """A CloudBrokerage implementation for FTXUS brokerage.""" - - def __init__(self, api_key: str, secret_key: str, account_tier: str) -> None: - super().__init__(api_key, secret_key, account_tier) - - @classmethod - def get_id(cls) -> str: - return "FTXUSBrokerage" - - @classmethod - def get_name(cls) -> str: - return "FTXUS" - - @classmethod - def get_domain(cls) -> str: - return "ftx.us" - - @classmethod - def create_brokerage(cls, api_key: str, secret_key: str, account_tier: str) -> CloudBrokerage: - return FTXUSBrokerage(api_key, secret_key, account_tier) \ No newline at end of file diff --git a/lean/models/brokerages/local/__init__.py b/lean/models/brokerages/local/__init__.py index 74a8f761..30ffcd90 100644 --- a/lean/models/brokerages/local/__init__.py +++ b/lean/models/brokerages/local/__init__.py @@ -32,7 +32,6 @@ from lean.models.brokerages.local.samco import SamcoBrokerage, SamcoDataFeed from lean.models.brokerages.local.kraken import KrakenBrokerage, KrakenDataFeed from lean.models.brokerages.local.ftx import FTXBrokerage, FTXDataFeed -from lean.models.brokerages.local.ftxus import FTXUSBrokerage, FTXUSDataFeed from lean.models.config import LeanConfigConfigurer all_local_brokerages = [ @@ -49,8 +48,7 @@ AtreyuBrokerage, TradingTechnologiesBrokerage, KrakenBrokerage, - FTXBrokerage, - FTXUSBrokerage + FTXBrokerage ] all_local_data_feeds = [ @@ -66,8 +64,7 @@ TradingTechnologiesDataFeed, CustomDataOnlyDataFeed, KrakenDataFeed, - FTXDataFeed, - FTXUSDataFeed + FTXDataFeed ] local_brokerage_data_feeds: Dict[Type[LocalBrokerage], List[Type[LeanConfigConfigurer]]] = { @@ -84,8 +81,7 @@ AtreyuBrokerage: [x for x in all_local_data_feeds if x != CustomDataOnlyDataFeed], TradingTechnologiesBrokerage: [TradingTechnologiesDataFeed], KrakenBrokerage: [KrakenDataFeed], - FTXBrokerage: [FTXDataFeed], - FTXUSBrokerage: [FTXUSDataFeed] + FTXBrokerage: [FTXDataFeed] } if container.platform_manager().is_host_windows() or os.environ.get("__README__", "false") == "true": From 3f763eb3ffb8079e7902e83bdcd732467e0c7b28 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Tue, 25 Jan 2022 23:34:55 +0300 Subject: [PATCH 09/14] cloud brokerage --- lean/models/brokerages/cloud/ftx.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index 0677d1a8..537ad59d 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -39,9 +39,11 @@ def get_name(cls) -> str: @classmethod def build(cls, logger: Logger) -> CloudBrokerage: exchange_name = click.prompt("FTX Exchange [FTX|FTXUS]") + exchange = FTXExchange() if exchange_name.casefold() == "FTX".casefold() else FTXUSExchange() + logger.info(""" Create an API key by logging in and accessing the {} Profile page (https://{}/profile). - """.format(cls.get_name(), cls.get_domain()).strip()) + """.format(exchange.get_name(), exchange.get_domain()).strip()) api_key = click.prompt("API key") secret_key = logger.prompt_password("Secret key") @@ -57,3 +59,21 @@ def _get_settings(self) -> Dict[str, str]: "exchange": self._exchange_name, "environment": "live" } + +class FTXExchange: + @classmethod + def get_name(cls) -> str: + return "FTX" + + @classmethod + def get_domain(cls) -> str: + return "ftx.com" + +class FTXUSExchange(FTXExchange): + @classmethod + def get_name(cls) -> str: + return "FTXUS" + + @classmethod + def get_domain(cls) -> str: + return "ftx.us" From 19aaa65a4208d9b2b6d34f46d87a8d9e516fbbc9 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Tue, 25 Jan 2022 23:43:56 +0300 Subject: [PATCH 10/14] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39c8e87e..443c5f61 100644 --- a/README.md +++ b/README.md @@ -730,7 +730,7 @@ Options: --gui-organization TEXT The name or id of the organization with the local GUI module subscription --brokerage [Paper Trading|Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Atreyu|Trading Technologies|Kraken|FTX] The brokerage to use - --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTXIQFeed] + --data-feed [Interactive Brokers|Tradier|OANDA|Bitfinex|Coinbase Pro|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Custom data only|Kraken|FTX|IQFeed] The data feed to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id From d95581fad539bcbf125b84ce91dadb6c57f189bb Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Tue, 25 Jan 2022 23:51:33 +0300 Subject: [PATCH 11/14] local brokerage --- lean/models/brokerages/cloud/__init__.py | 1 + lean/models/brokerages/cloud/ftx.py | 12 +-- lean/models/brokerages/local/ftx.py | 110 ++++++++++++++--------- lean/models/brokerages/local/ftxus.py | 87 ------------------ 4 files changed, 74 insertions(+), 136 deletions(-) delete mode 100644 lean/models/brokerages/local/ftxus.py diff --git a/lean/models/brokerages/cloud/__init__.py b/lean/models/brokerages/cloud/__init__.py index 482f87e3..e80b5830 100644 --- a/lean/models/brokerages/cloud/__init__.py +++ b/lean/models/brokerages/cloud/__init__.py @@ -20,6 +20,7 @@ from lean.models.brokerages.cloud.tradier import TradierBrokerage from lean.models.brokerages.cloud.kraken import KrakenBrokerage from lean.models.brokerages.cloud.ftx import FTXBrokerage + all_cloud_brokerages = [ PaperTradingBrokerage, InteractiveBrokersBrokerage, diff --git a/lean/models/brokerages/cloud/ftx.py b/lean/models/brokerages/cloud/ftx.py index 537ad59d..7b5cb8f9 100644 --- a/lean/models/brokerages/cloud/ftx.py +++ b/lean/models/brokerages/cloud/ftx.py @@ -61,19 +61,15 @@ def _get_settings(self) -> Dict[str, str]: } class FTXExchange: - @classmethod - def get_name(cls) -> str: + def get_name(self) -> str: return "FTX" - @classmethod - def get_domain(cls) -> str: + def get_domain(self) -> str: return "ftx.com" class FTXUSExchange(FTXExchange): - @classmethod - def get_name(cls) -> str: + def get_name(self) -> str: return "FTXUS" - @classmethod - def get_domain(cls) -> str: + def get_domain(self) -> str: return "ftx.us" diff --git a/lean/models/brokerages/local/ftx.py b/lean/models/brokerages/local/ftx.py index a6580755..97325675 100644 --- a/lean/models/brokerages/local/ftx.py +++ b/lean/models/brokerages/local/ftx.py @@ -22,41 +22,23 @@ from lean.models.config import LeanConfigConfigurer from lean.models.logger import Option - -class FTXBrokerage(LocalBrokerage): - """A LocalBrokerage implementation for the FTX brokerage.""" - - _is_module_installed = False - - - def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: - self._api_key = api_key - self._api_secret = api_secret - self._account_tier = account_tier - self._organization_id = organization_id - - @classmethod - def get_name(cls) -> str: +class FTXExchange: + def get_name(self) -> str: return "FTX" - @classmethod - def get_module_id(cls) -> int: - return FTX_PRODUCT_ID + def live_mode_brokerage(self) -> str: + return "FTXBrokerage" - @classmethod - def get_domain(cls) -> str: + def data_queue_handler_name(self) -> str: + return "FTXBrokerage" + + def get_domain(self) -> str: return "ftx.com" - @classmethod - def data_queue_handler_name(cls) -> str: - return "FTXBrokerage" - - @classmethod - def property_prefix(cls) -> str: + def prefix(self) -> str: return "ftx" - @classmethod - def account_tier_options(cls) -> List[Option]: + def account_tier_options(self) -> List[Option]: return [Option(id="Tier1", label="Tier1"), Option(id="Tier2", label="Tier2"), Option(id="Tier3", label="Tier3"), @@ -70,10 +52,56 @@ def account_tier_options(cls) -> List[Option]: Option(id="MM2", label="MM2"), Option(id="MM3", label="MM3")] +class FTXUSExchange(FTXExchange): + def get_name(self) -> str: + return "FTXUS" + + def live_mode_brokerage(self) -> str: + return "FTXUSBrokerage" + + def data_queue_handler_name(self) -> str: + return "FTXUSBrokerage" + + def get_domain(self) -> str: + return "ftx.us" + + def prefix(self) -> str: + return "ftxus" + + def account_tier_options(self) -> List[Option]: + return [Option(id="Tier1", label="Tier1"), + Option(id="Tier2", label="Tier2"), + Option(id="Tier3", label="Tier3"), + Option(id="Tier4", label="Tier4"), + Option(id="Tier5", label="Tier5"), + Option(id="Tier6", label="Tier6"), + Option(id="Tier7", label="Tier7"), + Option(id="Tier8", label="Tier8"), + Option(id="Tier9", label="Tier9"), + Option(id="VIP1", label="VIP1"), + Option(id="VIP2", label="VIP2"), + Option(id="MM1", label="MM1"), + Option(id="MM2", label="MM2"), + Option(id="MM3", label="MM3")] + +class FTXBrokerage(LocalBrokerage): + """A LocalBrokerage implementation for the FTX brokerage.""" + _exchange: FTXExchange + _is_module_installed = False + + def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str, exchange: FTXExchange) -> None: + self._api_key = api_key + self._api_secret = api_secret + self._account_tier = account_tier + self._organization_id = organization_id + self._exchange = exchange + @classmethod - def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: - prefix = cls.property_prefix() + def get_name(cls) -> str: + return "FTX" + @classmethod + def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: api_client = container.api_client() organizations = api_client.organizations.get_all() @@ -84,30 +112,34 @@ def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: options ) + exchange_name = click.prompt("FTX Exchange [FTX|FTXUS]") + exchange = FTXExchange() if exchange_name.casefold() == "FTX".casefold() else FTXUSExchange() + logger.info(""" Create an API key by logging in and accessing the {} Profile page (https://{}/profile). - """.format(cls.get_name(), cls.get_domain()).strip()) + """.format(exchange.get_name(), exchange.get_domain()).strip()) + prefix = exchange.prefix() api_key = click.prompt("API key", cls._get_default(lean_config, f'{prefix}-api-key')) api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, f'{prefix}-api-secret')) account_tier = logger.prompt_list( "Select the Account Tier", - cls.account_tier_options(), + exchange.account_tier_options(), cls._get_default(lean_config, f'{prefix}-account-tier') ) - return cls(organization_id, api_key, api_secret, account_tier) + return FTXBrokerage(organization_id, api_key, api_secret, account_tier, exchange) def _configure_environment(self, lean_config: Dict[str, Any], environment_name: str) -> None: self.ensure_module_installed() - lean_config["environments"][environment_name]["live-mode-brokerage"] = self.__class__.data_queue_handler_name() + lean_config["environments"][environment_name]["live-mode-brokerage"] = self._exchange.live_mode_brokerage() lean_config["environments"][environment_name]["transaction-handler"] = \ "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler" def configure_credentials(self, lean_config: Dict[str, Any]) -> None: - prefix = self.__class__.property_prefix() + prefix = self._exchange.prefix() lean_config[f'{prefix}-api-key'] = self._api_key lean_config[f'{prefix}-api-secret'] = self._api_secret @@ -118,7 +150,7 @@ def configure_credentials(self, lean_config: Dict[str, Any]) -> None: def ensure_module_installed(self) -> None: if not self._is_module_installed: - container.module_manager().install_module(self.__class__.get_module_id(), self._organization_id) + container.module_manager().install_module(FTX_PRODUCT_ID, self._organization_id) self._is_module_installed = True class FTXDataFeed(LeanConfigConfigurer): @@ -136,14 +168,10 @@ def get_name(cls) -> str: def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigurer: return FTXDataFeed(FTXBrokerage.build(lean_config, logger)) - @classmethod - def data_queue_handler_name(cls) -> str: - return "FTXBrokerage" - def configure(self, lean_config: Dict[str, Any], environment_name: str) -> None: self._brokerage.ensure_module_installed() - lean_config["environments"][environment_name]["data-queue-handler"] = self.__class__.data_queue_handler_name() + lean_config["environments"][environment_name]["data-queue-handler"] = self._brokerage._exchange.data_queue_handler_name() lean_config["environments"][environment_name]["history-provider"] = "BrokerageHistoryProvider" self._brokerage.configure_credentials(lean_config) diff --git a/lean/models/brokerages/local/ftxus.py b/lean/models/brokerages/local/ftxus.py deleted file mode 100644 index cdcaab2b..00000000 --- a/lean/models/brokerages/local/ftxus.py +++ /dev/null @@ -1,87 +0,0 @@ -# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. -# Lean CLI v1.0. Copyright 2021 QuantConnect Corporation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Any, Dict, List - -import click - -from lean.components.util.logger import Logger -from lean.constants import FTXUS_PRODUCT_ID -from lean.container import container -from lean.models.brokerages.local.base import LocalBrokerage -from lean.models.brokerages.local.ftx import FTXBrokerage -from lean.models.brokerages.local.ftx import FTXDataFeed -from lean.models.config import LeanConfigConfigurer -from lean.models.logger import Option - - -class FTXUSBrokerage(FTXBrokerage): - """A LocalBrokerage implementation for the FTXUS brokerage.""" - - def __init__(self, organization_id: str, api_key: str, api_secret: str, account_tier: str) -> None: - super().__init__(organization_id, api_key, api_secret, account_tier) - - @classmethod - def get_name(cls) -> str: - return "FTXUS" - - @classmethod - def get_module_id(cls) -> int: - return FTXUS_PRODUCT_ID - - @classmethod - def get_domain(cls) -> str: - return "ftx.us" - - @classmethod - def data_queue_handler_name(cls) -> str: - return "FTXUSBrokerage" - - @classmethod - def property_prefix(cls) -> str: - return "ftxus" - - @classmethod - def account_tier_options(cls) -> List[Option]: - return [Option(id="Tier1", label="Tier1"), - Option(id="Tier2", label="Tier2"), - Option(id="Tier3", label="Tier3"), - Option(id="Tier4", label="Tier4"), - Option(id="Tier5", label="Tier5"), - Option(id="Tier6", label="Tier6"), - Option(id="Tier7", label="Tier7"), - Option(id="Tier8", label="Tier8"), - Option(id="Tier9", label="Tier9"), - Option(id="VIP1", label="VIP1"), - Option(id="VIP2", label="VIP2"), - Option(id="MM1", label="MM1"), - Option(id="MM2", label="MM2"), - Option(id="MM3", label="MM3")] - -class FTXUSDataFeed(FTXDataFeed): - """A LeanConfigConfigurer implementation for the FTXUS data feed.""" - - def __init__(self, brokerage: FTXUSBrokerage) -> None: - super().__init__(brokerage) - - @classmethod - def data_queue_handler_name(cls) -> str: - return "FTXUSBrokerage" - - @classmethod - def get_name(cls) -> str: - return FTXUSBrokerage.get_name() - - @classmethod - def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigurer: - return FTXUSDataFeed(FTXUSBrokerage.build(lean_config, logger)) From 1d39ccb51a6bbd0b3c954a5ae4a4ec7d2148aaaf Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Wed, 26 Jan 2022 00:31:34 +0300 Subject: [PATCH 12/14] not required param --- lean/commands/live.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lean/commands/live.py b/lean/commands/live.py index b5361034..265ad676 100644 --- a/lean/commands/live.py +++ b/lean/commands/live.py @@ -65,7 +65,7 @@ "tt-order-routing-host", "tt-order-routing-port", "tt-log-fix-messages"], "KrakenBrokerage": ["kraken-api-key", "kraken-api-secret", "kraken-verification-tier"], - "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier", "ftx-exchange-name"] + "FTXBrokerage": ["ftx-api-key", "ftx-api-secret", "ftx-account-tier"] } # Data queue handler -> required configuration properties @@ -593,7 +593,6 @@ def _get_default_value(key: str) -> Optional[Any]: help="Your FTX Account Tier") @click.option("--ftx-exchange-name", type=str, - default=lambda: _get_default_value("ftx-exchange-name"), help="FTX exchange name [FTX, FTXUS]") @click.option("--release", is_flag=True, From 8767e364b586a61a7efcf70bfc111dac1f8cfda4 Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Wed, 26 Jan 2022 00:33:55 +0300 Subject: [PATCH 13/14] provide default value --- lean/models/brokerages/local/ftx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean/models/brokerages/local/ftx.py b/lean/models/brokerages/local/ftx.py index 97325675..1f754a24 100644 --- a/lean/models/brokerages/local/ftx.py +++ b/lean/models/brokerages/local/ftx.py @@ -112,7 +112,7 @@ def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage: options ) - exchange_name = click.prompt("FTX Exchange [FTX|FTXUS]") + exchange_name = click.prompt("FTX Exchange [FTX|FTXUS]", cls._get_default(lean_config, "ftx-exchange-name")) exchange = FTXExchange() if exchange_name.casefold() == "FTX".casefold() else FTXUSExchange() logger.info(""" From 541909fd381220e8c08210de6a5522fc30818dab Mon Sep 17 00:00:00 2001 From: Adalyat Nazirov Date: Wed, 26 Jan 2022 21:44:42 +0300 Subject: [PATCH 14/14] merge announcement --- announcements.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/announcements.json b/announcements.json index a63813a5..3647c57d 100644 --- a/announcements.json +++ b/announcements.json @@ -2,11 +2,7 @@ "announcements": [ { "date": "2022-01-26", - "message": "We've added support for FTX.US Exchange" - }, - { - "date": "2022-01-25", - "message": "We've added support for Samco brokerage for India Market" + "message": "We've added support for Samco brokerage for India Market and FTX.US Exchange" }, { "date": "2021-11-17",