From 5e64f59835ccc204e48498901950ce8b888a8f92 Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Fri, 13 Mar 2026 16:09:43 -0500 Subject: [PATCH 1/2] Fix readme.py: Pydantic v2 config and Click 8.2 get_metavar signature --- .github/workflows/build.yml | 8 +- README.md | 140 ++++++++++++++++----------------- lean/click.py | 2 +- lean/commands/data/download.py | 2 +- scripts/readme.py | 6 +- 5 files changed, 82 insertions(+), 76 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e59473a5..db74534d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: # Static analysis tools - name: Static Code Analysis - if: runner.os == 'Linux' && matrix.python-version != '3.8' + if: runner.os == 'Linux' run: | pip install mypy==1.19.1 flake8==7.3.0 python static_analysis.py @@ -48,6 +48,12 @@ jobs: - name: Run tests run: python -m pytest -s -rs + - name: Check README + if: runner.os == 'Linux' + run: | + python scripts/readme.py + git diff --exit-code README.md + release: runs-on: ubuntu-latest diff --git a/README.md b/README.md index 9761cf48..158826e8 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Options: -d, --detach Run the backtest in a detached Docker container and return immediately --debug [pycharm|ptvsd|debugpy|vsdbg|rider|local-platform] Enable a certain debugging method (see --help for more information) - --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -176,14 +176,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -191,7 +191,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -201,23 +201,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] + --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [Free|Value|Standard|Pro] + --thetadata-subscription-plan [free|value|standard|pro] Your ThetaData subscription price plan - --terminal-link-connection-type [DAPI|SAPI] + --terminal-link-connection-type [dapi|sapi] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -380,9 +380,9 @@ Usage: lean cloud live deploy [OPTIONS] PROJECT --notify-insights. Options: - --brokerage [Paper Trading|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] + --brokerage [paper trading|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|bybit|tradestation|alpaca|tastytrade|eze|dydx] The brokerage to use - --data-provider-live [QuantConnect|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Polygon|CoinApi|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] + --data-provider-live [quantconnect|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|polygon|coinapi|bybit|tradestation|alpaca|tastytrade|eze|dydx] The live data provider to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -400,14 +400,14 @@ Options: Whether the developer sandbox should be used --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -436,7 +436,7 @@ Options: commodities on MCX --terminal-link-server-auth-id TEXT The Auth ID of the TerminalLink server - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the SAPI server @@ -459,13 +459,13 @@ Options: The order routing sender comp id to use --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number --bybit-api-key TEXT Your Bybit API key --bybit-api-secret TEXT Your Bybit API secret - --bybit-vip-level [VIP0|VIP1|VIP2|VIP3|VIP4|VIP5|SupremeVIP|Pro1|Pro2|Pro3|Pro4|Pro5] + --bybit-vip-level [vip0|vip1|vip2|vip3|vip4|vip5|supremevip|pro1|pro2|pro3|pro4|pro5] Your Bybit VIP Level --bybit-use-testnet [live|paper] Whether the testnet should be used @@ -489,10 +489,10 @@ Options: --dydx-environment [live|paper] Whether the developer sandbox should be used --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --alpaca-api-key TEXT Your Alpaca Api Key --alpaca-api-secret TEXT Your Alpaca Api Secret @@ -693,7 +693,7 @@ Options: --parameter ... The 'parameter min max step' pairs configuring the parameters to optimize --constraint TEXT The 'statistic operator value' pairs configuring the constraints of the optimization - --node [O2-8|O4-12|O8-16] The node type to run the optimization on + --node [o2-8|o4-12|o8-16] The node type to run the optimization on --parallel-nodes INTEGER The number of nodes that may be run in parallel --name TEXT The name of the optimization (a random one is generated if not specified) --push Push local modifications to the cloud before starting the optimization @@ -899,7 +899,7 @@ Usage: lean data download [OPTIONS] https://www.quantconnect.com/datasets Options: - --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] The name of the downloader data provider. --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -910,14 +910,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -925,7 +925,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -935,23 +935,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] + --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [Free|Value|Standard|Pro] + --thetadata-subscription-plan [free|value|standard|pro] Your ThetaData subscription price plan - --terminal-link-connection-type [DAPI|SAPI] + --terminal-link-connection-type [dapi|sapi] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -985,9 +985,9 @@ Options: -y, --yes Automatically confirm payment confirmation prompts --data-type [Trade|Quote|Bulk|Universe|OpenInterest] Specify the type of historical data - --resolution [Tick|Second|Minute|Hour|Daily] + --resolution [tick|second|minute|hour|daily] Specify the resolution of the historical data - --security-type [Equity|Index|Forex|Cfd|Future|Crypto|CryptoFuture|Option|IndexOption|Commodity|FutureOption] + --security-type [equity|index|forex|cfd|future|crypto|cryptofuture|option|indexoption|commodity|futureoption] Specify the security type of the historical data --market TEXT Specify the market name for tickers (e.g., 'USA', 'NYMEX', 'Binance') (if not provided or empty the default market for the requested security type will be used) @@ -1044,11 +1044,11 @@ Options: --end [yyyyMMdd] End date for the data to generate in yyyyMMdd format (defaults to today) --symbol-count INTEGER RANGE The number of symbols to generate data for [x>=0] --tickers TEXT Comma separated list of tickers to use for generated data - --security-type [Equity|Forex|Cfd|Future|Crypto|Option] + --security-type [equity|forex|cfd|future|crypto|option] The security type to generate data for (defaults to Equity) - --resolution [Tick|Second|Minute|Hour|Daily] + --resolution [tick|second|minute|hour|daily] The resolution of the generated data (defaults to Minute) - --data-density [Dense|Sparse|VerySparse] + --data-density [dense|sparse|verysparse] The density of the generated data (defaults to Dense) --include-coarse BOOLEAN Whether coarse universe data should be generated for Equity data (defaults to True) --market TEXT The market to generate data for (defaults to standard market for the security type) @@ -1073,7 +1073,7 @@ Options: (defaults to 30.0) --option-price-engine TEXT The stochastic process, and returns new pricing engine to run calculations for that option (defaults to BaroneAdesiWhaleyApproximationEngine) - --volatility-model-resolution [Tick|Second|Minute|Hour|Daily] + --volatility-model-resolution [tick|second|minute|hour|daily] The volatility model period span (defaults to Daily) --chain-symbol-count INTEGER RANGE The size of the option chain (defaults to 10) [x>=0] @@ -1348,11 +1348,11 @@ Options: --environment TEXT The environment to use --output DIRECTORY Directory to store results in (defaults to PROJECT/live/TIMESTAMP) -d, --detach Run the live deployment in a detached Docker container and return immediately - --brokerage [Paper Trading|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] + --brokerage [paper trading|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|bybit|tradestation|alpaca|tastytrade|eze|dydx] The brokerage to use - --data-provider-live [Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|IQFeed|Polygon|CoinApi|ThetaData|Custom data only|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-live [interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|iqfeed|polygon|coinapi|thetadata|custom data only|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] The live data provider to use - --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -1370,14 +1370,14 @@ Options: Whether the developer sandbox should be used --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -1404,9 +1404,9 @@ Options: --samco-trading-segment [equity|commodity] EQUITY if you are trading equities on NSE or BSE, COMMODITY if you are trading commodities on MCX - --terminal-link-connection-type [DAPI|SAPI] + --terminal-link-connection-type [dapi|sapi] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -1442,13 +1442,13 @@ Options: --tt-log-fix-messages BOOLEAN Whether FIX messages should be logged (Optional). --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number --bybit-api-key TEXT Your Bybit API key --bybit-api-secret TEXT Your Bybit API secret - --bybit-vip-level [VIP0|VIP1|VIP2|VIP3|VIP4|VIP5|SupremeVIP|Pro1|Pro2|Pro3|Pro4|Pro5] + --bybit-vip-level [vip0|vip1|vip2|vip3|vip4|vip5|supremevip|pro1|pro2|pro3|pro4|pro5] Your Bybit VIP Level --bybit-use-testnet [live|paper] Whether the testnet should be used @@ -1483,14 +1483,14 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [Free|Value|Standard|Pro] + --thetadata-subscription-plan [free|value|standard|pro] Your ThetaData subscription price plan --trade-station-enable-delayed-streaming-data BOOLEAN Whether delayed data may be used when your algorithm subscribes to a security you @@ -1501,7 +1501,7 @@ Options: --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] + --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] Your Alpha Vantage Premium API Key plan --release Compile C# projects in release configuration instead of debug --image TEXT The LEAN engine image to use (defaults to quantconnect/lean:latest) @@ -1802,14 +1802,14 @@ Options: --output DIRECTORY Directory to store results in (defaults to PROJECT/optimizations/TIMESTAMP) -d, --detach Run the optimization in a detached Docker container and return immediately --optimizer-config FILE The optimizer configuration file that should be used - --strategy [Grid Search|Euler Search] + --strategy [grid search|euler search] The optimization strategy to use --target TEXT The target statistic of the optimization --target-direction [min|max] Whether the target must be minimized or maximized --parameter ... The 'parameter min max step' pairs configuring the parameters to optimize --constraint TEXT The 'statistic operator value' pairs configuring the constraints of the optimization - --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] Update the Lean configuration file to retrieve data from the given historical provider --download-data Update the Lean configuration file to download data from the QuantConnect API, alias for --data-provider-historical QuantConnect @@ -1833,14 +1833,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -1848,7 +1848,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -1858,23 +1858,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] + --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [Free|Value|Standard|Pro] + --thetadata-subscription-plan [free|value|standard|pro] Your ThetaData subscription price plan - --terminal-link-connection-type [DAPI|SAPI] + --terminal-link-connection-type [dapi|sapi] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -2080,7 +2080,7 @@ Usage: lean research [OPTIONS] PROJECT Options: --port INTEGER The port to run Jupyter Lab on (defaults to 8888) - --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] + --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -2091,14 +2091,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [Practice|Trade] + --oanda-environment [practice|trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] + --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -2106,7 +2106,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [Starter|Intermediate|Pro] + --kraken-verification-tier [starter|intermediate|pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -2116,23 +2116,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [Individual|Business] + --polygon-license-type [individual|business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] + --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] + --coinapi-product [free|startup|streamer|professional|enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [Free|Value|Standard|Pro] + --thetadata-subscription-plan [free|value|standard|pro] Your ThetaData subscription price plan - --terminal-link-connection-type [DAPI|SAPI] + --terminal-link-connection-type [dapi|sapi] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [Production|Beta] + --terminal-link-environment [production|beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server diff --git a/lean/click.py b/lean/click.py index 0eb4e86d..6b6592e4 100644 --- a/lean/click.py +++ b/lean/click.py @@ -352,7 +352,7 @@ class DateParameter(ParamType): name = "date" - def get_metavar(self, param: Parameter) -> str: + def get_metavar(self, param: Parameter, ctx=None) -> str: return "[yyyyMMdd]" def convert(self, value: str, param: Parameter, ctx: Context): diff --git a/lean/commands/data/download.py b/lean/commands/data/download.py index 6b21f402..1153d83b 100644 --- a/lean/commands/data/download.py +++ b/lean/commands/data/download.py @@ -501,7 +501,7 @@ def _configure_date_option(date_value: str, option_id: str, option_label: str) - class QCDataTypeCustomChoice(Choice): - def get_metavar(self, param) -> str: + def get_metavar(self, param, ctx=None) -> str: choices_str = "|".join(QCDataType.get_all_members_except('Open Interest')) # Use square braces to indicate an option or optional argument. diff --git a/scripts/readme.py b/scripts/readme.py index 61071cde..c6402247 100644 --- a/scripts/readme.py +++ b/scripts/readme.py @@ -24,6 +24,7 @@ from click import Command, Group from click.testing import CliRunner +from pydantic import ConfigDict from lean.commands import lean from lean.models.pydantic import WrappedBaseModel @@ -31,12 +32,11 @@ from lean.container import container class NamedCommand(WrappedBaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + name: str command: Command - class Config: - arbitrary_types_allowed = True - def get_commands(group: Group, parent_names: List[str] = []) -> List[NamedCommand]: """Returns all lean commands by name. From 80d3ecaf9457b4ea9dc9465c09e5dccf05d8cfac Mon Sep 17 00:00:00 2001 From: Josue Nina Date: Mon, 16 Mar 2026 19:17:59 -0500 Subject: [PATCH 2/2] Fix choice casing in CLI help text and README after Click 8+ upgrade --- README.md | 140 ++++++++++++++--------------- lean/click.py | 16 +++- lean/commands/backtest.py | 8 +- lean/commands/cloud/live/deploy.py | 8 +- lean/commands/cloud/optimize.py | 8 +- lean/commands/create_project.py | 6 +- lean/commands/data/download.py | 14 +-- lean/commands/data/generate.py | 12 +-- lean/commands/init.py | 4 +- lean/commands/live/deploy.py | 10 +-- lean/commands/optimize.py | 10 +-- lean/commands/research.py | 6 +- lean/models/click_options.py | 6 +- lean/models/configuration.py | 5 +- 14 files changed, 134 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 158826e8..9761cf48 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Options: -d, --detach Run the backtest in a detached Docker container and return immediately --debug [pycharm|ptvsd|debugpy|vsdbg|rider|local-platform] Enable a certain debugging method (see --help for more information) - --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -176,14 +176,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -191,7 +191,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -201,23 +201,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] + --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [free|value|standard|pro] + --thetadata-subscription-plan [Free|Value|Standard|Pro] Your ThetaData subscription price plan - --terminal-link-connection-type [dapi|sapi] + --terminal-link-connection-type [DAPI|SAPI] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -380,9 +380,9 @@ Usage: lean cloud live deploy [OPTIONS] PROJECT --notify-insights. Options: - --brokerage [paper trading|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|bybit|tradestation|alpaca|tastytrade|eze|dydx] + --brokerage [Paper Trading|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] The brokerage to use - --data-provider-live [quantconnect|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|polygon|coinapi|bybit|tradestation|alpaca|tastytrade|eze|dydx] + --data-provider-live [QuantConnect|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Polygon|CoinApi|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] The live data provider to use --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -400,14 +400,14 @@ Options: Whether the developer sandbox should be used --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -436,7 +436,7 @@ Options: commodities on MCX --terminal-link-server-auth-id TEXT The Auth ID of the TerminalLink server - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the SAPI server @@ -459,13 +459,13 @@ Options: The order routing sender comp id to use --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number --bybit-api-key TEXT Your Bybit API key --bybit-api-secret TEXT Your Bybit API secret - --bybit-vip-level [vip0|vip1|vip2|vip3|vip4|vip5|supremevip|pro1|pro2|pro3|pro4|pro5] + --bybit-vip-level [VIP0|VIP1|VIP2|VIP3|VIP4|VIP5|SupremeVIP|Pro1|Pro2|Pro3|Pro4|Pro5] Your Bybit VIP Level --bybit-use-testnet [live|paper] Whether the testnet should be used @@ -489,10 +489,10 @@ Options: --dydx-environment [live|paper] Whether the developer sandbox should be used --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --alpaca-api-key TEXT Your Alpaca Api Key --alpaca-api-secret TEXT Your Alpaca Api Secret @@ -693,7 +693,7 @@ Options: --parameter ... The 'parameter min max step' pairs configuring the parameters to optimize --constraint TEXT The 'statistic operator value' pairs configuring the constraints of the optimization - --node [o2-8|o4-12|o8-16] The node type to run the optimization on + --node [O2-8|O4-12|O8-16] The node type to run the optimization on --parallel-nodes INTEGER The number of nodes that may be run in parallel --name TEXT The name of the optimization (a random one is generated if not specified) --push Push local modifications to the cloud before starting the optimization @@ -899,7 +899,7 @@ Usage: lean data download [OPTIONS] https://www.quantconnect.com/datasets Options: - --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] The name of the downloader data provider. --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -910,14 +910,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -925,7 +925,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -935,23 +935,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] + --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [free|value|standard|pro] + --thetadata-subscription-plan [Free|Value|Standard|Pro] Your ThetaData subscription price plan - --terminal-link-connection-type [dapi|sapi] + --terminal-link-connection-type [DAPI|SAPI] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -985,9 +985,9 @@ Options: -y, --yes Automatically confirm payment confirmation prompts --data-type [Trade|Quote|Bulk|Universe|OpenInterest] Specify the type of historical data - --resolution [tick|second|minute|hour|daily] + --resolution [Tick|Second|Minute|Hour|Daily] Specify the resolution of the historical data - --security-type [equity|index|forex|cfd|future|crypto|cryptofuture|option|indexoption|commodity|futureoption] + --security-type [Equity|Index|Forex|Cfd|Future|Crypto|CryptoFuture|Option|IndexOption|Commodity|FutureOption] Specify the security type of the historical data --market TEXT Specify the market name for tickers (e.g., 'USA', 'NYMEX', 'Binance') (if not provided or empty the default market for the requested security type will be used) @@ -1044,11 +1044,11 @@ Options: --end [yyyyMMdd] End date for the data to generate in yyyyMMdd format (defaults to today) --symbol-count INTEGER RANGE The number of symbols to generate data for [x>=0] --tickers TEXT Comma separated list of tickers to use for generated data - --security-type [equity|forex|cfd|future|crypto|option] + --security-type [Equity|Forex|Cfd|Future|Crypto|Option] The security type to generate data for (defaults to Equity) - --resolution [tick|second|minute|hour|daily] + --resolution [Tick|Second|Minute|Hour|Daily] The resolution of the generated data (defaults to Minute) - --data-density [dense|sparse|verysparse] + --data-density [Dense|Sparse|VerySparse] The density of the generated data (defaults to Dense) --include-coarse BOOLEAN Whether coarse universe data should be generated for Equity data (defaults to True) --market TEXT The market to generate data for (defaults to standard market for the security type) @@ -1073,7 +1073,7 @@ Options: (defaults to 30.0) --option-price-engine TEXT The stochastic process, and returns new pricing engine to run calculations for that option (defaults to BaroneAdesiWhaleyApproximationEngine) - --volatility-model-resolution [tick|second|minute|hour|daily] + --volatility-model-resolution [Tick|Second|Minute|Hour|Daily] The volatility model period span (defaults to Daily) --chain-symbol-count INTEGER RANGE The size of the option chain (defaults to 10) [x>=0] @@ -1348,11 +1348,11 @@ Options: --environment TEXT The environment to use --output DIRECTORY Directory to store results in (defaults to PROJECT/live/TIMESTAMP) -d, --detach Run the live deployment in a detached Docker container and return immediately - --brokerage [paper trading|interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|bybit|tradestation|alpaca|tastytrade|eze|dydx] + --brokerage [Paper Trading|Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX] The brokerage to use - --data-provider-live [interactive brokers|tradier|oanda|bitfinex|coinbase advanced trade|binance|zerodha|samco|terminal link|trading technologies|kraken|charlesschwab|iqfeed|polygon|coinapi|thetadata|custom data only|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-live [Interactive Brokers|Tradier|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Zerodha|Samco|Terminal Link|Trading Technologies|Kraken|CharlesSchwab|IQFeed|Polygon|CoinApi|ThetaData|Custom data only|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] The live data provider to use - --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -1370,14 +1370,14 @@ Options: Whether the developer sandbox should be used --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -1404,9 +1404,9 @@ Options: --samco-trading-segment [equity|commodity] EQUITY if you are trading equities on NSE or BSE, COMMODITY if you are trading commodities on MCX - --terminal-link-connection-type [dapi|sapi] + --terminal-link-connection-type [DAPI|SAPI] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -1442,13 +1442,13 @@ Options: --tt-log-fix-messages BOOLEAN Whether FIX messages should be logged (Optional). --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number --bybit-api-key TEXT Your Bybit API key --bybit-api-secret TEXT Your Bybit API secret - --bybit-vip-level [vip0|vip1|vip2|vip3|vip4|vip5|supremevip|pro1|pro2|pro3|pro4|pro5] + --bybit-vip-level [VIP0|VIP1|VIP2|VIP3|VIP4|VIP5|SupremeVIP|Pro1|Pro2|Pro3|Pro4|Pro5] Your Bybit VIP Level --bybit-use-testnet [live|paper] Whether the testnet should be used @@ -1483,14 +1483,14 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [free|value|standard|pro] + --thetadata-subscription-plan [Free|Value|Standard|Pro] Your ThetaData subscription price plan --trade-station-enable-delayed-streaming-data BOOLEAN Whether delayed data may be used when your algorithm subscribes to a security you @@ -1501,7 +1501,7 @@ Options: --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] + --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] Your Alpha Vantage Premium API Key plan --release Compile C# projects in release configuration instead of debug --image TEXT The LEAN engine image to use (defaults to quantconnect/lean:latest) @@ -1802,14 +1802,14 @@ Options: --output DIRECTORY Directory to store results in (defaults to PROJECT/optimizations/TIMESTAMP) -d, --detach Run the optimization in a detached Docker container and return immediately --optimizer-config FILE The optimizer configuration file that should be used - --strategy [grid search|euler search] + --strategy [Grid Search|Euler Search] The optimization strategy to use --target TEXT The target statistic of the optimization --target-direction [min|max] Whether the target must be minimized or maximized --parameter ... The 'parameter min max step' pairs configuring the parameters to optimize --constraint TEXT The 'statistic operator value' pairs configuring the constraints of the optimization - --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] Update the Lean configuration file to retrieve data from the given historical provider --download-data Update the Lean configuration file to download data from the QuantConnect API, alias for --data-provider-historical QuantConnect @@ -1833,14 +1833,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -1848,7 +1848,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -1858,23 +1858,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] + --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [free|value|standard|pro] + --thetadata-subscription-plan [Free|Value|Standard|Pro] Your ThetaData subscription price plan - --terminal-link-connection-type [dapi|sapi] + --terminal-link-connection-type [DAPI|SAPI] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server @@ -2080,7 +2080,7 @@ Usage: lean research [OPTIONS] PROJECT Options: --port INTEGER The port to run Jupyter Lab on (defaults to 8888) - --data-provider-historical [interactive brokers|oanda|bitfinex|coinbase advanced trade|binance|kraken|charlesschwab|iqfeed|polygon|factset|alphavantage|coinapi|thetadata|quantconnect|local|terminal link|bybit|tradestation|alpaca|tastytrade|eze|dydx|databento] + --data-provider-historical [Interactive Brokers|Oanda|Bitfinex|Coinbase Advanced Trade|Binance|Kraken|CharlesSchwab|IQFeed|Polygon|FactSet|AlphaVantage|CoinApi|ThetaData|QuantConnect|Local|Terminal Link|Bybit|TradeStation|Alpaca|Tastytrade|Eze|dYdX|DataBento] Update the Lean configuration file to retrieve data from the given historical provider --ib-user-name TEXT Your Interactive Brokers username --ib-account TEXT Your Interactive Brokers account id @@ -2091,14 +2091,14 @@ Options: Use this option explicitly to override the default value. (Optional). --oanda-account-id TEXT Your OANDA account id --oanda-access-token TEXT Your OANDA API token - --oanda-environment [practice|trade] + --oanda-environment [Practice|Trade] The environment to run in, Practice for fxTrade Practice, Trade for fxTrade --bitfinex-api-key TEXT Your Bitfinex API key --bitfinex-api-secret TEXT Your Bitfinex API secret --coinbase-api-name TEXT Your Coinbase Advanced Trade API name from file. --coinbase-api-private-key TEXT Your Coinbase Advanced Trade API private key from file. - --binance-exchange-name [binance|binanceus|binance-usdm-futures|binance-coin-futures] + --binance-exchange-name [Binance|BinanceUS|Binance-USDM-Futures|Binance-COIN-Futures] Binance exchange name [Binance, BinanceUS, Binance-USDM-Futures, Binance-COIN-Futures] --binance-api-key TEXT Your Binance API key --binanceus-api-key TEXT Your Binance API key @@ -2106,7 +2106,7 @@ Options: --binanceus-api-secret TEXT Your Binance API secret --kraken-api-key TEXT Your Kraken API key --kraken-api-secret TEXT Your Kraken API secret - --kraken-verification-tier [starter|intermediate|pro] + --kraken-verification-tier [Starter|Intermediate|Pro] Your Kraken Verification Tier --charles-schwab-account-number TEXT The CharlesSchwab account number @@ -2116,23 +2116,23 @@ Options: --iqfeed-version TEXT The product version of your IQFeed developer account --iqfeed-host TEXT The IQFeed host address (Optional). --polygon-api-key TEXT Your Polygon.io API Key - --polygon-license-type [individual|business] + --polygon-license-type [Individual|Business] Select your Polygon.io subscription plan (Optional). --factset-auth-config-file FILE The path to the FactSet authentication configuration file --alpha-vantage-api-key TEXT Your Alpha Vantage Api Key - --alpha-vantage-price-plan [free|plan30|plan75|plan150|plan300|plan600|plan1200] + --alpha-vantage-price-plan [Free|Plan30|Plan75|Plan150|Plan300|Plan600|Plan1200] Your Alpha Vantage Premium API Key plan --coinapi-api-key TEXT Your coinapi.io Api Key - --coinapi-product [free|startup|streamer|professional|enterprise] + --coinapi-product [Free|Startup|Streamer|Professional|Enterprise] CoinApi pricing plan (https://www.coinapi.io/market-data-api/pricing) --thetadata-ws-url TEXT The ThetaData host address (Optional). --thetadata-rest-url TEXT The ThetaData host address (Optional). - --thetadata-subscription-plan [free|value|standard|pro] + --thetadata-subscription-plan [Free|Value|Standard|Pro] Your ThetaData subscription price plan - --terminal-link-connection-type [dapi|sapi] + --terminal-link-connection-type [DAPI|SAPI] Terminal Link Connection Type [DAPI, SAPI] - --terminal-link-environment [production|beta] + --terminal-link-environment [Production|Beta] The environment to run in --terminal-link-server-host TEXT The host of the TerminalLink server diff --git a/lean/click.py b/lean/click.py index 6b6592e4..128c3040 100644 --- a/lean/click.py +++ b/lean/click.py @@ -14,7 +14,7 @@ from pathlib import Path from typing import Optional, List, Callable -from click import Command, Context, Parameter, ParamType, Option as ClickOption +from click import Choice, Command, Context, Parameter, ParamType, Option as ClickOption from click.decorators import FC, option from lean.constants import DEFAULT_LEAN_CONFIG_FILE_NAME, CONTAINER_LABEL_LEAN_VERSION_NAME @@ -305,6 +305,20 @@ def _parse_config_option(self, ctx: Context, param: Parameter, value: Optional[P +class CaseInsensitiveChoice(Choice): + """A click.Choice subclass that matches case-insensitively but displays original casing in help text.""" + + def __init__(self, choices, **kwargs): + super().__init__(choices, case_sensitive=False, **kwargs) + + def get_metavar(self, param, ctx=None) -> str: + import enum + choices_str = "|".join(c.value if isinstance(c, enum.Enum) else str(c) for c in self.choices) + if param is not None and param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + return f"[{choices_str}]" + + class PathParameter(ParamType): """A limited version of click.Path which uses pathlib.Path.""" diff --git a/lean/commands/backtest.py b/lean/commands/backtest.py index 98d6fb3e..bf9a8cac 100644 --- a/lean/commands/backtest.py +++ b/lean/commands/backtest.py @@ -13,9 +13,9 @@ from pathlib import Path from typing import List, Optional, Tuple -from click import command, option, argument, Choice +from click import command, option, argument -from lean.click import LeanCommand, PathParameter, backtest_parameter_option +from lean.click import LeanCommand, PathParameter, backtest_parameter_option, CaseInsensitiveChoice from lean.constants import DEFAULT_ENGINE_IMAGE, LEAN_ROOT_PATH from lean.container import container, Logger from lean.models.utils import DebuggingMethod @@ -234,10 +234,10 @@ def _migrate_csharp_csproj(project_dir: Path) -> None: default=False, help="Run the backtest in a detached Docker container and return immediately") @option("--debug", - type=Choice(["pycharm", "ptvsd", "debugpy", "vsdbg", "rider", "local-platform"], case_sensitive=False), + type=CaseInsensitiveChoice(["pycharm", "ptvsd", "debugpy", "vsdbg", "rider", "local-platform"]), help="Enable a certain debugging method (see --help for more information)") @option("--data-provider-historical", - type=Choice([dp.get_name() for dp in cli_data_downloaders], case_sensitive=False), + type=CaseInsensitiveChoice([dp.get_name() for dp in cli_data_downloaders]), default="Local", help="Update the Lean configuration file to retrieve data from the given historical provider") @options_from_json(get_configs_for_options("backtest")) diff --git a/lean/commands/cloud/live/deploy.py b/lean/commands/cloud/live/deploy.py index 1fee429c..c667ae40 100644 --- a/lean/commands/cloud/live/deploy.py +++ b/lean/commands/cloud/live/deploy.py @@ -12,8 +12,8 @@ # limitations under the License. from typing import List, Tuple, Optional -from click import prompt, option, argument, Choice, confirm -from lean.click import LeanCommand, ensure_options +from click import prompt, option, argument, confirm +from lean.click import LeanCommand, ensure_options, CaseInsensitiveChoice from lean.components.api.api_client import APIClient from lean.components.util.json_modules_handler import non_interactive_config_build_for_name, \ interactive_config_build @@ -166,10 +166,10 @@ def _configure_auto_restart(logger: Logger) -> bool: @live.command(cls=LeanCommand, default_command=True, name="deploy") @argument("project", type=str) @option("--brokerage", - type=Choice([b.get_name() for b in cloud_brokerages], case_sensitive=False), + type=CaseInsensitiveChoice([b.get_name() for b in cloud_brokerages]), help="The brokerage to use") @option("--data-provider-live", - type=Choice([d.get_name() for d in cloud_data_queue_handlers], case_sensitive=False), + type=CaseInsensitiveChoice([d.get_name() for d in cloud_data_queue_handlers]), multiple=True, help="The live data provider to use") @options_from_json(get_configs_for_options("live-cloud")) diff --git a/lean/commands/cloud/optimize.py b/lean/commands/cloud/optimize.py index d66334ae..cc7efeea 100644 --- a/lean/commands/cloud/optimize.py +++ b/lean/commands/cloud/optimize.py @@ -13,9 +13,9 @@ from typing import List, Optional, Tuple -from click import command, option, Choice, argument, confirm +from click import command, option, argument, confirm -from lean.click import LeanCommand, ensure_options +from lean.click import LeanCommand, ensure_options, CaseInsensitiveChoice from lean.components.config.optimizer_config_manager import NodeType, available_nodes from lean.container import container from lean.models.api import QCOptimizationBacktest, QCProject, QCCompileWithLogs, QCFullOrganization @@ -156,7 +156,7 @@ def _display_estimate(cloud_project: QCProject, type=str, help="The target statistic of the optimization") @option("--target-direction", - type=Choice(["min", "max"], case_sensitive=False), + type=CaseInsensitiveChoice(["min", "max"]), help="Whether the target must be minimized or maximized") @option("--parameter", type=(str, float, float, float), @@ -167,7 +167,7 @@ def _display_estimate(cloud_project: QCProject, multiple=True, help="The 'statistic operator value' pairs configuring the constraints of the optimization") @option("--node", - type=Choice([node.name for node in available_nodes], case_sensitive=False), + type=CaseInsensitiveChoice([node.name for node in available_nodes]), help="The node type to run the optimization on") @option("--parallel-nodes", type=int, diff --git a/lean/commands/create_project.py b/lean/commands/create_project.py index 2bd9e9bd..6f2d5d4d 100644 --- a/lean/commands/create_project.py +++ b/lean/commands/create_project.py @@ -12,9 +12,9 @@ # limitations under the License. from pathlib import Path -from click import Choice, option, argument +from click import option, argument -from lean.click import LeanCommand +from lean.click import LeanCommand, CaseInsensitiveChoice from lean.commands import lean from lean.container import container from lean.models.api import QCLanguage @@ -398,7 +398,7 @@ def _not_identifier_char(text): @lean.command(cls=LeanCommand, name="project-create", aliases=["create-project"]) @argument("name", type=str) @option("--language", "-l", - type=Choice(container.cli_config_manager.default_language.allowed_values, case_sensitive=False), + type=CaseInsensitiveChoice(container.cli_config_manager.default_language.allowed_values), help="The language of the project to create") def create_project(name: str, language: str) -> None: """Create a new project containing starter code. diff --git a/lean/commands/data/download.py b/lean/commands/data/download.py index 1153d83b..1657acc2 100644 --- a/lean/commands/data/download.py +++ b/lean/commands/data/download.py @@ -15,8 +15,8 @@ from docker.types import Mount from typing import Any, Dict, Iterable, List, Optional -from click import command, option, confirm, pass_context, Context, Choice, prompt -from lean.click import LeanCommand, ensure_options +from click import command, option, confirm, pass_context, Context, prompt +from lean.click import LeanCommand, ensure_options, CaseInsensitiveChoice from lean.components.util.json_modules_handler import config_build_for_name from lean.constants import DEFAULT_ENGINE_IMAGE from lean.container import container @@ -500,7 +500,7 @@ def _configure_date_option(date_value: str, option_id: str, option_label: str) - return date_option.configure_non_interactive(date_value) -class QCDataTypeCustomChoice(Choice): +class QCDataTypeCustomChoice(CaseInsensitiveChoice): def get_metavar(self, param, ctx=None) -> str: choices_str = "|".join(QCDataType.get_all_members_except('Open Interest')) @@ -521,7 +521,7 @@ def _replace_data_type(ctx, param, value): @command(cls=LeanCommand, requires_lean_config=True, allow_unknown_options=True, name="download") @option("--data-provider-historical", - type=Choice([data_downloader.get_name() for data_downloader in cli_data_downloaders], case_sensitive=False), + type=CaseInsensitiveChoice([data_downloader.get_name() for data_downloader in cli_data_downloaders]), help="The name of the downloader data provider.") @options_from_json(get_configs_for_options("download")) @option("--dataset", type=str, help="The name of the dataset to download non-interactively") @@ -530,11 +530,11 @@ def _replace_data_type(ctx, param, value): @option("--yes", "-y", "auto_confirm", is_flag=True, default=False, help="Automatically confirm payment confirmation prompts") @option("--data-type", callback=_replace_data_type, - type=QCDataTypeCustomChoice(QCDataType.get_all_members(), case_sensitive=False), + type=QCDataTypeCustomChoice(QCDataType.get_all_members()), help="Specify the type of historical data") -@option("--resolution", type=Choice(QCResolution.get_all_members(), case_sensitive=False), +@option("--resolution", type=CaseInsensitiveChoice(QCResolution.get_all_members()), help="Specify the resolution of the historical data") -@option("--security-type", type=Choice(QCSecurityType.get_all_members(), case_sensitive=False), +@option("--security-type", type=CaseInsensitiveChoice(QCSecurityType.get_all_members()), help="Specify the security type of the historical data") @option("--market", type=str, help="Specify the market name for tickers (e.g., 'USA', 'NYMEX', 'Binance')" diff --git a/lean/commands/data/generate.py b/lean/commands/data/generate.py index 86a4b66d..3346f4f4 100644 --- a/lean/commands/data/generate.py +++ b/lean/commands/data/generate.py @@ -14,9 +14,9 @@ from datetime import datetime from typing import Optional -from click import command, option, Choice, IntRange +from click import command, option, IntRange -from lean.click import DateParameter, LeanCommand, ensure_options +from lean.click import DateParameter, LeanCommand, ensure_options, CaseInsensitiveChoice from lean.constants import DEFAULT_ENGINE_IMAGE from lean.container import container @@ -39,15 +39,15 @@ default="", help="Comma separated list of tickers to use for generated data") @option("--security-type", - type=Choice(["Equity", "Forex", "Cfd", "Future", "Crypto", "Option"], case_sensitive=False), + type=CaseInsensitiveChoice(["Equity", "Forex", "Cfd", "Future", "Crypto", "Option"]), default="Equity", help="The security type to generate data for (defaults to Equity)") @option("--resolution", - type=Choice(["Tick", "Second", "Minute", "Hour", "Daily"], case_sensitive=False), + type=CaseInsensitiveChoice(["Tick", "Second", "Minute", "Hour", "Daily"]), default="Minute", help="The resolution of the generated data (defaults to Minute)") @option("--data-density", - type=Choice(["Dense", "Sparse", "VerySparse"], case_sensitive=False), + type=CaseInsensitiveChoice(["Dense", "Sparse", "VerySparse"]), default="Dense", help="The density of the generated data (defaults to Dense)") @option("--include-coarse", @@ -98,7 +98,7 @@ help="The stochastic process, and returns new pricing engine to run calculations for that option " "(defaults to BaroneAdesiWhaleyApproximationEngine)") @option("--volatility-model-resolution", - type=Choice(["Tick", "Second", "Minute", "Hour", "Daily"], case_sensitive=False), + type=CaseInsensitiveChoice(["Tick", "Second", "Minute", "Hour", "Daily"]), default="Daily", help="The volatility model period span (defaults to Daily)") @option("--chain-symbol-count", diff --git a/lean/commands/init.py b/lean/commands/init.py index 89dd4a76..461d0dc3 100644 --- a/lean/commands/init.py +++ b/lean/commands/init.py @@ -16,7 +16,7 @@ from click import command, option, Choice, confirm, prompt -from lean.click import LeanCommand +from lean.click import LeanCommand, CaseInsensitiveChoice from lean.commands.login import get_credentials, validate_credentials, get_lean_config_credentials from lean.constants import DEFAULT_DATA_DIRECTORY_NAME, DEFAULT_LEAN_CONFIG_FILE_NAME from lean.container import container @@ -121,7 +121,7 @@ def _download_repository(output_path: Path) -> None: @command(cls=LeanCommand) @option("--organization", type=str, help="The name or id of the organization the Lean CLI will be scaffolded for") @option("--language", "-l", - type=Choice(container.cli_config_manager.default_language.allowed_values, case_sensitive=False), + type=CaseInsensitiveChoice(container.cli_config_manager.default_language.allowed_values), help="The default language to use for new projects") def init(organization: Optional[str], language: Optional[str]) -> None: """Scaffold a Lean configuration file and data directory.""" diff --git a/lean/commands/live/deploy.py b/lean/commands/live/deploy.py index be7e8867..bd2efd8c 100644 --- a/lean/commands/live/deploy.py +++ b/lean/commands/live/deploy.py @@ -13,8 +13,8 @@ from pathlib import Path from typing import List, Optional, Tuple -from click import option, argument, Choice -from lean.click import LeanCommand, PathParameter +from click import option, argument +from lean.click import LeanCommand, PathParameter, CaseInsensitiveChoice from lean.components.util.name_rename import rename_internal_config_to_user_friendly_format from lean.constants import DEFAULT_ENGINE_IMAGE from lean.container import container @@ -64,14 +64,14 @@ def _get_history_provider_name(data_provider_live_names: [str]) -> [str]: default=False, help="Run the live deployment in a detached Docker container and return immediately") @option("--brokerage", - type=Choice([b.get_name() for b in cli_brokerages], case_sensitive=False), + type=CaseInsensitiveChoice([b.get_name() for b in cli_brokerages]), help="The brokerage to use") @option("--data-provider-live", - type=Choice([d.get_name() for d in cli_data_queue_handlers], case_sensitive=False), + type=CaseInsensitiveChoice([d.get_name() for d in cli_data_queue_handlers]), multiple=True, help="The live data provider to use") @option("--data-provider-historical", - type=Choice([dp.get_name() for dp in cli_data_downloaders if dp.get_id() != "TerminalLinkBrokerage"], case_sensitive=False), + type=CaseInsensitiveChoice([dp.get_name() for dp in cli_data_downloaders if dp.get_id() != "TerminalLinkBrokerage"]), help="Update the Lean configuration file to retrieve data from the given historical provider") @options_from_json(get_configs_for_options("live-cli")) @option("--release", diff --git a/lean/commands/optimize.py b/lean/commands/optimize.py index 3e659082..7e63e67e 100644 --- a/lean/commands/optimize.py +++ b/lean/commands/optimize.py @@ -15,9 +15,9 @@ from typing import Optional, List, Tuple from datetime import datetime, timedelta -from click import command, argument, option, Choice, IntRange +from click import command, argument, option, IntRange -from lean.click import LeanCommand, PathParameter, ensure_options +from lean.click import LeanCommand, PathParameter, ensure_options, CaseInsensitiveChoice from lean.components.docker.lean_runner import LeanRunner from lean.constants import DEFAULT_ENGINE_IMAGE from lean.container import container @@ -81,13 +81,13 @@ def get_filename_timestamp(path: Path) -> datetime: type=PathParameter(exists=True, file_okay=True, dir_okay=False), help=f"The optimizer configuration file that should be used") @option("--strategy", - type=Choice(["Grid Search", "Euler Search"], case_sensitive=False), + type=CaseInsensitiveChoice(["Grid Search", "Euler Search"]), help="The optimization strategy to use") @option("--target", type=str, help="The target statistic of the optimization") @option("--target-direction", - type=Choice(["min", "max"], case_sensitive=False), + type=CaseInsensitiveChoice(["min", "max"]), help="Whether the target must be minimized or maximized") @option("--parameter", type=(str, float, float, float), @@ -98,7 +98,7 @@ def get_filename_timestamp(path: Path) -> datetime: multiple=True, help="The 'statistic operator value' pairs configuring the constraints of the optimization") @option("--data-provider-historical", - type=Choice([dp.get_name() for dp in cli_data_downloaders], case_sensitive=False), + type=CaseInsensitiveChoice([dp.get_name() for dp in cli_data_downloaders]), default="Local", help="Update the Lean configuration file to retrieve data from the given historical provider") @option("--download-data", diff --git a/lean/commands/research.py b/lean/commands/research.py index 018c618c..49480205 100644 --- a/lean/commands/research.py +++ b/lean/commands/research.py @@ -13,8 +13,8 @@ from pathlib import Path from typing import Optional, Tuple -from click import command, argument, option, Choice -from lean.click import LeanCommand, PathParameter +from click import command, argument, option +from lean.click import LeanCommand, PathParameter, CaseInsensitiveChoice from lean.components.docker.lean_runner import LeanRunner from lean.constants import DEFAULT_RESEARCH_IMAGE, LEAN_ROOT_PATH from lean.container import container @@ -38,7 +38,7 @@ def _check_docker_output(chunk: str, port: int) -> None: @argument("project", type=PathParameter(exists=True, file_okay=False, dir_okay=True)) @option("--port", type=int, default=8888, help="The port to run Jupyter Lab on (defaults to 8888)") @option("--data-provider-historical", - type=Choice([dp.get_name() for dp in cli_data_downloaders], case_sensitive=False), + type=CaseInsensitiveChoice([dp.get_name() for dp in cli_data_downloaders]), default="Local", help="Update the Lean configuration file to retrieve data from the given historical provider") @options_from_json(get_configs_for_options("research")) diff --git a/lean/models/click_options.py b/lean/models/click_options.py index 65526334..5531395c 100644 --- a/lean/models/click_options.py +++ b/lean/models/click_options.py @@ -13,8 +13,8 @@ from typing import List, Dict -from click import option, Choice -from lean.click import PathParameter +from click import option +from lean.click import PathParameter, CaseInsensitiveChoice from lean.models.cli import cli_brokerages, cli_data_downloaders, cli_data_queue_handlers from lean.models.cloud import cloud_brokerages, cloud_data_queue_handlers from lean.models.configuration import Configuration, InfoConfiguration, InternalInputUserInput @@ -59,7 +59,7 @@ def get_click_option_type(configuration: Configuration): # Skip validation if no predefined choices in config and user provided input manually if not configuration._choices: return str - return Choice(configuration._choices, case_sensitive=False) + return CaseInsensitiveChoice(configuration._choices) elif configuration._input_method == "prompt": return configuration.get_input_type() elif configuration._input_method == "prompt-password": diff --git a/lean/models/configuration.py b/lean/models/configuration.py index 67b79e05..e7a61e27 100644 --- a/lean/models/configuration.py +++ b/lean/models/configuration.py @@ -13,7 +13,8 @@ from pathlib import Path from typing import Any, Dict, List -from click import prompt, Choice +from click import prompt +from lean.click import CaseInsensitiveChoice from abc import ABC, abstractmethod from lean.components.util.logger import Logger from lean.click import PathParameter @@ -294,7 +295,7 @@ def ask_user_for_input(self, default_value, logger: Logger, hide_input: bool = F return prompt( self._prompt_info, default_value, - type=Choice(self._choices, case_sensitive=False) + type=CaseInsensitiveChoice(self._choices) )