diff --git a/single-page/Quantconnect-Cloud-Platform.html b/single-page/Quantconnect-Cloud-Platform.html index c771a78b22..cc3da0aeeb 100644 --- a/single-page/Quantconnect-Cloud-Platform.html +++ b/single-page/Quantconnect-Cloud-Platform.html @@ -142,94 +142,111 @@
@@ -565,7 +582,11 @@
Physical access to our servers is limited to a few dedicated team members whom QuantConnect has vetted. Only those credentialed team members can access the physical servers, and we schedule all work in advance. - Work on the servers is always done in pairs to prevent single rogue actors from accessing the servers. We host our servers in a world-class security facility (Equinix) with security staff 24/7. + Work on the servers is always done in pairs to prevent single rogue actors from accessing the servers. We host our servers in a world-class security facility, on co-located servers racked in + + Equinix + + , with security staff 24/7.
- Live trading nodes enable you to deploy live algorithms to our professionally-managed, co-located servers. + Live trading nodes enable you to deploy live algorithms to our professionally-managed, co-located servers racked in + + Equinix + + . You need a live trading node for each algorithm that you deploy to our co-located servers. Several models of live trading nodes are available. More powerful live trading nodes allow you to run algorithms with larger universes and give you @@ -1639,6 +1664,133 @@
+ Assistant nodes enable you to deploy assistant tasks. + The more assistant nodes your organization has, the more concurrent assistant tasks that you can run. + More powerful assistant nodes have more cores and RAM to handle larger, more demanding tasks. + The following table shows the specifications of the assistant node models: +
+| + Name + | ++ Number of Cores + | ++ RAM (GB) + | ++ Agents + | +
|---|---|---|---|
| + A-MICRO + | ++ 1 + | ++ 1 + | ++ 1 + | +
| + A1-1 + | ++ 1 + | ++ 1 + | ++ 1 + | +
| + A4-8 + | ++ 4 + | ++ 8 + | ++ 4 + | +
| + A16-32 + | ++ 16 + | ++ 32 + | ++ 16 + | +
+ Refer to the + + Pricing + + page to see the price of each assistant node model. + Your first organization includes one free A-MICRO assistant node, which is capped at 100,000 tokens per month. + The token cap is lifted and the node is replaced when you + + upgrade your organization to a paid tier + + and + + add a new assistant node + + . +
++ To view the status of all of your organization's nodes, see the + + Resources panel + + of the IDE. + When you launch an assistant task, it uses the best-performing resource by default, but you can + + select a specific resource to use + + . +
+ + +There are three tiers of support seats and each tier provides different services. You can file support tickets to get private assistance with issues, but support tickets should not replace your efforts of performing your own research and reading through the documentation. If you need further assistance than what our Support Team offers, consider hiring an - + Integration Partner . @@ -3059,11 +3211,11 @@
For more information on this feature, see - - Strategy Development + + AI Assistance .
@@ -3470,7 +3622,7 @@Chat with - + Mia for immediate assistance. We trained it on hundreds of algorithms and thousands of documentation pages to provide contextual assistance for most issues you may encounter when developing a strategy. @@ -5801,7 +5953,7 @@
To show your appreciation for contributions in the forum, - + give some QuantConnect Credit (QCC) rewards . The following table shows the available QCC rewards: @@ -7020,7 +7172,7 @@
+ You can add + + tags + + to your orders to track why each trade was placed. This is useful for debugging your algorithm's trading logic because you can include the indicator values or conditions that triggered the order. +
+public class OrderTaggingAlgorithm : QCAlgorithm
+{
+ private ExponentialMovingAverage _emaShort;
+ private ExponentialMovingAverage _emaLong;
+ private Symbol _symbol;
+
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ SetCash(100000);
+
+ _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
+ _emaShort = EMA(_symbol, 10);
+ _emaLong = EMA(_symbol, 30);
+ }
+
+ public override void OnData(Slice data)
+ {
+ if (!_emaShort.IsReady || !_emaLong.IsReady) return;
+
+ if (_emaShort > _emaLong && !Portfolio[_symbol].IsLong)
+ {
+ MarketOrder(_symbol, 100, tag: $"BUY: ema-short: {_emaShort:F4} > ema-long: {_emaLong:F4}");
+ }
+ else if (_emaShort < _emaLong && !Portfolio[_symbol].IsShort)
+ {
+ MarketOrder(_symbol, -100, tag: $"SELL: ema-short: {_emaShort:F4} < ema-long: {_emaLong:F4}");
+ }
+ }
+}
+ class OrderTaggingAlgorithm(QCAlgorithm):
+ def initialize(self) -> None:
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ self.set_cash(100000)
+
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+ self._ema_short = self.ema(self._symbol, 10)
+ self._ema_long = self.ema(self._symbol, 30)
+
+ def on_data(self, data: Slice) -> None:
+ if not self._ema_short.is_ready or not self._ema_long.is_ready:
+ return
+
+ ema_short = self._ema_short.current.value
+ ema_long = self._ema_long.current.value
+ if ema_short > ema_long and not self.portfolio[self._symbol].is_long:
+ self.market_order(self._symbol, 100, tag=f'BUY: ema-short: {ema_short:.4f} > ema-long: {ema_long:.4f}')
+ elif ema_short < ema_long and not self.portfolio[self._symbol].is_short:
+ self.market_order(self._symbol, -100, tag=f'SELL: ema-short: {ema_short:.4f} < ema-long: {ema_long:.4f}')
+ + The tag is saved to the + + result files + + that you can download for local analysis. Unlike + + logging statements + + , order tags are attached directly to each order, so you don't need to search through logs to match a message to a specific trade, and they don't consume your + + log quota + + . +
+ + +The Object Store is a key-value data store for low-latency information storage and retrieval. - During a backtest, you can build large objects you’d like to analyze and write them for later analysis. + During a backtest, you can build large objects you'd like to analyze and write them for later analysis. This workflow can be helpful when the objects are large and plotting is impossible or when you want to perform analysis across many backtests.
#load "../QuantConnect.csx" -using QuantConnect; +#load "../QuantConnect.csx"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -11735,11 +11970,11 @@Share Backtests
To attach the embedded backtest result to a forum discussion, see - + Create Discussions or - + Post Comments . @@ -14174,7 +14409,7 @@
To attach the embedded backtest result to a forum discussion, see - + Create Discussions or - + Post Comments . @@ -18483,7 +18718,11 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. @@ -18665,7 +18904,11 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. @@ -18813,142 +19056,150 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. -
-- Live data takes time to travel from the source to your algorithm. - The QuantConnect latencies vary depending on the data provider, but for US Equities, we have a latency of 5-40 milliseconds. - A much more significant source of latency is the round trip order times from brokers, which can vary from 100ms to 5 seconds. - QuantConnect is not intended for high-frequency trading, but we have integrations to high-speed brokers if you need. -
- - - -- When you - - request historical data - - or run - - warm-up + Most live trading algorithms run on co-located servers racked in + + Equinix - , the amount of historical data you can access depends on the resolution of your data subscriptions. The following table shows the amount of trailing historical data you can access for each data resolution: -
-| - Resolution - | -- Available History - | -
|---|---|
| - Daily - | -- All historical data - | -
| - Hour - | -- All historical data - | -
| - Minute - | -- 1 year - | -
| - Second - | -- 2 months - | -
| - Tick - | -- 1 month - | -
- The QuantConnect data provider serves Crypto Futures data for free. -
- - - -- -
- The QuantConnect data provider provides a stream of CFD trades and quotes to your trading algorithm during live execution. Live data enables you to make real-time trades and update the value of the securities in your portfolio. -
- - - -- The QuantConnect data provider consolidates CFD market data from OANDA. -
- - - -- We aggregate ticks to build bars. -
-- In live trading, bars are built using the exchange timestamps with microsecond accuracy. This microsecond-by-microsecond processing - of the ticks can mean that the individual bars between live trading and backtesting can have slightly different ticks. As a result, it's possible for a - tick to be counted in different bars between backtesting and live trading, which can lead to bars having slightly different open, high, low, close, and volume values. -
- - - -- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. +
++ Live data takes time to travel from the source to your algorithm. + The QuantConnect latencies vary depending on the data provider, but for US Equities, we have a latency of 5-40 milliseconds. + A much more significant source of latency is the round trip order times from brokers, which can vary from 100ms to 5 seconds. + QuantConnect is not intended for high-frequency trading, but we have integrations to high-speed brokers if you need. +
+ + + ++ When you + + request historical data + + or run + + warm-up + + , the amount of historical data you can access depends on the resolution of your data subscriptions. The following table shows the amount of trailing historical data you can access for each data resolution: +
+| + Resolution + | ++ Available History + | +
|---|---|
| + Daily + | ++ All historical data + | +
| + Hour + | ++ All historical data + | +
| + Minute + | ++ 1 year + | +
| + Second + | ++ 2 months + | +
| + Tick + | ++ 1 month + | +
+ The QuantConnect data provider serves Crypto Futures data for free. +
+ + + ++ +
+ The QuantConnect data provider provides a stream of CFD trades and quotes to your trading algorithm during live execution. Live data enables you to make real-time trades and update the value of the securities in your portfolio. +
+ + + ++ The QuantConnect data provider consolidates CFD market data from OANDA. +
+ + + ++ We aggregate ticks to build bars. +
++ In live trading, bars are built using the exchange timestamps with microsecond accuracy. This microsecond-by-microsecond processing + of the ticks can mean that the individual bars between live trading and backtesting can have slightly different ticks. As a result, it's possible for a + tick to be counted in different bars between backtesting and live trading, which can lead to bars having slightly different open, high, low, close, and volume values. +
+ + + ++ Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. @@ -19083,7 +19334,11 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. @@ -19249,7 +19504,11 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. @@ -19389,7 +19648,11 @@
- Most live trading algorithms run on co-located servers racked in Equinix. Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters. + Most live trading algorithms run on co-located servers racked in + + Equinix + + . Co-location reduces several factors that can interfere with your algorithm, including downtime from internet outages, equipment repairs, and natural disasters.
Live data takes time to travel from the source to your algorithm. The latency of the alternative data depends on the specific dataset you're using. @@ -20415,7 +20678,7 @@
When you - + deploy a live algorithm with the Charles Schwab brokerage , you can use a third-party data provider, the Charles Schwab data provider, or both. @@ -21666,7 +21929,11 @@
- A live algorithm is an algorithm that trades in real-time with real market data. QuantConnect enables you to run your algorithms in live mode with real-time market data. Deploy your algorithms using QuantConnect because our infrastructure is battle-tested. The algorithms that our members create are run on co-located servers and the trading infrastructure is maintained at all times by our team of engineers. It's common for members to achieve 6-months of uptime with no interruptions. + A live algorithm is an algorithm that trades in real-time with real market data. QuantConnect enables you to run your algorithms in live mode with real-time market data. Deploy your algorithms using QuantConnect because our infrastructure is battle-tested. The algorithms that our members create are run on co-located servers racked in + + Equinix + + and the trading infrastructure is maintained at all times by our team of engineers. It's common for members to achieve 6-months of uptime with no interruptions.
@@ -23531,6 +23798,110 @@+ FIX (Financial Information eXchange) integration lets existing Interactive Brokers (IB) clients route orders from QuantConnect through their IB account. If you already hold an IB account, you can subscribe to QuantConnect directly from the IB Client Portal to enable FIX order routing. +
++ Before you start, make sure you have an active IB account and access to the IB Client Portal. +
++ Follow these steps to add FIX support to your IB account: +
++ The user name you enter is the default subscriber for the QuantConnect service. You can select multiple accounts here. When you later connect from QuantConnect to IB, you enter this same user name to authenticate. +
++ After you confirm, your subscription is complete and the selected information is added to the FIX connection for order validation. +
++ You must have an available + + live trading node + + for each live trading algorithm you deploy. +
++ Follow these steps to deploy a live algorithm: +
++ In most cases, we suggest using + + both the QC and IB data providers + + . +
++ If you use + + IB + + data provider and trade with a paper trading account, you need to share the market data subscription with your paper trading account. For instructions on sharing market data subscription, see + + Account Types + + . +
++ By enabling + + automatic restarts + + , the algorithm will use best efforts to restart the algorithm if it fails due to a runtime error. This can help improve the algorithm's resilience to temporary outages such as a brokerage API disconnection. +
++ The deployment process can take up to 5 minutes. When the algorithm deploys, the + + live results page + + displays. If you know your brokerage positions before you deployed, you can verify they have been loaded properly by checking your equity value in the runtime statistics, your cashbook holdings, and your position holdings. +
+ + ++ Charles Schwab limits order requests (place, update, and cancel) to 120 requests per minute and 4,000 order requests per day. To avoid hitting these limits, design your algorithm to issue orders sparingly. +
+ + +- Deploy your trading algorithms live to receive real-time market data and submit orders on our co-located servers. As your algorithms run, you can view their performance in the Algorithm Lab. Since the algorithms run in QuantConnect Cloud, you can close the IDE without interrupting the execution of your algorithms. Deploying your algorithms to live trading through QuantConnect is cheaper than purchasing server space, setting up data feeds, and maintaining the software on your own. To deploy your algorithms on QuantConnect, you just need to follow the + Deploy your trading algorithms live to receive real-time market data and submit orders on our co-located servers racked in + + Equinix + + . As your algorithms run, you can view their performance in the Algorithm Lab. Since the algorithms run in QuantConnect Cloud, you can close the IDE without interrupting the execution of your algorithms. Deploying your algorithms to live trading through QuantConnect is cheaper than purchasing server space, setting up data feeds, and maintaining the software on your own. To deploy your algorithms on QuantConnect, you just need to follow the Deploy Live Algorithms @@ -38477,7 +38996,11 @@
- Live trading nodes enable you to deploy live algorithms to our professionally-managed, co-located servers. + Live trading nodes enable you to deploy live algorithms to our professionally-managed, co-located servers racked in + + Equinix + + . You need a live trading node for each algorithm that you deploy to our co-located servers. Several models of live trading nodes are available. More powerful live trading nodes allow you to run algorithms with larger universes and give you @@ -39293,7 +39816,7 @@
To programmatically analyze orders, call the - + - ReadBacktestOrders + ReadLiveOrders read_live_orders method or the - + /live/orders/read endpoint. @@ -41195,6 +41718,13 @@
If your algorithm is perfectly reconciled, it has an exact overlap between its live and OOS backtest equity curves. Deviations mean that the performance of your algorithm has differed between the two execution modes. Several factors can contribute to the deviations.
++ To generate the OOS reconciliation curve for a live deployment and overlay live vs. backtest equity and order fills from the Research Environment, see + + Live Reconciliation + + . +
@@ -43674,9 +44204,414 @@- +
+ The Research Pipeline is a kanban board that enables you to easily monitor the state of your organization. + Think of it as a structured approach to bringing your ideas through the stages of research validation, backtesting, paper trading, and ending with live trading. + Each card represents one project in QuantConnect Cloud. + Simply add projects to the board, then drag-and-drop them, to move them throughout the various stages of the pipeline as your team completes tasks. + To view the board, + + log in to the Algorithm Lab + + and then click the + + Research Pipeline + + tab. +
++ To supercharge your productivity, add some + + AI assistants + + to your Research Pipeline. + We offer a set of highly-skilled AI assistants that you can add to your organization. + They are each pre-configured to specialize in a particular phase of the Research Pipeline, but you can always define custom assistants to fit your organization's needs. +
+ + + +
+ The
+
+ Ideas
+
+ list on the Research Pipeline should contain cards that describe new trading ideas for your team's researchers to explore.
+ To add ideas to the list, click the
+
+
+ Add card
+
+ icon in the top-right corner of the list, enter a description of the trading idea, and then click
+
+ .
+
+ If you need some help generating some trading ideas, an + + Ideas Assistant + + can add a steady stream of novel trading ideas to your organization's + + Ideas + + list. + This assistant analyzes recent financial news articles and trading blog posts. + It then adds a card to the list with a concise description of the strategy, including the underlying logic, the types of assets it would trade, and any specific indicators or datasets it would utilize. +
+ + + ++ The + + Research + + list on the Research Pipeline should contain a card for each project that your research team is currently investigating. + During the research stage, the goal is to perform preliminary analysis to assess the viability of the trading idea before committing resources to a formal backtest. + This stage helps filter out weak ideas early, refine hypotheses, and identify potential pitfalls. +
+
+ To add cards to the
+
+ Research
+
+ list, drag-and-drop a card from the
+
+ Ideas
+
+ list.
+ Alternatively, click the
+
+
+ Add card
+
+ icon in the top-right corner of the list, enter a description of the trading idea, and then click
+
+ .
+
+ If you need some help researching ideas, add + + Research + + and + + Research Validation Assistants + + to your organization. + The Research Assistant has access to tools that let it write, read, and execute research notebooks, and it produces a research report in the project that documents its process and findings — typically covering empirical evidence, statistical significance, and a deep analysis of the fundamental reason for the edge of the trading idea. +
++ The Research Validation Assistant then pressure-tests that work, using the same notebook tools to check the model's residuals for stationarity, serial correlation, heteroscedasticity, and stability between training and testing windows. + Together, they decide whether an idea has earned its place in the backtesting queue or whether it should be sent back before any engineering time is spent on it. +
+ + + ++ The + + Backtest + + list on the Research Pipeline should contain a card for each project that your backtest team is currently investigating. + During the backtest stage, the goal is to implement the trading idea in an error-free, event-driven algorithm. + This stage helps filter out strategies that passed the research phase but have poor performance after running a backtest with realistic + + reality modeling + + . +
+
+ To add cards to the
+
+ Backtest
+
+ list, drag-and-drop a card from the
+
+ Ideas
+
+ or
+
+ Research
+
+ lists.
+ Alternatively, click the
+
+
+ Add card
+
+ icon in the top-right corner of the list, enter a description of the trading idea, and then click
+
+ .
+
+ If you need some help backtesting ideas, add a + + Backtest Assistant + + to your organization. + This assistant has access to tools that enable it to write algorithms, fix coding errors, run backtests, interpret backtest results, and optimize parameters. + The output of this assistant is an algorithm that's proven to underperform the market or an algorithm that's ready for testing in the paper trading environment. +
+ + + ++ The + + Paper Trading + + list on the Research Pipeline should contain a card for each project that your team is currently running live with the + + paper trading brokerage + + . + During the paper trading stage, the goal is to confirm the strategy works as expected in a live environment and diagnose any deviations. +
++ To add cards to the + + Paper Trading + + list, drag-and-drop a card from the + + Backtest + + list. +
++ If you need some help validating ideas with paper trading, add a + + Paper Testing Assistant + + to your organization. + This assistant has access to tools to deploy algorithms, analyze their live performance, and adjust the algorithm logic if necessary. + As it runs, it verifies the following questions: +
++ When any of these questions fail validation, the assistant reviews the code, debugs the algorithm, edits the logic, and redeploys the project. + If the assistant determines the strategy is not ready for live trading with real money, it stops the algorithm and sends you a report. +
+ + + ++ The + + Live Trading + + list on the Research Pipeline should contain a card for each project that your organization is running live with real money. + During this final stage, the goal is to ensure the algorithm continues running and to intervene when necessary. + To add cards to the + + Live Trading + + list, drag-and-drop a card from the + + Paper Trading + + list. +
++ If you need some help monitoring your live algorithms, add a + + Live Monitoring Assistant + + to your organization. + This assistant has access to tools to deploy algorithms, read their current positions, and scan for material news events that affect the positions. + As it runs, it assesses the directional risk of your holdings given breaking news events. + When it detects an event that can significantly reduce the value of your holdings, it notifies you so you can act. +
+ + + ++ The + + Archived Items + + section at the bottom of the Research Pipeline should contain a card for each project to which you're no longer allocating resources. + These may be ideas that failed the research validation stage, strategies that underperformed in the backtesting stage, or algorithms that lost their edge in live trading. +
++ To add projects to the archive, drag-and-drop a card from one of the stages of the Research Pipeline. + You can always recover projects from the archive later on. +
+ + + ++ Follow these steps to update the title or body of a card on the Research Pipeline: +
++ The + + Card + + tab shows the current title and description. +
++ When you assign a card to an Assistant and the Assistant is currently working on the task, the card displays “Running”. +
++ To view the deployment details, click + + . + The deployment view page displays the output of the Assistant(s) assigned to the task. +
++ To open the project associated with the task, click the project link at the top of the deployment view. +
+
+ To interrupt the assistant during its run, in the top-right corner of the deployment view, click the
+
+
+ stop
+
+ icon.
+
+ To view all the current and historical tasks, follow these steps: +
++ From this view, you can click the + + Status + + column to open the deployment view of the task or click + + to remove the task from the view. +
+ + + ++ Assistants have a fair-use quota, but are essentially uncapped. + The number of agents you can concurrently run in your organization and the amount of tokens you can use depends on your team's + + Assistant Nodes + + . +
+ + + ++ +
The QuantConnect forum is a place to discuss with other community members, Mia (our AI assistant), the core QuantConnect team, and our - + Integration Partners . Use the forum to spark interesting discussions, ask for assistance from other members, and voice your opinion on our products. You must complete 30% of the Bootcamp lessons in the @@ -44523,7 +45458,7 @@
To show your appreciation for contributions in the forum, - + give some QuantConnect Credit (QCC) rewards . The following table shows the available QCC rewards: @@ -44874,7 +45809,7 @@
To toggle your subscription to individual discussions, add or remove a - + bookmark to the discussions. @@ -45377,7 +46312,7 @@
The Discord server is governed by the normal rules in the - + Code of Conduct . @@ -45410,7 +46345,7 @@
- + Submit your strategies to join the competition. @@ -47201,7 +48136,7 @@
// Generate a timestamped SHA-256 hashed API token for secure authentication
-#r "nuget:RestSharp"
-using System;
using System.Security.Cryptography;
-using RestSharp;
-
-// Request your API token on https://www.quantconnect.com/settings/ and replace the below values.
-var yourUserId = 0;
-var yourApiToken = "_____";
+using System.Text;
-// Get timestamp
-var stamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
-var timeStampedToken = $"{<yourApiToken>}:{stamp}";
+// Set the QC_USER_ID and QC_API_TOKEN environment variables with values from https://www.quantconnect.com/settings/.
+var yourUserId = Environment.GetEnvironmentVariable("QC_USER_ID") ?? "0";
+var yourApiToken = Environment.GetEnvironmentVariable("QC_API_TOKEN") ?? "_____";
-// Get hashed API token
-var crypt = new SHA256Managed();
-var hashToken = crypt.ComputeHash(Encoding.UTF8.GetBytes(timeStampedToken), 0, Encoding.UTF8.GetByteCount(timeStampedToken));
-var hash = new StringBuilder();
-foreach (var theByte in hashToken)
+Dictionary<string, string> GetHeaders()
{
- hash.Append(theByte.ToString("x2"));
+ // Get timestamp
+ var timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds().ToString();
+ var timeStampedToken = $"{yourApiToken}:{timestamp}";
+
+ // Get hashed API token
+ var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(timeStampedToken));
+ var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
+ var authentication = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{yourUserId}:{hash}"));
+
+ // Create headers dictionary.
+ return new Dictionary<string, string>
+ {
+ { "Authorization", $"Basic {authentication}" },
+ { "Timestamp", timestamp }
+ };
}
-var apiToken = hash.ToString();
# Generate a timestamped SHA-256 hashed API token for secure authentication
+from os import environ
from base64 import b64encode
from hashlib import sha256
from time import time
-# Request your API token on https://www.quantconnect.com/settings/ and replace the below values.
-USER_ID = 0
-API_TOKEN = '_____'
+# Set the QC_USER_ID and QC_API_TOKEN environment variables with values from https://www.quantconnect.com/settings/.
+USER_ID = environ.get('QC_USER_ID', 0)
+API_TOKEN = environ.get('QC_API_TOKEN', '_____')
def get_headers():
# Get timestamp
timestamp = f'{int(time())}'
time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
- # Get hased API token
+ # Get hashed API token
hashed_token = sha256(time_stamped_token).hexdigest()
authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
authentication = b64encode(authentication).decode('ascii')
@@ -47512,27 +48462,22 @@
Make API Request
-
- Follow the below example to install the hashing into the authenticator and make an API request.
-
-
- Follow the below example to install the hashing into the headings and make an API request.
+
+ Follow the below example to set the authentication headers and make an API request.
- // Create REST client and install authenticator.
-var client = new RestClient("<requestUrl>");
-client.Authenticator = new HttpBasicAuthenticator(
- "<yourUserId>",
- hash.ToString()
-);
-
-// Create Request and add timestamp header (optional: Json Content).
-var request = new RestRequest();
-request.AddHeader("Timestamp", stamp.ToString());
+ // Create HTTP client with authentication headers.
+var client = new HttpClient();
+client.BaseAddress = new Uri("https://www.quantconnect.com/api/v2/");
+foreach (var header in GetHeaders())
+{
+ client.DefaultRequestHeaders.Add(header.Key, header.Value);
+}
// Make POST request.
-var response = await client.PostAsync(request);
-var content = response.Content
+var request = new StringContent("{}", Encoding.UTF8, "application/json");
+var response = await client.PostAsync("<requestUrl>", request);
+var content = await response.Content.ReadAsStringAsync();
# Create POST Request with headers
from requests import post
BASE_URL = 'https://www.quantconnect.com/api/v2/'
@@ -47542,6 +48487,61 @@
json = {}) # Use json keyword to send the payload
content = response.text
+
+ Using cURL
+
+
+ Follow the below example to make an API request with authentication using cURL.
+
+
+ # Set the QC_USER_ID and QC_API_TOKEN environment variables with values from https://www.quantconnect.com/settings/.
+YOUR_USER_ID=${QC_USER_ID:-0}
+YOUR_API_TOKEN=${QC_API_TOKEN:-_____}
+
+# Get timestamp
+TIMESTAMP=$(date +%s)
+TIME_STAMPED_TOKEN="${YOUR_API_TOKEN}:${TIMESTAMP}"
+
+# Get hashed API token
+HASHED_TOKEN=$(echo -n "$TIME_STAMPED_TOKEN" | sha256sum | cut -d ' ' -f 1)
+AUTHENTICATION=$(echo -n "${YOUR_USER_ID}:${HASHED_TOKEN}" | base64 -w 0)
+
+# Make POST request with authentication headers
+curl -X POST "https://www.quantconnect.com/api/v2/<request_url>" \
+ -H "Authorization: Basic ${AUTHENTICATION}" \
+ -H "Timestamp: ${TIMESTAMP}" \
+ -H "Content-Type: application/json" \
+ -d '{}'
+
+
+ Using PowerShell
+
+
+ Follow the below example to make an API request with authentication using PowerShell.
+
+
+ # Set the QC_USER_ID and QC_API_TOKEN environment variables with values from https://www.quantconnect.com/settings/.
+$yourUserId = if ($env:QC_USER_ID) { $env:QC_USER_ID } else { "0" }
+$yourApiToken = if ($env:QC_API_TOKEN) { $env:QC_API_TOKEN } else { "_____" }
+
+# Get timestamp
+$timestamp = [Math]::Floor((([DateTimeOffset]::UtcNow).ToUnixTimeSeconds()))
+$timeStampedToken = "${yourApiToken}:${timestamp}"
+
+# Get hashed API token
+$hasher = [System.Security.Cryptography.SHA256]::Create()
+$hashBytes = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($timeStampedToken))
+$hash = -join ($hashBytes | ForEach-Object { $_.ToString("x2") })
+$authentication = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${yourUserId}:${hash}"))
+
+# Make POST request with authentication headers
+$headers = @{
+ "Authorization" = "Basic $authentication"
+ "Timestamp" = "$timestamp"
+}
+$response = Invoke-RestMethod -Uri "https://www.quantconnect.com/api/v2/<requestUrl>" -Method Post -Headers $headers -ContentType "application/json" -Body "{}"
+Write-Host "Response: $($response | ConvertTo-Json)"
+
@@ -47641,7 +48641,7 @@
- object
+ Grid object
@@ -48448,7 +49448,7 @@
- object
+ Grid object
@@ -48466,7 +49466,7 @@
- object
+ LiveForm object
@@ -48520,7 +49520,7 @@
- object
+ EncryptionKey object
@@ -48592,7 +49592,7 @@
- int
+ integer
@@ -48850,7 +49850,7 @@
"name": "string"
},
"isPinned": true,
- "maxFileSize": "string",
+ "maxFileSize": 0,
"sharingTokenBacktest": "q"
}
@@ -49495,7 +50495,7 @@
- object
+ BrokerageData object
@@ -49504,7 +50504,7 @@
- object
+ Grid object
@@ -51948,7 +52948,7 @@
- object
+ Grid object
@@ -51966,7 +52966,7 @@
- object
+ LiveForm object
@@ -52020,7 +53020,7 @@
- object
+ EncryptionKey object
@@ -52092,7 +53092,7 @@
- int
+ integer
@@ -52350,7 +53350,7 @@
"name": "string"
},
"isPinned": true,
- "maxFileSize": "string",
+ "maxFileSize": 0,
"sharingTokenBacktest": "q"
}
@@ -52995,7 +53995,7 @@
- object
+ BrokerageData object
@@ -53004,7 +54004,7 @@
+ The following example demonstrates how to add a collaborator to all projects that start with a given folder name. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# Define the folder prefix to match (e.g., "SubFolder/")
+folder_prefix = "SubFolder/"
+# Define collaborator ID (replace with actual user ID)
+collaborator_id = 'johnny_walker'
+# Send a POST request to the /projects/read endpoint to get all projects
+response = post(f'{BASE_URL}/projects/read', headers=get_headers())
+result = response.json()
+if result['success']:
+ # Filter projects that start with the given folder prefix
+ matching_projects = [
+ project for project in result['projects']
+ if project['name'].startswith(folder_prefix)
+ ]
+ # Add the collaborator to each matching project
+ for project in matching_projects:
+ response = post(f'{BASE_URL}/projects/collaboration/create', headers=get_headers(), json={
+ "projectId": project['projectId'],
+ "collaboratorUserId": collaborator_id,
+ "collaborationLiveControl": True,
+ "collaborationWrite": True
+ })
+ add_result = response.json()
+ if add_result['success']:
+ print(f"Added collaborator to project '{project['name']}' (ID: {project['projectId']})")
+ else:
+ print(f"Failed to add collaborator to project '{project['name']}': {add_result}")
+
+ The following example demonstrates how to add a collaborator to all projects that start with a given folder name. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# Define the folder prefix to match (e.g., "SubFolder/")
+folder_prefix = "SubFolder/"
+# Define collaborator ID (replace with actual user ID)
+collaborator_id = 'johnny_walker'
+# Send a POST request to the /projects/read endpoint to get all projects
+response = post(f'{BASE_URL}/projects/read', headers=get_headers())
+result = response.json()
+if result['success']:
+ # Filter projects that start with the given folder prefix
+ matching_projects = [
+ project for project in result['projects']
+ if project['name'].startswith(folder_prefix)
+ ]
+ # Add the collaborator to each matching project
+ for project in matching_projects:
+ response = post(f'{BASE_URL}/projects/collaboration/create', headers=get_headers(), json={
+ "projectId": project['projectId'],
+ "collaboratorUserId": collaborator_id,
+ "collaborationLiveControl": True,
+ "collaborationWrite": True
+ })
+ add_result = response.json()
+ if add_result['success']:
+ print(f"Added collaborator to project '{project['name']}' (ID: {project['projectId']})")
+ else:
+ print(f"Failed to add collaborator to project '{project['name']}': {add_result}")
+
+ The following example demonstrates how to add a collaborator to all projects that start with a given folder name. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# Define the folder prefix to match (e.g., "SubFolder/")
+folder_prefix = "SubFolder/"
+# Define collaborator ID (replace with actual user ID)
+collaborator_id = 'johnny_walker'
+# Send a POST request to the /projects/read endpoint to get all projects
+response = post(f'{BASE_URL}/projects/read', headers=get_headers())
+result = response.json()
+if result['success']:
+ # Filter projects that start with the given folder prefix
+ matching_projects = [
+ project for project in result['projects']
+ if project['name'].startswith(folder_prefix)
+ ]
+ # Add the collaborator to each matching project
+ for project in matching_projects:
+ response = post(f'{BASE_URL}/projects/collaboration/create', headers=get_headers(), json={
+ "projectId": project['projectId'],
+ "collaboratorUserId": collaborator_id,
+ "collaborationLiveControl": True,
+ "collaborationWrite": True
+ })
+ add_result = response.json()
+ if add_result['success']:
+ print(f"Added collaborator to project '{project['name']}' (ID: {project['projectId']})")
+ else:
+ print(f"Failed to add collaborator to project '{project['name']}': {add_result}")
+
+ The following example demonstrates how to add a collaborator to all projects that start with a given folder name. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# Define the folder prefix to match (e.g., "SubFolder/")
+folder_prefix = "SubFolder/"
+# Define collaborator ID (replace with actual user ID)
+collaborator_id = 'johnny_walker'
+# Send a POST request to the /projects/read endpoint to get all projects
+response = post(f'{BASE_URL}/projects/read', headers=get_headers())
+result = response.json()
+if result['success']:
+ # Filter projects that start with the given folder prefix
+ matching_projects = [
+ project for project in result['projects']
+ if project['name'].startswith(folder_prefix)
+ ]
+ # Add the collaborator to each matching project
+ for project in matching_projects:
+ response = post(f'{BASE_URL}/projects/collaboration/create', headers=get_headers(), json={
+ "projectId": project['projectId'],
+ "collaboratorUserId": collaborator_id,
+ "collaborationLiveControl": True,
+ "collaborationWrite": True
+ })
+ add_result = response.json()
+ if add_result['success']:
+ print(f"Added collaborator to project '{project['name']}' (ID: {project['projectId']})")
+ else:
+ print(f"Failed to add collaborator to project '{project['name']}': {add_result}")
+
+ The following example demonstrates how to add a collaborator to all projects that start with a given folder name. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# Define the folder prefix to match (e.g., "SubFolder/")
+folder_prefix = "SubFolder/"
+# Define collaborator ID (replace with actual user ID)
+collaborator_id = 'johnny_walker'
+# Send a POST request to the /projects/read endpoint to get all projects
+response = post(f'{BASE_URL}/projects/read', headers=get_headers())
+result = response.json()
+if result['success']:
+ # Filter projects that start with the given folder prefix
+ matching_projects = [
+ project for project in result['projects']
+ if project['name'].startswith(folder_prefix)
+ ]
+ # Add the collaborator to each matching project
+ for project in matching_projects:
+ response = post(f'{BASE_URL}/projects/collaboration/create', headers=get_headers(), json={
+ "projectId": project['projectId'],
+ "collaboratorUserId": collaborator_id,
+ "collaborationLiveControl": True,
+ "collaborationWrite": True
+ })
+ add_result = response.json()
+ if add_result['success']:
+ print(f"Added collaborator to project '{project['name']}' (ID: {project['projectId']})")
+ else:
+ print(f"Failed to add collaborator to project '{project['name']}': {add_result}")
+
+ AnalysisResult Array
+
+
- AlgorithmPerformance
-
- Model - The AlgorithmPerformance class is a wrapper for TradeStatistics and PortfolioStatistics.
-
- TradeStatistics object
-
-
- PortfolioStatistics object
-
-
- Trade Array
-
-
-{
- "tradeStatistics": {
- "startDateTime": "2021-11-26T15:18:27.693Z",
- "endDateTime": "2021-11-26T15:18:27.693Z",
- "totalNumberOfTrades": 0,
- "numberOfWinningTrades": 0,
- "numberOfLosingTrades": 0,
- "totalProfitLoss": "string",
- "totalProfit": "string",
- "totalLoss": "string",
- "largestProfit": "string",
- "largestLoss": "string",
- "averageProfitLoss": "string",
- "averageProfit": "string",
- "averageLoss": "string",
- "averageTradeDuration": "string",
- "averageWinningTradeDuration": "string",
- "averageLosingTradeDuration": "string",
- "medianTradeDuration": "string",
- "medianWinningTradeDuration": "string",
- "medianLosingTradeDuration": "string",
- "maxConsecutiveWinningTrades": 0,
- "maxConsecutiveLosingTrades": 0,
- "profitLossRatio": "string",
- "winLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "averageMAE": "string",
- "averageMFE": "string",
- "largestMAE": "string",
- "largestMFE": "string",
- "maximumClosedTradeDrawdown": "string",
- "maximumIntraTradeDrawdown": "string",
- "profitLossStandardDeviation": "string",
- "profitLossDownsideDeviation": "string",
- "profitFactor": "string",
- "sharpeRatio": "string",
- "sortinoRatio": "string",
- "profitToMaxDrawdownRatio": "string",
- "maximumEndTradeDrawdown": "string",
- "averageEndTradeDrawdown": "string",
- "maximumDrawdownDuration": "string",
- "totalFees": "string"
- },
- "portfolioStatistics": {
- "averageWinRate": "string",
- "averageLossRate": "string",
- "profitLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "expectancy": "string",
- "startEquity": "string",
- "endEquity": "string",
- "compoundingAnnualReturn": "string",
- "drawdown": "string",
- "totalNetProfit": "string",
- "sharpeRatio": "string",
- "probabilisticSharpeRatio": "string",
- "sortinoRatio": "string",
- "alpha": "string",
- "beta": "string",
- "annualStandardDeviation": "string",
- "annualVariance": "string",
- "informationRatio": "string",
- "trackingError": "string",
- "treynorRatio": "string",
- "portfolioTurnover": "string",
- "valueAtRisk99": "string",
- "valueAtRisk95": "string",
- "drawdownRecovery": "string"
- },
- "closedTrades": [
- {
- "symbol": {
- "value": "string",
- "id": "string",
- "permtick": "string"
- },
- "entryTime": "2021-11-26T15:18:27.693Z",
- "entryPrice": 0,
- "direction": 0,
- "quantity": 0,
- "exitTime": "2021-11-26T15:18:27.693Z",
- "exitPrice": 0,
- "profitLoss": 0,
- "totalFees": 0,
- "mae": 0,
- "mfe": 0,
- "duration": "string",
- "endTradeDrawdown": 0
- }
- ]
-}
-
-
- TradeStatistics
+ RuntimeStatistics
- Model - A set of statistics calculated from a list of closed trades.
+ Model
|
|
|---|---|
| - startDateTime - | -
-
- string($date-time)
-
- - The entry date/time of the first trade. - |
-
| - endDateTime + Equity |
- string($date-time)
+ string
+
- The exit date/time of the first trade. + Total portfolio value. |
| - totalNumberOfTrades + Fees |
- integer
+ string
+
- The total number of trades. + Transaction fee. |
| - numberOfWinningTrades + Holdings |
- integer
+ string
+
- The total number of winning trades. + Equity value of security holdings. |
| - numberOfLosingTrades + Net Profit |
- integer
+ string
+
- The total number of losing trades. + Net profit. |
| - totalProfitLoss + Probabilistic Sharpe Ratio |
string
+
- The total profit/loss for all trades (as symbol currency). + Probabilistic Sharpe Ratio. |
| - totalProfit + Return |
string
+
- The total profit for all winning trades (as symbol currency). + Return. |
| - totalLoss + Unrealized |
string
+
- The total loss for all losing trades (as symbol currency). + Unrealized profit/loss. |
| - largestProfit + Volume |
string
+
- The largest profit in a single trade (as symbol currency). + Total transaction volume. |
| - largestLoss + Example |
-
- string
-
- - The largest loss in a single trade (as symbol currency). +
+
+{
+ "Equity": "$100.00",
+ "Fees": "-$100.00",
+ "Holdings": "$100.00",
+ "Net Profit": "$100.00",
+ "Probabilistic Sharpe Ratio": "50.00%",
+ "Return": "50.00%",
+ "Unrealized": "$100.00",
+ "Volume": "$100.00"
+}
+ |
+
+ StatisticsResult
+
+ Model - Statistics information sent during the algorithm operations.
+ |
+ |
|---|---|
| - averageProfitLoss + Total Orders |
string
- The average profit/loss (a.k.a. Expectancy or Average Trade) for all trades (as symbol currency). + Total nuber of orders. |
| - averageProfit + Average Win |
string
- The average profit for all winning trades (as symbol currency). + The average rate of return for winning trades. |
| - averageLoss + Average Loss |
string
- The average loss for all winning trades (as symbol currency). + The average rate of return for losing trades. |
| - averageTradeDuration + Compounding Annual Return |
string
- The average duration for all trades. + Annual compounded returns statistic based on the final-starting capital and years. |
| - averageWinningTradeDuration + Drawdown |
string
- The average duration for all winning trades. + Drawdown maximum percentage. |
| - averageLosingTradeDuration + Expectancy |
string
- The average duration for all losing trades. + The expected value of the rate of return. |
| - medianTradeDuration + Start Equity |
string
- The median duration for all trades. + Initial Equity Total Value. |
| - medianWinningTradeDuration + End Equity |
string
- The median duration for all winning trades. + Final Equity Total Value. |
| - medianLosingTradeDuration + Net Profit |
string
- The median duration for all losing trades. + The total net profit percentage. |
| - maxConsecutiveWinningTrades + Sharpe Ratio |
- integer
+ string
- The maximum number of consecutive winning trades. + Sharpe ratio with respect to risk free rate; measures excess of return per unit of risk. |
| - maxConsecutiveLosingTrades + Sortino Ratio |
- integer
+ string
- The maximum number of consecutive losing trades. + Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. |
| - profitLossRatio + Probabilistic Sharpe Ratio |
string
- The ratio of the average profit per trade to the average loss per trade. + Is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. |
| - winLossRatio + Loss Rate |
string
- The ratio of the number of winning trades to the number of losing trades. + The ratio of the number of losing trades to the total number of trades. |
| - winRate + Win Rate |
@@ -63622,206 +64735,245 @@ |
| - lossRate + Profit-Loss Ratio |
string
- The ratio of the number of losing trades to the total number of trades. + The ratio of the average win rate to the average loss rate. |
| - averageMAE + Alpha |
string
- The average Maximum Adverse Excursion for all trades. + Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. |
| - averageMFE + Beta |
string
- The average Maximum Adverse Excursion for all trades. + Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance. |
| - largestMAE + Annual Standard Deviation |
string
- The average Maximum Favorable Excursion for all trades. + Annualized standard deviation. |
| - largestMFE + Annual Variance |
string
- The largest Maximum Adverse Excursion in a single trade (as symbol currency). + Annualized variance statistic calculation using the daily performance variance and trading days per year. |
| - maximumClosedTradeDrawdown + Information Ratio |
string
- The maximum closed-trade drawdown for all trades (as symbol currency). + Information ratio - risk adjusted return. |
| - maximumIntraTradeDrawdown + Tracking Error |
string
- The maximum intra-trade drawdown for all trades (as symbol currency). + Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. |
| - profitLossStandardDeviation + Treynor Ratio |
string
- The standard deviation of the profits/losses for all trades (as symbol currency). + Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. |
| - profitLossDownsideDeviation + Total Fees |
string
- The downside deviation of the profits/losses for all trades (as symbol currency). + Total amount of fees. |
| - profitFactor + Estimated Strategy Capacity |
string
- The ratio of the total profit to the total loss. + The estimated total capacity of the strategy at a point in time. |
| - sharpeRatio + Lowest Capacity Asset |
string
- The ratio of the average profit/loss to the standard deviation. + Provide a reference to the lowest capacity symbol used in scaling down the capacity for debugging. |
| - sortinoRatio + Portfolio Turnover |
string
- The ratio of the average profit/loss to the downside deviation. + The average Portfolio Turnover. |
| - profitToMaxDrawdownRatio + Drawdown Recovery |
string
- The ratio of the total profit/loss to the maximum closed trade drawdown. + /. |
| - maximumEndTradeDrawdown + Example |
-
- string
-
- - The maximum amount of profit given back by a single trade before exit (as symbol currency). +
+
+{
+ "Total Orders": "string",
+ "Average Win": "string",
+ "Average Loss": "string",
+ "Compounding Annual Return": "string",
+ "Drawdown": "string",
+ "Expectancy": "string",
+ "Start Equity": "string",
+ "End Equity": "string",
+ "Net Profit": "string",
+ "Sharpe Ratio": "string",
+ "Sortino Ratio": "string",
+ "Probabilistic Sharpe Ratio": "string",
+ "Loss Rate": "string",
+ "Win Rate": "string",
+ "Profit-Loss Ratio": "string",
+ "Alpha": "string",
+ "Beta": "string",
+ "Annual Standard Deviation": "string",
+ "Annual Variance": "string",
+ "Information Ratio": "string",
+ "Tracking Error": "string",
+ "Treynor Ratio": "string",
+ "Total Fees": "string",
+ "Estimated Strategy Capacity": "string",
+ "Lowest Capacity Asset": "string",
+ "Portfolio Turnover": "string",
+ "Drawdown Recovery": "string"
+}
+ |
+
+ AlgorithmPerformance
+
+ Model - The AlgorithmPerformance class is a wrapper for TradeStatistics and PortfolioStatistics.
+ |
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - averageEndTradeDrawdown + tradeStatistics |
- string
+ TradeStatistics object
- The average amount of profit given back by all trades before exit (as symbol currency). + A set of statistics calculated from a list of closed trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - maximumDrawdownDuration + portfolioStatistics |
- string
+ PortfolioStatistics object
- The maximum amount of time to recover from a drawdown (longest time between new equity highs or peaks). + Represents a set of statistics calculated from equity and benchmark samples. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - totalFees + closedTrades |
- string
+ Trade Array
- The sum of fees for all trades. + The algorithm statistics on portfolio. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
- PortfolioStatistics
+ TradeStatistics
- Model - Represents a set of statistics calculated from equity and benchmark samples.
+ Model - A set of statistics calculated from a list of closed trades.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| - averageWinRate + startDateTime |
- string
+ string($date-time)
- The average rate of return for winning trades. + The entry date/time of the first trade. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - averageLossRate + endDateTime |
- string
+ string($date-time)
- The average rate of return for losing trades. + The exit date/time of the first trade. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - profitLossRatio + totalNumberOfTrades |
- string
+ integer
- The ratio of the average win rate to the average loss rate. + The total number of trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - winRate + numberOfWinningTrades |
- string
+ integer
- The ratio of the number of winning trades to the total number of trades. + The total number of winning trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - lossRate + numberOfLosingTrades |
- string
+ integer
- The ratio of the number of losing trades to the total number of trades. + The total number of losing trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - expectancy + totalProfitLoss |
string
- The expected value of the rate of return. + The total profit/loss for all trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - startEquity + totalProfit |
string
- Initial Equity Total Value. + The total profit for all winning trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - endEquity + totalLoss |
string
- Final Equity Total Value. + The total loss for all losing trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - compoundingAnnualReturn + largestProfit |
string
- Annual compounded returns statistic based on the final-starting capital and years. + The largest profit in a single trade (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - drawdown + largestLoss |
string
- Drawdown maximum percentage. + The largest loss in a single trade (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - totalNetProfit + averageProfitLoss |
string
- The total net profit percentage. + The average profit/loss (a.k.a. Expectancy or Average Trade) for all trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - sharpeRatio + averageProfit |
string
- Sharpe ratio with respect to risk free rate: measures excess of return per unit of risk. + The average profit for all winning trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - probabilisticSharpeRatio + averageLoss |
string
- Probabilistic Sharpe Ratio is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. + The average loss for all winning trades (as symbol currency). |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - sortinoRatio + averageTradeDuration |
string
- Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. + The average duration for all trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - alpha + averageWinningTradeDuration |
string
- Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. + The average duration for all winning trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - beta + averageLosingTradeDuration |
string
- Algorithm beta statistic - the covariance between the algorithm and benchmark performance, divided by benchmark variance. + The average duration for all losing trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - annualStandardDeviation + medianTradeDuration |
string
- Annualized standard deviation. + The median duration for all trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - annualVariance + medianWinningTradeDuration |
string
- Annualized variance statistic calculation using the daily performance variance and trading days per year. + The median duration for all winning trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - informationRatio + medianLosingTradeDuration |
string
- Information ratio - risk adjusted return. + The median duration for all losing trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - trackingError + maxConsecutiveWinningTrades |
- string
+ integer
- Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. + The maximum number of consecutive winning trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - treynorRatio + maxConsecutiveLosingTrades |
- string
+ integer
- Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. + The maximum number of consecutive losing trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - portfolioTurnover + profitLossRatio |
string
- The average Portfolio Turnover. + The ratio of the average profit per trade to the average loss per trade. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - valueAtRisk99 + winLossRatio |
string
- The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 99% confidence level, 1 year lookback period, and that the returns are normally distributed. + The ratio of the number of winning trades to the number of losing trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - valueAtRisk95 + winRate |
string
- The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 95% confidence level, 1 year lookback period, and that the returns are normally distributed. + The ratio of the number of winning trades to the total number of trades. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - drawdownRecovery + lossRate |
string
- /. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Example - | -
-
-
+ The ratio of the number of losing trades to the total number of trades.
-{
- "averageWinRate": "string",
- "averageLossRate": "string",
- "profitLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "expectancy": "string",
- "startEquity": "string",
- "endEquity": "string",
- "compoundingAnnualReturn": "string",
- "drawdown": "string",
- "totalNetProfit": "string",
- "sharpeRatio": "string",
- "probabilisticSharpeRatio": "string",
- "sortinoRatio": "string",
- "alpha": "string",
- "beta": "string",
- "annualStandardDeviation": "string",
- "annualVariance": "string",
- "informationRatio": "string",
- "trackingError": "string",
- "treynorRatio": "string",
- "portfolioTurnover": "string",
- "valueAtRisk99": "string",
- "valueAtRisk95": "string",
- "drawdownRecovery": "string"
-}
- |
||||||||||||||||||||||||||||||||||||||||||||||||||||
-
- Trade
-
- Model - Represents a closed trade.
- |
- |
|---|---|
| - symbol + averageMAE |
- Symbol object
+ string
- Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security. + The average Maximum Adverse Excursion for all trades. |
| - entryTime + averageMFE |
- string($date-time)
+ string
- The date and time the trade was opened. + The average Maximum Adverse Excursion for all trades. |
| - entryPrice + largestMAE |
- number
+ string
- The price at which the trade was opened (or the average price if multiple entries). + The average Maximum Favorable Excursion for all trades. |
| - direction + largestMFE |
- integer Enum
+ string
- Direction of a trade. 0=Long, 1=Short. Options : [0, 1] + The largest Maximum Adverse Excursion in a single trade (as symbol currency). |
| - quantity + maximumClosedTradeDrawdown |
- number
+ string
- The total unsigned quantity of the trade. + The maximum closed-trade drawdown for all trades (as symbol currency). |
| - exitTime + maximumIntraTradeDrawdown |
- string($date-time)
+ string
- The date and time the trade was closed. + The maximum intra-trade drawdown for all trades (as symbol currency). |
| - exitPrice + profitLossStandardDeviation |
- number
+ string
- The price at which the trade was closed (or the average price if multiple exits). + The standard deviation of the profits/losses for all trades (as symbol currency). |
| - profitLoss + profitLossDownsideDeviation |
- number
+ string
- The gross profit/loss of the trade (as account currency). + The downside deviation of the profits/losses for all trades (as symbol currency). |
| - totalFees + profitFactor |
- number
+ string
- The total fees associated with the trade (always positive value) (as account currency). + The ratio of the total profit to the total loss. |
| - mae + sharpeRatio |
- number
+ string
- The Maximum Adverse Excursion (as account currency). + The ratio of the average profit/loss to the standard deviation. |
| - mfe + sortinoRatio |
- number
+ string
- The Maximum Favorable Excursion (as account currency). + The ratio of the average profit/loss to the downside deviation. |
| - duration + profitToMaxDrawdownRatio |
string
- The duration of the trade. + The ratio of the total profit/loss to the maximum closed trade drawdown. |
| - endTradeDrawdown + maximumEndTradeDrawdown |
- number
+ string
- The amount of profit given back before the trade was closed. - |
-
| - Example - | -
-
-
+ The maximum amount of profit given back by a single trade before exit (as symbol currency).
-{
- "symbol": {
- "value": "string",
- "id": "string",
- "permtick": "string"
- },
- "entryTime": "2021-11-26T15:18:27.693Z",
- "entryPrice": 0,
- "direction": 0,
- "quantity": 0,
- "exitTime": "2021-11-26T15:18:27.693Z",
- "exitPrice": 0,
- "profitLoss": 0,
- "totalFees": 0,
- "mae": 0,
- "mfe": 0,
- "duration": "string",
- "endTradeDrawdown": 0
-}
- |
-
- Symbol
-
- Model - Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security.
- |
- |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - value + averageEndTradeDrawdown |
string
- The current symbol for this ticker. + The average amount of profit given back by all trades before exit (as symbol currency). |
||||||||||||||||||
| - id + maximumDrawdownDuration |
string
- The security identifier for this symbol. + The maximum amount of time to recover from a drawdown (longest time between new equity highs or peaks). |
||||||||||||||||||
| - permtick + totalFees |
string
- The ticker at IPO for this security. + The sum of fees for all trades. |
||||||||||||||||||
- RuntimeStatistics
+ PortfolioStatistics
- Model
+ Model - Represents a set of statistics calculated from equity and benchmark samples.
|
|||||||||||||||||||
| - Equity + averageWinRate |
string
-
- Total portfolio value. + The average rate of return for winning trades. |
||||||||||||||||||
| - Fees + averageLossRate |
string
-
- Transaction fee. + The average rate of return for losing trades. |
||||||||||||||||||
| - Holdings + profitLossRatio |
string
-
- Equity value of security holdings. + The ratio of the average win rate to the average loss rate. |
||||||||||||||||||
| - Net Profit + winRate |
string
-
- Net profit. + The ratio of the number of winning trades to the total number of trades. |
||||||||||||||||||
| - Probabilistic Sharpe Ratio + lossRate |
string
-
- Probabilistic Sharpe Ratio. + The ratio of the number of losing trades to the total number of trades. |
||||||||||||||||||
| - Return + expectancy |
string
-
- Return. + The expected value of the rate of return. |
||||||||||||||||||
| - Unrealized + startEquity |
string
-
- Unrealized profit/loss. + Initial Equity Total Value. |
||||||||||||||||||
| - Volume + endEquity |
string
-
- Total transaction volume. + Final Equity Total Value. |
||||||||||||||||||
| - Example + compoundingAnnualReturn |
-
-
+
-{
- "Equity": "$100.00",
- "Fees": "-$100.00",
- "Holdings": "$100.00",
- "Net Profit": "$100.00",
- "Probabilistic Sharpe Ratio": "50.00%",
- "Return": "50.00%",
- "Unrealized": "$100.00",
- "Volume": "$100.00"
-}
-
+ string
+
+ + Annual compounded returns statistic based on the final-starting capital and years. |
||||||||||||||||||
-
- StatisticsResult
-
- Model - Statistics information sent during the algorithm operations.
- |
- |
|---|---|
| - Total Orders + drawdown |
string
- Total nuber of orders. + Drawdown maximum percentage. |
| - Average Win + totalNetProfit |
string
- The average rate of return for winning trades. + The total net profit percentage. |
| - Average Loss + sharpeRatio |
string
- The average rate of return for losing trades. + Sharpe ratio with respect to risk free rate: measures excess of return per unit of risk. |
| - Compounding Annual Return + probabilisticSharpeRatio |
string
- Annual compounded returns statistic based on the final-starting capital and years. + Probabilistic Sharpe Ratio is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. |
| - Drawdown + sortinoRatio |
string
- Drawdown maximum percentage. + Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. |
| - Expectancy + alpha |
string
- The expected value of the rate of return. + Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. |
| - Start Equity + beta |
string
- Initial Equity Total Value. + Algorithm beta statistic - the covariance between the algorithm and benchmark performance, divided by benchmark variance. |
| - End Equity + annualStandardDeviation |
string
- Final Equity Total Value. + Annualized standard deviation. |
| - Net Profit + annualVariance |
string
- The total net profit percentage. + Annualized variance statistic calculation using the daily performance variance and trading days per year. |
| - Sharpe Ratio + informationRatio |
string
- Sharpe ratio with respect to risk free rate; measures excess of return per unit of risk. + Information ratio - risk adjusted return. |
| - Sortino Ratio + trackingError |
string
- Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. + Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. |
| - Probabilistic Sharpe Ratio + treynorRatio |
string
- Is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. + Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. |
| - Loss Rate + portfolioTurnover |
string
- The ratio of the number of losing trades to the total number of trades. + The average Portfolio Turnover. |
| - Win Rate + valueAtRisk99 |
string
- The ratio of the number of winning trades to the total number of trades. + The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 99% confidence level, 1 year lookback period, and that the returns are normally distributed. |
| - Profit-Loss Ratio + valueAtRisk95 |
string
- The ratio of the average win rate to the average loss rate. + The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 95% confidence level, 1 year lookback period, and that the returns are normally distributed. |
| - Alpha + drawdownRecovery |
string
- Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. + /. |
| - Beta + Example + | +
+
+
+
+{
+ "averageWinRate": "string",
+ "averageLossRate": "string",
+ "profitLossRatio": "string",
+ "winRate": "string",
+ "lossRate": "string",
+ "expectancy": "string",
+ "startEquity": "string",
+ "endEquity": "string",
+ "compoundingAnnualReturn": "string",
+ "drawdown": "string",
+ "totalNetProfit": "string",
+ "sharpeRatio": "string",
+ "probabilisticSharpeRatio": "string",
+ "sortinoRatio": "string",
+ "alpha": "string",
+ "beta": "string",
+ "annualStandardDeviation": "string",
+ "annualVariance": "string",
+ "informationRatio": "string",
+ "trackingError": "string",
+ "treynorRatio": "string",
+ "portfolioTurnover": "string",
+ "valueAtRisk99": "string",
+ "valueAtRisk95": "string",
+ "drawdownRecovery": "string"
+}
+ |
+
+
+ Trade
+
+ Model - Represents a closed trade.
+ |
+ |
|---|---|
| + symbol |
- string
+ Symbol object
- Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance. + Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security. |
| - Annual Standard Deviation + entryTime |
- string
+ string($date-time)
- Annualized standard deviation. + The date and time the trade was opened. |
| - Annual Variance + entryPrice |
- string
+ number
- Annualized variance statistic calculation using the daily performance variance and trading days per year. + The price at which the trade was opened (or the average price if multiple entries). |
| - Information Ratio + direction |
- string
+ integer Enum
- Information ratio - risk adjusted return. + Direction of a trade. 0=Long, 1=Short. Options : [0, 1] |
| - Tracking Error + quantity |
- string
+ number
- Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. + The total unsigned quantity of the trade. |
| - Treynor Ratio + exitTime + | +
+
+ string($date-time)
+
+ + The date and time the trade was closed. + |
+
| + exitPrice + | +
+
+ number
+
+ + The price at which the trade was closed (or the average price if multiple exits). + |
+
| + profitLoss + | +
+
+ number
+
+ + The gross profit/loss of the trade (as account currency). + |
+
| + totalFees + | +
+
+ number
+
+ + The total fees associated with the trade (always positive value) (as account currency). + |
+
| + mae + | +
+
+ number
+
+ + The Maximum Adverse Excursion (as account currency). + |
+
| + mfe + | +
+
+ number
+
+ + The Maximum Favorable Excursion (as account currency). + |
+
| + duration |
string
- Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. + The duration of the trade. |
| - Total Fees + endTradeDrawdown + | +
+
+ number
+
+ + The amount of profit given back before the trade was closed. + |
+
| + Example + | +
+
+
+
+{
+ "symbol": {
+ "value": "string",
+ "id": "string",
+ "permtick": "string"
+ },
+ "entryTime": "2021-11-26T15:18:27.693Z",
+ "entryPrice": 0,
+ "direction": 0,
+ "quantity": 0,
+ "exitTime": "2021-11-26T15:18:27.693Z",
+ "exitPrice": 0,
+ "profitLoss": 0,
+ "totalFees": 0,
+ "mae": 0,
+ "mfe": 0,
+ "duration": "string",
+ "endTradeDrawdown": 0
+}
+ |
+
+
+ Symbol
+
+ Model - Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security.
+ |
+ |
|---|---|
| + value |
string
- Total amount of fees. + The current symbol for this ticker. |
| - Estimated Strategy Capacity + id |
string
- The estimated total capacity of the strategy at a point in time. + The security identifier for this symbol. |
| - Lowest Capacity Asset + permtick |
string
- Provide a reference to the lowest capacity symbol used in scaling down the capacity for debugging. + The ticker at IPO for this security. |
| - Portfolio Turnover + Example + | +
+
+
+
+{
+ "value": "string",
+ "id": "string",
+ "permtick": "string"
+}
+ |
+
+
+ AnalysisResult
+
+ Model - The result of an analysis performed on a result.
+ |
+ ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| + name |
string
+
- The average Portfolio Turnover. + The name of the analysis that produced this result. |
|||||||||
| - Drawdown Recovery + issue |
string
+
- /. + A short description of why the analysis was triggered. + |
+ |||||||||
| + sample + | +
+
+ object
+
+ + A representative sample value of the issue detected by the analysis. + |
+ |||||||||
| + count + | +
+
+ integer
+
+ + The total number of matching occurrences found by the analysis. If not present, it should be assumed that there is only one occurrence. + |
+ |||||||||
| + solutions + | +
+
+ string Array
+
+ + Human-readable suggestions for resolving the detected issue. |
|||||||||
| + analysis + | +
+
+ AnalysisResult Array
+
+ + /. + |
+ |||||||||
Example
@@ -66225,98 +67510,7 @@
},
"parameterSet": ,
"rollingWindow": {
- "tradeStatistics": {
- "startDateTime": "2021-11-26T15:18:27.693Z",
- "endDateTime": "2021-11-26T15:18:27.693Z",
- "totalNumberOfTrades": 0,
- "numberOfWinningTrades": 0,
- "numberOfLosingTrades": 0,
- "totalProfitLoss": "string",
- "totalProfit": "string",
- "totalLoss": "string",
- "largestProfit": "string",
- "largestLoss": "string",
- "averageProfitLoss": "string",
- "averageProfit": "string",
- "averageLoss": "string",
- "averageTradeDuration": "string",
- "averageWinningTradeDuration": "string",
- "averageLosingTradeDuration": "string",
- "medianTradeDuration": "string",
- "medianWinningTradeDuration": "string",
- "medianLosingTradeDuration": "string",
- "maxConsecutiveWinningTrades": 0,
- "maxConsecutiveLosingTrades": 0,
- "profitLossRatio": "string",
- "winLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "averageMAE": "string",
- "averageMFE": "string",
- "largestMAE": "string",
- "largestMFE": "string",
- "maximumClosedTradeDrawdown": "string",
- "maximumIntraTradeDrawdown": "string",
- "profitLossStandardDeviation": "string",
- "profitLossDownsideDeviation": "string",
- "profitFactor": "string",
- "sharpeRatio": "string",
- "sortinoRatio": "string",
- "profitToMaxDrawdownRatio": "string",
- "maximumEndTradeDrawdown": "string",
- "averageEndTradeDrawdown": "string",
- "maximumDrawdownDuration": "string",
- "totalFees": "string"
- },
- "portfolioStatistics": {
- "averageWinRate": "string",
- "averageLossRate": "string",
- "profitLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "expectancy": "string",
- "startEquity": "string",
- "endEquity": "string",
- "compoundingAnnualReturn": "string",
- "drawdown": "string",
- "totalNetProfit": "string",
- "sharpeRatio": "string",
- "probabilisticSharpeRatio": "string",
- "sortinoRatio": "string",
- "alpha": "string",
- "beta": "string",
- "annualStandardDeviation": "string",
- "annualVariance": "string",
- "informationRatio": "string",
- "trackingError": "string",
- "treynorRatio": "string",
- "portfolioTurnover": "string",
- "valueAtRisk99": "string",
- "valueAtRisk95": "string",
- "drawdownRecovery": "string"
- },
- "closedTrades": [
- {
- "symbol": {
- "value": "string",
- "id": "string",
- "permtick": "string"
- },
- "entryTime": "2021-11-26T15:18:27.693Z",
- "entryPrice": 0,
- "direction": 0,
- "quantity": 0,
- "exitTime": "2021-11-26T15:18:27.693Z",
- "exitPrice": 0,
- "profitLoss": 0,
- "totalFees": 0,
- "mae": 0,
- "mfe": 0,
- "duration": "string",
- "endTradeDrawdown": 0
- }
- ]
- },
+},
"runtimeStatistics": {
"Equity": "$100.00",
"Fees": "-$100.00",
@@ -66451,7 +67645,21 @@ |
@@ -66562,1223 +67770,1204 @@ ||||||||||
- AlgorithmPerformance
+ RuntimeStatistics
- Model - The AlgorithmPerformance class is a wrapper for TradeStatistics and PortfolioStatistics.
+ Model
|
||||||||||
| - tradeStatistics + Equity |
- TradeStatistics object
+ string
+
- A set of statistics calculated from a list of closed trades. + Total portfolio value. |
|||||||||
| - portfolioStatistics + Fees |
- PortfolioStatistics object
+ string
+
- Represents a set of statistics calculated from equity and benchmark samples. + Transaction fee. |
|||||||||
| - closedTrades + Holdings |
- Trade Array
+ string
+
- The algorithm statistics on portfolio. + Equity value of security holdings. |
|||||||||
| - Example + Net Profit |
-
-
+
-{
- "tradeStatistics": {
- "startDateTime": "2021-11-26T15:18:27.693Z",
- "endDateTime": "2021-11-26T15:18:27.693Z",
- "totalNumberOfTrades": 0,
- "numberOfWinningTrades": 0,
- "numberOfLosingTrades": 0,
- "totalProfitLoss": "string",
- "totalProfit": "string",
- "totalLoss": "string",
- "largestProfit": "string",
- "largestLoss": "string",
- "averageProfitLoss": "string",
- "averageProfit": "string",
- "averageLoss": "string",
- "averageTradeDuration": "string",
- "averageWinningTradeDuration": "string",
- "averageLosingTradeDuration": "string",
- "medianTradeDuration": "string",
- "medianWinningTradeDuration": "string",
- "medianLosingTradeDuration": "string",
- "maxConsecutiveWinningTrades": 0,
- "maxConsecutiveLosingTrades": 0,
- "profitLossRatio": "string",
- "winLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "averageMAE": "string",
- "averageMFE": "string",
- "largestMAE": "string",
- "largestMFE": "string",
- "maximumClosedTradeDrawdown": "string",
- "maximumIntraTradeDrawdown": "string",
- "profitLossStandardDeviation": "string",
- "profitLossDownsideDeviation": "string",
- "profitFactor": "string",
- "sharpeRatio": "string",
- "sortinoRatio": "string",
- "profitToMaxDrawdownRatio": "string",
- "maximumEndTradeDrawdown": "string",
- "averageEndTradeDrawdown": "string",
- "maximumDrawdownDuration": "string",
- "totalFees": "string"
- },
- "portfolioStatistics": {
- "averageWinRate": "string",
- "averageLossRate": "string",
- "profitLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "expectancy": "string",
- "startEquity": "string",
- "endEquity": "string",
- "compoundingAnnualReturn": "string",
- "drawdown": "string",
- "totalNetProfit": "string",
- "sharpeRatio": "string",
- "probabilisticSharpeRatio": "string",
- "sortinoRatio": "string",
- "alpha": "string",
- "beta": "string",
- "annualStandardDeviation": "string",
- "annualVariance": "string",
- "informationRatio": "string",
- "trackingError": "string",
- "treynorRatio": "string",
- "portfolioTurnover": "string",
- "valueAtRisk99": "string",
- "valueAtRisk95": "string",
- "drawdownRecovery": "string"
- },
- "closedTrades": [
- {
- "symbol": {
- "value": "string",
- "id": "string",
- "permtick": "string"
- },
- "entryTime": "2021-11-26T15:18:27.693Z",
- "entryPrice": 0,
- "direction": 0,
- "quantity": 0,
- "exitTime": "2021-11-26T15:18:27.693Z",
- "exitPrice": 0,
- "profitLoss": 0,
- "totalFees": 0,
- "mae": 0,
- "mfe": 0,
- "duration": "string",
- "endTradeDrawdown": 0
- }
- ]
-}
-
+ string
+
+ + Net profit. |
|||||||||
-
- TradeStatistics
-
- Model - A set of statistics calculated from a list of closed trades.
- |
- |
|---|---|
| - startDateTime + Probabilistic Sharpe Ratio |
- string($date-time)
+ string
+
- The entry date/time of the first trade. + Probabilistic Sharpe Ratio. |
| - endDateTime + Return |
- string($date-time)
+ string
+
- The exit date/time of the first trade. + Return. |
| - totalNumberOfTrades + Unrealized |
- integer
+ string
+
- The total number of trades. + Unrealized profit/loss. |
| - numberOfWinningTrades + Volume |
- integer
+ string
+
- The total number of winning trades. + Total transaction volume. |
| - numberOfLosingTrades + Example |
-
- integer
-
- - The total number of losing trades. +
+
+{
+ "Equity": "$100.00",
+ "Fees": "-$100.00",
+ "Holdings": "$100.00",
+ "Net Profit": "$100.00",
+ "Probabilistic Sharpe Ratio": "50.00%",
+ "Return": "50.00%",
+ "Unrealized": "$100.00",
+ "Volume": "$100.00"
+}
+ |
+
+ StatisticsResult
+
+ Model - Statistics information sent during the algorithm operations.
+ |
+ |
|---|---|
| - totalProfitLoss + Total Orders |
string
- The total profit/loss for all trades (as symbol currency). + Total nuber of orders. |
| - totalProfit + Average Win |
string
- The total profit for all winning trades (as symbol currency). + The average rate of return for winning trades. |
| - totalLoss + Average Loss |
string
- The total loss for all losing trades (as symbol currency). + The average rate of return for losing trades. |
| - largestProfit + Compounding Annual Return |
string
- The largest profit in a single trade (as symbol currency). + Annual compounded returns statistic based on the final-starting capital and years. |
| - largestLoss + Drawdown |
string
- The largest loss in a single trade (as symbol currency). + Drawdown maximum percentage. |
| - averageProfitLoss + Expectancy |
string
- The average profit/loss (a.k.a. Expectancy or Average Trade) for all trades (as symbol currency). + The expected value of the rate of return. |
| - averageProfit + Start Equity |
string
- The average profit for all winning trades (as symbol currency). + Initial Equity Total Value. |
| - averageLoss + End Equity |
string
- The average loss for all winning trades (as symbol currency). + Final Equity Total Value. |
| - averageTradeDuration + Net Profit |
string
- The average duration for all trades. + The total net profit percentage. |
| - averageWinningTradeDuration + Sharpe Ratio |
string
- The average duration for all winning trades. + Sharpe ratio with respect to risk free rate; measures excess of return per unit of risk. |
| - averageLosingTradeDuration + Sortino Ratio |
string
- The average duration for all losing trades. + Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. |
| - medianTradeDuration + Probabilistic Sharpe Ratio |
string
- The median duration for all trades. + Is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. |
| - medianWinningTradeDuration + Loss Rate |
string
- The median duration for all winning trades. + The ratio of the number of losing trades to the total number of trades. |
| - medianLosingTradeDuration + Win Rate |
string
- The median duration for all losing trades. + The ratio of the number of winning trades to the total number of trades. |
| - maxConsecutiveWinningTrades + Profit-Loss Ratio |
- integer
+ string
- The maximum number of consecutive winning trades. + The ratio of the average win rate to the average loss rate. |
| - maxConsecutiveLosingTrades + Alpha |
- integer
+ string
- The maximum number of consecutive losing trades. + Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. |
| - profitLossRatio + Beta |
string
- The ratio of the average profit per trade to the average loss per trade. + Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance. |
| - winLossRatio + Annual Standard Deviation |
string
- The ratio of the number of winning trades to the number of losing trades. + Annualized standard deviation. |
| - winRate + Annual Variance |
string
- The ratio of the number of winning trades to the total number of trades. + Annualized variance statistic calculation using the daily performance variance and trading days per year. |
| - lossRate + Information Ratio |
string
- The ratio of the number of losing trades to the total number of trades. + Information ratio - risk adjusted return. |
| - averageMAE + Tracking Error |
string
- The average Maximum Adverse Excursion for all trades. + Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. |
| - averageMFE + Treynor Ratio |
string
- The average Maximum Adverse Excursion for all trades. + Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. |
| - largestMAE + Total Fees |
string
- The average Maximum Favorable Excursion for all trades. + Total amount of fees. |
| - largestMFE + Estimated Strategy Capacity |
string
- The largest Maximum Adverse Excursion in a single trade (as symbol currency). + The estimated total capacity of the strategy at a point in time. |
| - maximumClosedTradeDrawdown + Lowest Capacity Asset |
string
- The maximum closed-trade drawdown for all trades (as symbol currency). + Provide a reference to the lowest capacity symbol used in scaling down the capacity for debugging. |
| - maximumIntraTradeDrawdown + Portfolio Turnover |
string
- The maximum intra-trade drawdown for all trades (as symbol currency). + The average Portfolio Turnover. |
| - profitLossStandardDeviation + Drawdown Recovery |
string
- The standard deviation of the profits/losses for all trades (as symbol currency). + /. |
| - profitLossDownsideDeviation + Example |
-
- string
-
- - The downside deviation of the profits/losses for all trades (as symbol currency). +
+
+{
+ "Total Orders": "string",
+ "Average Win": "string",
+ "Average Loss": "string",
+ "Compounding Annual Return": "string",
+ "Drawdown": "string",
+ "Expectancy": "string",
+ "Start Equity": "string",
+ "End Equity": "string",
+ "Net Profit": "string",
+ "Sharpe Ratio": "string",
+ "Sortino Ratio": "string",
+ "Probabilistic Sharpe Ratio": "string",
+ "Loss Rate": "string",
+ "Win Rate": "string",
+ "Profit-Loss Ratio": "string",
+ "Alpha": "string",
+ "Beta": "string",
+ "Annual Standard Deviation": "string",
+ "Annual Variance": "string",
+ "Information Ratio": "string",
+ "Tracking Error": "string",
+ "Treynor Ratio": "string",
+ "Total Fees": "string",
+ "Estimated Strategy Capacity": "string",
+ "Lowest Capacity Asset": "string",
+ "Portfolio Turnover": "string",
+ "Drawdown Recovery": "string"
+}
+ |
+
+ AlgorithmPerformance
+
+ Model - The AlgorithmPerformance class is a wrapper for TradeStatistics and PortfolioStatistics.
+ |
+ |
|---|---|
| - profitFactor + tradeStatistics |
- string
+ TradeStatistics object
- The ratio of the total profit to the total loss. + A set of statistics calculated from a list of closed trades. |
| - sharpeRatio + portfolioStatistics |
- string
+ PortfolioStatistics object
- The ratio of the average profit/loss to the standard deviation. + Represents a set of statistics calculated from equity and benchmark samples. |
| - sortinoRatio + closedTrades |
- string
+ Trade Array
- The ratio of the average profit/loss to the downside deviation. + The algorithm statistics on portfolio. |
| - profitToMaxDrawdownRatio + Example |
-
- string
-
- - The ratio of the total profit/loss to the maximum closed trade drawdown. +
+
+{
+ "tradeStatistics": {
+ "startDateTime": "2021-11-26T15:18:27.693Z",
+ "endDateTime": "2021-11-26T15:18:27.693Z",
+ "totalNumberOfTrades": 0,
+ "numberOfWinningTrades": 0,
+ "numberOfLosingTrades": 0,
+ "totalProfitLoss": "string",
+ "totalProfit": "string",
+ "totalLoss": "string",
+ "largestProfit": "string",
+ "largestLoss": "string",
+ "averageProfitLoss": "string",
+ "averageProfit": "string",
+ "averageLoss": "string",
+ "averageTradeDuration": "string",
+ "averageWinningTradeDuration": "string",
+ "averageLosingTradeDuration": "string",
+ "medianTradeDuration": "string",
+ "medianWinningTradeDuration": "string",
+ "medianLosingTradeDuration": "string",
+ "maxConsecutiveWinningTrades": 0,
+ "maxConsecutiveLosingTrades": 0,
+ "profitLossRatio": "string",
+ "winLossRatio": "string",
+ "winRate": "string",
+ "lossRate": "string",
+ "averageMAE": "string",
+ "averageMFE": "string",
+ "largestMAE": "string",
+ "largestMFE": "string",
+ "maximumClosedTradeDrawdown": "string",
+ "maximumIntraTradeDrawdown": "string",
+ "profitLossStandardDeviation": "string",
+ "profitLossDownsideDeviation": "string",
+ "profitFactor": "string",
+ "sharpeRatio": "string",
+ "sortinoRatio": "string",
+ "profitToMaxDrawdownRatio": "string",
+ "maximumEndTradeDrawdown": "string",
+ "averageEndTradeDrawdown": "string",
+ "maximumDrawdownDuration": "string",
+ "totalFees": "string"
+ },
+ "portfolioStatistics": {
+ "averageWinRate": "string",
+ "averageLossRate": "string",
+ "profitLossRatio": "string",
+ "winRate": "string",
+ "lossRate": "string",
+ "expectancy": "string",
+ "startEquity": "string",
+ "endEquity": "string",
+ "compoundingAnnualReturn": "string",
+ "drawdown": "string",
+ "totalNetProfit": "string",
+ "sharpeRatio": "string",
+ "probabilisticSharpeRatio": "string",
+ "sortinoRatio": "string",
+ "alpha": "string",
+ "beta": "string",
+ "annualStandardDeviation": "string",
+ "annualVariance": "string",
+ "informationRatio": "string",
+ "trackingError": "string",
+ "treynorRatio": "string",
+ "portfolioTurnover": "string",
+ "valueAtRisk99": "string",
+ "valueAtRisk95": "string",
+ "drawdownRecovery": "string"
+ },
+ "closedTrades": [
+ {
+ "symbol": {
+ "value": "string",
+ "id": "string",
+ "permtick": "string"
+ },
+ "entryTime": "2021-11-26T15:18:27.693Z",
+ "entryPrice": 0,
+ "direction": 0,
+ "quantity": 0,
+ "exitTime": "2021-11-26T15:18:27.693Z",
+ "exitPrice": 0,
+ "profitLoss": 0,
+ "totalFees": 0,
+ "mae": 0,
+ "mfe": 0,
+ "duration": "string",
+ "endTradeDrawdown": 0
+ }
+ ]
+}
+ |
+
+ TradeStatistics
+
+ Model - A set of statistics calculated from a list of closed trades.
+ |
+ |
|---|---|
| - maximumEndTradeDrawdown + startDateTime |
- string
+ string($date-time)
- The maximum amount of profit given back by a single trade before exit (as symbol currency). + The entry date/time of the first trade. |
| - averageEndTradeDrawdown + endDateTime |
- string
+ string($date-time)
- The average amount of profit given back by all trades before exit (as symbol currency). + The exit date/time of the first trade. |
| - maximumDrawdownDuration + totalNumberOfTrades |
- string
+ integer
- The maximum amount of time to recover from a drawdown (longest time between new equity highs or peaks). + The total number of trades. |
| - totalFees + numberOfWinningTrades |
- string
+ integer
- The sum of fees for all trades. + The total number of winning trades. |
| - Example + numberOfLosingTrades |
-
-
+
-{
- "startDateTime": "2021-11-26T15:18:27.693Z",
- "endDateTime": "2021-11-26T15:18:27.693Z",
- "totalNumberOfTrades": 0,
- "numberOfWinningTrades": 0,
- "numberOfLosingTrades": 0,
- "totalProfitLoss": "string",
- "totalProfit": "string",
- "totalLoss": "string",
- "largestProfit": "string",
- "largestLoss": "string",
- "averageProfitLoss": "string",
- "averageProfit": "string",
- "averageLoss": "string",
- "averageTradeDuration": "string",
- "averageWinningTradeDuration": "string",
- "averageLosingTradeDuration": "string",
- "medianTradeDuration": "string",
- "medianWinningTradeDuration": "string",
- "medianLosingTradeDuration": "string",
- "maxConsecutiveWinningTrades": 0,
- "maxConsecutiveLosingTrades": 0,
- "profitLossRatio": "string",
- "winLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "averageMAE": "string",
- "averageMFE": "string",
- "largestMAE": "string",
- "largestMFE": "string",
- "maximumClosedTradeDrawdown": "string",
- "maximumIntraTradeDrawdown": "string",
- "profitLossStandardDeviation": "string",
- "profitLossDownsideDeviation": "string",
- "profitFactor": "string",
- "sharpeRatio": "string",
- "sortinoRatio": "string",
- "profitToMaxDrawdownRatio": "string",
- "maximumEndTradeDrawdown": "string",
- "averageEndTradeDrawdown": "string",
- "maximumDrawdownDuration": "string",
- "totalFees": "string"
-}
-
+ integer
+
+ + The total number of losing trades. |
-
- PortfolioStatistics
-
- Model - Represents a set of statistics calculated from equity and benchmark samples.
- |
- |
|---|---|
| - averageWinRate + totalProfitLoss |
string
- The average rate of return for winning trades. + The total profit/loss for all trades (as symbol currency). |
| - averageLossRate + totalProfit |
string
- The average rate of return for losing trades. + The total profit for all winning trades (as symbol currency). |
| - profitLossRatio + totalLoss |
string
- The ratio of the average win rate to the average loss rate. + The total loss for all losing trades (as symbol currency). |
| - winRate + largestProfit |
string
- The ratio of the number of winning trades to the total number of trades. + The largest profit in a single trade (as symbol currency). |
| - lossRate + largestLoss |
string
- The ratio of the number of losing trades to the total number of trades. + The largest loss in a single trade (as symbol currency). |
| - expectancy + averageProfitLoss |
string
- The expected value of the rate of return. + The average profit/loss (a.k.a. Expectancy or Average Trade) for all trades (as symbol currency). |
| - startEquity + averageProfit |
string
- Initial Equity Total Value. + The average profit for all winning trades (as symbol currency). |
| - endEquity + averageLoss |
string
- Final Equity Total Value. + The average loss for all winning trades (as symbol currency). |
| - compoundingAnnualReturn + averageTradeDuration |
string
- Annual compounded returns statistic based on the final-starting capital and years. + The average duration for all trades. |
| - drawdown + averageWinningTradeDuration |
string
- Drawdown maximum percentage. + The average duration for all winning trades. |
| - totalNetProfit + averageLosingTradeDuration |
string
- The total net profit percentage. + The average duration for all losing trades. |
| - sharpeRatio + medianTradeDuration |
string
- Sharpe ratio with respect to risk free rate: measures excess of return per unit of risk. + The median duration for all trades. |
| - probabilisticSharpeRatio + medianWinningTradeDuration |
string
- Probabilistic Sharpe Ratio is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. + The median duration for all winning trades. |
| - sortinoRatio + medianLosingTradeDuration |
string
- Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. + The median duration for all losing trades. |
| - alpha + maxConsecutiveWinningTrades |
- string
+ integer
- Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. + The maximum number of consecutive winning trades. |
| - beta + maxConsecutiveLosingTrades |
- string
+ integer
- Algorithm beta statistic - the covariance between the algorithm and benchmark performance, divided by benchmark variance. + The maximum number of consecutive losing trades. |
| - annualStandardDeviation + profitLossRatio |
string
- Annualized standard deviation. + The ratio of the average profit per trade to the average loss per trade. |
| - annualVariance + winLossRatio |
string
- Annualized variance statistic calculation using the daily performance variance and trading days per year. + The ratio of the number of winning trades to the number of losing trades. |
| - informationRatio + winRate |
string
- Information ratio - risk adjusted return. + The ratio of the number of winning trades to the total number of trades. |
| - trackingError + lossRate |
string
- Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. + The ratio of the number of losing trades to the total number of trades. |
| - treynorRatio + averageMAE |
string
- Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. + The average Maximum Adverse Excursion for all trades. |
| - portfolioTurnover + averageMFE |
string
- The average Portfolio Turnover. + The average Maximum Adverse Excursion for all trades. |
| - valueAtRisk99 + largestMAE |
string
- The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 99% confidence level, 1 year lookback period, and that the returns are normally distributed. + The average Maximum Favorable Excursion for all trades. |
| - valueAtRisk95 + largestMFE |
string
- The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 95% confidence level, 1 year lookback period, and that the returns are normally distributed. + The largest Maximum Adverse Excursion in a single trade (as symbol currency). |
| - drawdownRecovery + maximumClosedTradeDrawdown |
string
- /. + The maximum closed-trade drawdown for all trades (as symbol currency). |
| - Example + maximumIntraTradeDrawdown |
-
-
+
-{
- "averageWinRate": "string",
- "averageLossRate": "string",
- "profitLossRatio": "string",
- "winRate": "string",
- "lossRate": "string",
- "expectancy": "string",
- "startEquity": "string",
- "endEquity": "string",
- "compoundingAnnualReturn": "string",
- "drawdown": "string",
- "totalNetProfit": "string",
- "sharpeRatio": "string",
- "probabilisticSharpeRatio": "string",
- "sortinoRatio": "string",
- "alpha": "string",
- "beta": "string",
- "annualStandardDeviation": "string",
- "annualVariance": "string",
- "informationRatio": "string",
- "trackingError": "string",
- "treynorRatio": "string",
- "portfolioTurnover": "string",
- "valueAtRisk99": "string",
- "valueAtRisk95": "string",
- "drawdownRecovery": "string"
-}
-
+ string
+
+ + The maximum intra-trade drawdown for all trades (as symbol currency). |
-
- Trade
-
- Model - Represents a closed trade.
- |
- |||||||||
|---|---|---|---|---|---|---|---|---|---|
| - symbol + profitLossStandardDeviation |
- Symbol object
+ string
- Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security. + The standard deviation of the profits/losses for all trades (as symbol currency). |
||||||||
| - entryTime + profitLossDownsideDeviation |
- string($date-time)
+ string
- The date and time the trade was opened. - |
- ||||||||
| - entryPrice - | -
-
- number
-
- - The price at which the trade was opened (or the average price if multiple entries). - |
- ||||||||
| - direction - | -
-
- integer Enum
-
- - Direction of a trade. 0=Long, 1=Short. Options : [0, 1] - |
- ||||||||
| - quantity - | -
-
- number
-
- - The total unsigned quantity of the trade. + The downside deviation of the profits/losses for all trades (as symbol currency). |
||||||||
| - exitTime + profitFactor |
- string($date-time)
+ string
- The date and time the trade was closed. + The ratio of the total profit to the total loss. |
||||||||
| - exitPrice + sharpeRatio |
- number
+ string
- The price at which the trade was closed (or the average price if multiple exits). + The ratio of the average profit/loss to the standard deviation. |
||||||||
| - profitLoss + sortinoRatio |
- number
+ string
- The gross profit/loss of the trade (as account currency). + The ratio of the average profit/loss to the downside deviation. |
||||||||
| - totalFees + profitToMaxDrawdownRatio |
- number
+ string
- The total fees associated with the trade (always positive value) (as account currency). + The ratio of the total profit/loss to the maximum closed trade drawdown. |
||||||||
| - mae + maximumEndTradeDrawdown |
- number
+ string
- The Maximum Adverse Excursion (as account currency). + The maximum amount of profit given back by a single trade before exit (as symbol currency). |
||||||||
| - mfe + averageEndTradeDrawdown |
- number
+ string
- The Maximum Favorable Excursion (as account currency). + The average amount of profit given back by all trades before exit (as symbol currency). |
||||||||
| - duration + maximumDrawdownDuration |
string
- The duration of the trade. + The maximum amount of time to recover from a drawdown (longest time between new equity highs or peaks). |
||||||||
| - endTradeDrawdown + totalFees |
- number
+ string
- The amount of profit given back before the trade was closed. + The sum of fees for all trades. |
||||||||
- Symbol
+ PortfolioStatistics
- Model - Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security.
+ Model - Represents a set of statistics calculated from equity and benchmark samples.
|
|||||||||
| - value + averageWinRate |
string
- The current symbol for this ticker. + The average rate of return for winning trades. |
||||||||
| - id + averageLossRate |
string
- The security identifier for this symbol. + The average rate of return for losing trades. |
||||||||
| - permtick + profitLossRatio |
string
- The ticker at IPO for this security. - |
- ||||||||
| - Example - | -
-
-
+ The ratio of the average win rate to the average loss rate.
-{
- "value": "string",
- "id": "string",
- "permtick": "string"
-}
- |
||||||||
-
- RuntimeStatistics
-
- Model
- |
- |
|---|---|
| - Equity + winRate |
string
-
- Total portfolio value. + The ratio of the number of winning trades to the total number of trades. |
| - Fees + lossRate |
string
-
- Transaction fee. + The ratio of the number of losing trades to the total number of trades. |
| - Holdings + expectancy |
string
-
- Equity value of security holdings. + The expected value of the rate of return. |
| - Net Profit + startEquity |
string
-
- Net profit. + Initial Equity Total Value. |
| - Probabilistic Sharpe Ratio + endEquity |
string
-
- Probabilistic Sharpe Ratio. + Final Equity Total Value. |
| - Return + compoundingAnnualReturn |
string
-
- Return. + Annual compounded returns statistic based on the final-starting capital and years. |
| - Unrealized + drawdown |
string
-
- Unrealized profit/loss. + Drawdown maximum percentage. |
| - Volume + totalNetProfit |
string
-
- Total transaction volume. + The total net profit percentage. |
| - Example + sharpeRatio |
-
-
+
-{
- "Equity": "$100.00",
- "Fees": "-$100.00",
- "Holdings": "$100.00",
- "Net Profit": "$100.00",
- "Probabilistic Sharpe Ratio": "50.00%",
- "Return": "50.00%",
- "Unrealized": "$100.00",
- "Volume": "$100.00"
-}
-
+ string
+
+ + Sharpe ratio with respect to risk free rate: measures excess of return per unit of risk. |
-
- StatisticsResult
-
- Model - Statistics information sent during the algorithm operations.
- |
- |
|---|---|
| - Total Orders + probabilisticSharpeRatio |
string
- Total nuber of orders. + Probabilistic Sharpe Ratio is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. |
| - Average Win + sortinoRatio |
string
- The average rate of return for winning trades. + Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. |
| - Average Loss + alpha |
string
- The average rate of return for losing trades. + Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. |
| - Compounding Annual Return + beta |
string
- Annual compounded returns statistic based on the final-starting capital and years. + Algorithm beta statistic - the covariance between the algorithm and benchmark performance, divided by benchmark variance. |
| - Drawdown + annualStandardDeviation |
string
- Drawdown maximum percentage. + Annualized standard deviation. |
| - Expectancy + annualVariance |
string
- The expected value of the rate of return. + Annualized variance statistic calculation using the daily performance variance and trading days per year. |
| - Start Equity + informationRatio |
string
- Initial Equity Total Value. + Information ratio - risk adjusted return. |
| - End Equity + trackingError |
string
- Final Equity Total Value. + Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. |
| - Net Profit + treynorRatio |
string
- The total net profit percentage. + Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. |
| - Sharpe Ratio + portfolioTurnover |
string
- Sharpe ratio with respect to risk free rate; measures excess of return per unit of risk. + The average Portfolio Turnover. |
| - Sortino Ratio + valueAtRisk99 |
string
- Sortino ratio with respect to risk free rate; measures excess of return per unit of downside risk. + The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 99% confidence level, 1 year lookback period, and that the returns are normally distributed. |
| - Probabilistic Sharpe Ratio + valueAtRisk95 |
string
- Is a probability measure associated with the Sharpe ratio. It informs us of the probability that the estimated Sharpe ratio is greater than a chosen benchmark. + The 1-day VaR for the portfolio, using the Variance-covariance approach. Assumes a 95% confidence level, 1 year lookback period, and that the returns are normally distributed. |
| - Loss Rate + drawdownRecovery |
string
- The ratio of the number of losing trades to the total number of trades. + /. |
| - Win Rate + Example |
-
- string
-
- - The ratio of the number of winning trades to the total number of trades. +
+
+{
+ "averageWinRate": "string",
+ "averageLossRate": "string",
+ "profitLossRatio": "string",
+ "winRate": "string",
+ "lossRate": "string",
+ "expectancy": "string",
+ "startEquity": "string",
+ "endEquity": "string",
+ "compoundingAnnualReturn": "string",
+ "drawdown": "string",
+ "totalNetProfit": "string",
+ "sharpeRatio": "string",
+ "probabilisticSharpeRatio": "string",
+ "sortinoRatio": "string",
+ "alpha": "string",
+ "beta": "string",
+ "annualStandardDeviation": "string",
+ "annualVariance": "string",
+ "informationRatio": "string",
+ "trackingError": "string",
+ "treynorRatio": "string",
+ "portfolioTurnover": "string",
+ "valueAtRisk99": "string",
+ "valueAtRisk95": "string",
+ "drawdownRecovery": "string"
+}
+ |
+
+ Trade
+
+ Model - Represents a closed trade.
+ |
+ |
|---|---|
| - Profit-Loss Ratio + symbol |
- string
+ Symbol object
- The ratio of the average win rate to the average loss rate. + Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security. |
| - Alpha + entryTime |
- string
+ string($date-time)
- Algorithm "Alpha" statistic - abnormal returns over the risk free rate and the relationshio (beta) with the benchmark returns. + The date and time the trade was opened. |
| - Beta + entryPrice |
- string
+ number
- Algorithm "beta" statistic - the covariance between the algorithm and benchmark performance, divided by benchmark's variance. + The price at which the trade was opened (or the average price if multiple entries). |
| - Annual Standard Deviation + direction |
- string
+ integer Enum
- Annualized standard deviation. + Direction of a trade. 0=Long, 1=Short. Options : [0, 1] |
| - Annual Variance + quantity |
- string
+ number
- Annualized variance statistic calculation using the daily performance variance and trading days per year. + The total unsigned quantity of the trade. |
| - Information Ratio + exitTime |
- string
+ string($date-time)
- Information ratio - risk adjusted return. + The date and time the trade was closed. |
| - Tracking Error + exitPrice |
- string
+ number
- Tracking error volatility (TEV) statistic - a measure of how closely a portfolio follows the index to which it is benchmarked. + The price at which the trade was closed (or the average price if multiple exits). |
| - Treynor Ratio + profitLoss |
- string
+ number
- Treynor ratio statistic is a measurement of the returns earned in excess of that which could have been earned on an investment that has no diversifiable risk. + The gross profit/loss of the trade (as account currency). |
| - Total Fees + totalFees |
- string
+ number
- Total amount of fees. + The total fees associated with the trade (always positive value) (as account currency). |
| - Estimated Strategy Capacity + mae |
- string
+ number
- The estimated total capacity of the strategy at a point in time. + The Maximum Adverse Excursion (as account currency). |
| - Lowest Capacity Asset + mfe |
- string
+ number
- Provide a reference to the lowest capacity symbol used in scaling down the capacity for debugging. + The Maximum Favorable Excursion (as account currency). |
| - Portfolio Turnover + duration |
string
- The average Portfolio Turnover. + The duration of the trade. |
| - Drawdown Recovery + endTradeDrawdown |
- string
+ number
- /. + The amount of profit given back before the trade was closed. |
| + "symbol": { + "value": "string", + "id": "string", + "permtick": "string" + }, + "entryTime": "2021-11-26T15:18:27.693Z", + "entryPrice": 0, + "direction": 0, + "quantity": 0, + "exitTime": "2021-11-26T15:18:27.693Z", + "exitPrice": 0, + "profitLoss": 0, + "totalFees": 0, + "mae": 0, + "mfe": 0, + "duration": "string", + "endTradeDrawdown": 0 +} + + + |
|---|
+
+ Symbol
+
+ Model - Represents a unique security identifier. This is made of two components, the unique SID and the Value. The value is the current ticker symbol while the SID is constant over the life of a security.
+ |
+ |
|---|---|
| + value + | +
+
+ string
+
+ + The current symbol for this ticker. + |
+
| + id + | +
+
+ string
+
+ + The security identifier for this symbol. + |
+
| + permtick + | +
+
+ string
+
+ + The ticker at IPO for this security. + |
+
| + Example + | +
+
+
+
+{
+ "value": "string",
+ "id": "string",
+ "permtick": "string"
+}
+ |
+
+
+ AnalysisResult
+
+ Model - The result of an analysis performed on a result.
+ |
+ |
|---|---|
| + name + | +
+
+ string
+
+ + The name of the analysis that produced this result. + |
+
| + issue + | +
+
+ string
+
+ + A short description of why the analysis was triggered. + |
+
| + sample + | +
+
+ object
+
+ + A representative sample value of the issue detected by the analysis. + |
+
| + count + | +
+
+ integer
+
+ + The total number of matching occurrences found by the analysis. If not present, it should be assumed that there is only one occurrence. + |
+
| + solutions + | +
+
+ string Array
+
+ + Human-readable suggestions for resolving the detected issue. + |
+
| + Example + | +
+
+
+
+{
+ "name": "PerformanceRelativeToBenchmarkAnalysis",
+ "issue": "The strategy has a lower Sharpe ratio than the benchmark.",
+ "sample": {
+ "backtestSharpe": -0.2281345806218534,
+ "benchmarkSharpe": -0.22182175736916387
+ },
+ "count": 5,
+ "solutions": [
+ "Try adjusting the trading rules and/or the universe to get a strategy that outperforms the benchmark."
+ ]
+}
+ |
+
UnauthorizedError
@@ -68582,7 +69932,7 @@ Examples
-
- Read BacktestChartsExamplesprint("List of Backtests:") print(result)- The following example demonstrates how to read and plot chart data from a backtest through the cloud API. - -
-
from base64 import b64encode
-from hashlib import sha256
-from time import time
-from requests import get, post
-BASE_URL = 'https://www.quantconnect.com/api/v2/'
-
-# You need to replace these with your actual credentials.
-# You can request your credentials at https://www.quantconnect.com/settings/
-# You can find our organization ID at https://www.quantconnect.com/organization/
-USER_ID = 0
-API_TOKEN = '____'
-ORGANIZATION_ID = '____'
-
-def get_headers():
- # Get timestamp
- timestamp = f'{int(time())}'
- time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
-
- # Get hased API token
- hashed_token = sha256(time_stamped_token).hexdigest()
- authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
- authentication = b64encode(authentication).decode('ascii')
-
- # Create headers dictionary.
- return {
- 'Authorization': f'Basic {authentication}',
- 'Timestamp': timestamp
- }
-
-# Authenticate to verify credentials
-response = post(f'{BASE_URL}/authenticate', headers = get_headers())
-print(response.json())
-
-# --------------------
-
-from time import sleep
-import matplotlib.pyplot as plt
-import matplotlib.dates as mdates
-from datetime import datetime, timedelta
-
-# The project and backtest ID of the backtest
-project_id = 12345678
-backtest_id = "..."
-
-### Read Backtest Chart
-# Define the chart name to retrieve
-chart_name = "Strategy Equity"
-# Prepare data payload to fetch chart data
-payload = {
- "projectId": project_id, # ID of the project
- "backtestId": backtest_id, # ID of the backtest
- "name": chart_name, # Name of the chart to retrieve
- "count": 500, # Number of data points to fetch
- "start": 1717801200, # Start time in Unix timestamp
- "end": 1743462000 # End time in Unix timestamp
-}
-# Retry up to 10 times if the chart data is still loading
-for attempt in range(10):
- # Send a POST request to the /backtests/chart/read endpoint
- response = post(f'{BASE_URL}/backtests/chart/read', headers=get_headers(), json=payload)
- # Parse the JSON response
- result = response.json()
- # Check if the data is still loading
- if result.get('status') == 'loading':
- print(f"Chart data is loading... Progress: {result['progress']}% (attempt {attempt + 1}/10)")
- sleep(10)
- continue
- break
-
-# If the request was successful, extract and plot the chart data
-if result['success']:
- chart = result['chart']
- # Filter to series with plottable list data points
- series_items = [(name, data) for name, data in chart['series'].items()
- if data['values'] and isinstance(data['values'][0], list)]
- if not series_items:
- print("No series data available in the chart.")
- else:
- # Create a subplot for each series
- fig, axes = plt.subplots(len(series_items), 1, figsize=(12, 4 * len(series_items)), sharex=True)
- if len(series_items) == 1:
- axes = [axes]
- for ax, (series_name, series_data) in zip(axes, series_items):
- values = series_data['values']
- # Check if the data is OHLC (5 elements: timestamp, open, high, low, close)
- is_ohlc = len(values[0]) == 5
- if is_ohlc:
- # Filter out data points with None values
- valid = [p for p in values if None not in p[1:]]
- if not valid:
- ax.set_title(f"{series_name} (no valid data)")
- continue
- timestamps = [datetime.utcfromtimestamp(p[0]) for p in valid]
- dates = mdates.date2num(timestamps)
- # Calculate bar width as 60% of the average interval between points
- bar_width = (dates[-1] - dates[0]) / len(dates) * 0.6
- for i, point in enumerate(valid):
- _, o, h, l, c = point
- color = 'green' if c >= o else 'red'
- # Draw the high-low wick
- ax.vlines(dates[i], l, h, color=color, linewidth=0.8)
- # Draw the open-close body
- ax.bar(dates[i], abs(c - o) or 0.01, bottom=min(o, c),
- width=bar_width, color=color, edgecolor=color)
- ax.xaxis_date()
- ax.set_ylabel("Price")
- else:
- # Filter out data points with None values
- valid = [p for p in values if p[1] is not None]
- timestamps = [datetime.utcfromtimestamp(p[0]) for p in valid]
- y_values = [p[1] for p in valid]
- ax.plot(timestamps, y_values)
- ax.set_ylabel("Value")
- ax.set_title(series_name)
- ax.tick_params(axis='x', rotation=45)
- fig.suptitle(chart_name, fontsize=14)
- plt.tight_layout()
- plt.savefig(f"{project_id}-{backtest_id}-{chart_name.replace(' ', '_')}.png")
- plt.show()
-
- Read BacktestOrdersExamples
- Read BacktestInsightsExamples
- Backtest ManagementUpdate BacktestExamples
- Backtest ManagementDelete BacktestExamples
- Backtest ManagementList BacktestsExamples
- API ReferenceLive ManagementLive Management
-
+
Create Live Algorithm
@@ -73135,7 +74361,7 @@
-
+
Read Live Algorithm
@@ -73146,7 +74372,7 @@
-
+
Update Live Algorithm
@@ -73157,7 +74383,7 @@
-
+
List Live Algorithms
@@ -73168,7 +74394,7 @@
-
+
Live Commands
@@ -73185,7 +74411,7 @@
- Live ManagementCreate Live AlgorithmExamples
| ||||||
|---|---|---|---|---|---|---|
| + algorithmId + | +
+
+ string
+
+ + Deploy Id (Algorithm Id) of the live running algorithm. + |
+ |||||
| + start + | +
+
+ integer
+
+ + Starting index of the orders to be fetched. + |
+ |||||
| + end + | +
+
+ integer
+
+ + Last index of the orders to be fetched. Note that end - start must be <= 1,000. + |
+ |||||
projectId
@@ -78673,6 +80472,9 @@ Request
{
+ "algorithmId": "L-6e9d8a78f5af89d401f630585be90e43",
+ "start": 0,
+ "end": 100,
"projectId": 23456789
}
Responses
The
+ Orders of the live algorithm within range.
+ |
+ | |||||
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
- LivePortfolioResponse
+ string
- Model - Contains holdings and cash of the live algorithm in the request criteria.
+ + Header + |
+
+ The following example demonstates creating, reading, updating, and listing live algorithms of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Create Live Algorithm
+# Define placeholder IDs for compilation and node (replace with actual values)
+project_id = 12345678
+compile_id = "compile_id..."
+node_id = "node_id..."
+# Prepare the data payload for creating a live algorithm with necessary details
+payload = {
+ "versionId": "-1", # Use the latest version of the algorithm
+ "projectId": project_id, # ID of the project to deploy as a live algorithm
+ "compileId": compile_id, # Compilation ID for the algorithm code
+ "nodeId": node_id, # Node ID where the algorithm will run
+ "brokerage": { # Brokerage configuration for live trading
+ "id": "QuantConnectBrokerage", # Brokerage identifier
+ "user": "", # Brokerage username (replace with actual value)
+ "password": "", # Brokerage password (replace with actual value)
+ "environment": "live-paper", # Trading environment (live or paper)
+ "account": "" # Brokerage account ID (replace with actual value)
+ },
+ "dataProviders": { # Data provider configuration
+ "QuantConnectBrokerage": {
+ "id": "QuantConnectBrokerage" # Data provider identifier
+ }
+ },
+ "parameters": {}, # Optional algorithm parameters (empty in this example)
+ "notification": {} # Optional notification settings (empty in this example)
+}
+# Send a POST request to the /live/create endpoint to deploy the algorithm
+response = post(f'{BASE_URL}/live/create', headers=get_headers(), json=data)
+# Parse the JSON response into python managable dict from the API
+result = response.json()
+# Extract the deploy ID from the response for future operations
+deploy_id = result['deployId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Created Successfully:")
+ print(result)
+
+### Read Live Algorithm Statistics
+# Prepare data payload with project and deploy IDs to fetch statistics
+payload = {
+ "projectId": project_id, # ID of the project
+ "deployId": deploy_id # ID of the deployed live algorithm
+}
+# Send a POST request to the /live/read endpoint to get algorithm statistics
+response = post(f'{BASE_URL}/live/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the statistics
+if result['success']:
+ print("Live Algorithm Statistics:")
+ print(result)
+
+### Liquidate Live Algorithm
+# Prepare data payload with project ID to liquidate the algorithm
+payload = {
+ "projectId": project_id # ID of the project to liquidate
+}
+# Send a POST request to the /live/update/liquidate endpoint to liquidate
+response = post(f'{BASE_URL}/live/update/liquidate', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Liquidated Successfully:")
+ print(result)
+
+### Stop Live Algorithm
+# Prepare data payload with project ID to stop the algorithm
+payload = {
+ "projectId": project_id # ID of the project to stop
+}
+# Send a POST request to the /live/update/stop endpoint to stop the algorithm
+response = post(f'{BASE_URL}/live/update/stop', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Stopped Successfully:")
+ print(result)
+
+### List Live Algorithms
+# Prepare data payload with filters for listing live algorithms
+payload = {
+ "status": "Running", # Filter to show only running algorithms
+ "start": 1717801200, # Start time (Unix timestamp) for the list range
+ "end": 1743462000 # End time (Unix timestamp) for the list range
+}
+# Send a POST request to the /live/list endpoint to list algorithms
+response = post(f'{BASE_URL}/live/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Live Algorithms:")
+ print(result)
+ + +
+ Read out the insights of a live algorithm. The snapshot updates about every 10 minutes. +
+ + + +
+ Fetch the insights of a live algorithm for the project Id and steps provided. The
+
+ /live/insights/read
+
+ API accepts requests in the following format:
+
+
+ ReadLiveInsightsRequest
+
+ Model - Request to read insights from a live algorithm.
|
|
|---|---|
| - portfolio + algorithmId |
- Portfolio object
+ string
+
- Portfolio object with the holdings and cash information. + Deploy Id (Algorithm Id) of the live running algorithm. |
| - success + start |
- boolean
+ integer
+
- Indicate if the API request was successful. + Starting index of the insights to be fetched. Required if end > 100. |
| - errors + end |
- string Array
+ integer
+
- List of errors with the API call. + Last index of the insights to be fetched. Note that end - start must be less than 100. + |
+
| + projectId + | +
+
+ integer
+
+ + Id of the project from which to read the live algorithm. |
+ The
+
+ /live/insights/read
+
+ API provides a response in the following format:
+
- Portfolio
+ LiveInsightsResponse
- Model - Portfolio object with the holdings and cash information.
+ Model - Contains insights and the number of insights of the live algorithm in the request criteria.
|
|||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - holdings + insights |
- Holding object
+ Insight Array
- Dictionary of algorithm holdings information, where the key is the Symbol Id. + Collection of insights. |
||||||||||||||||||||||
| - cash + length |
- Cash object
+ integer
- Dictionary of algorithm cash currencies information, where the key is the currency ticker. + Total number of returned insights. + |
+ ||||||||||||||||||||||
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. |
||||||||||||||||||||||
- Holding
+ Insight
- Model - Summary of asset holding.
+ Model - Insight struct for emitting new prediction.
|
|||||||||||||||||||||||
| - a + id |
- number
+ string
+
- Average purchase price of the holding in the currency it trades in. + Id of the insight. |
||||||||||||||||||||||
| - q + groupId |
- number
+ string
- Quantity of the asset. + Id of the group of insights. |
||||||||||||||||||||||
| - p + sourceModel |
- number
+ string
+
- Current market price of the asset in the currency it trades in. + An identifier for the source model that generated this insight. |
||||||||||||||||||||||
| - v + generatedTime |
- number
+ integer
+
- Current market value of the holding. + Gets the Unix time this insight was generated. |
||||||||||||||||||||||
| - u + closeTime + | +
+
+ integer
+
+ + Gets the Unix time this insight was closed. + |
+ ||||||||||||||||||||||
| + symbol + | +
+
+ string
+
+ + Gets the symbol Id this insight is for. + |
+ ||||||||||||||||||||||
| + ticker + | +
+
+ string
+
+ + Gets the symbol ticker this insight is for. + |
+ ||||||||||||||||||||||
| + type + | +
+
+ string Enum
+
+ + Gets the type of insight. Options : ['price', 'volatility'] + |
+ ||||||||||||||||||||||
| + reference |
number
+
- Unrealized profit/loss of the position. + Gets the initial reference value this insight is predicting against. That is, the price of the asset when the insight was created. |
||||||||||||||||||||||
| - up + referenceFinal |
number
- Unrealized profit/loss percentage of the position. + Gets the final reference value, used for scoring, this insight is predicting against. |
||||||||||||||||||||||
| - Example + direction |
-
-
+
-{
- "a": 0,
- "q": 0,
- "p": 0,
- "v": 0,
- "u": 0,
- "up": 0
-}
-
+ string Enum
+
+ + Gets the predicted direction. Options : ['down', 'flat', 'up'] |
||||||||||||||||||||||
-
- Cash
-
- Model - Represents a holding of a currency in cash.
- |
- |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - securitySymbols + period |
- object Array
+ integer
- /. + Gets the period, in seconds, over which this insight is expected to come to fruition. |
||||||||||||||||||
| - symbol + magnitude |
- string
+ number
- Gets the symbol used to represent this cash. + Gets the predicted percent change in the insight type (price/volatility). This value can be null. |
||||||||||||||||||
| - amount + confidence |
number
- Gets or sets the amount of cash held. + Gets the confidence in this insight. This value can be null. |
||||||||||||||||||
| - conversionRate + weight |
number
- The currency conversion rate to the account base currency. + Gets the portfolio weight of this insight. This value can be null. |
||||||||||||||||||
| - currencySymbol + scoreFinal |
- string
-
- The symbol of the currency. + Gets whether or not this is the insight's final score. |
||||||||||||||||||
| - valueInAccountCurrency + scoreDirection |
number
- The value of the currency cash in the account base currency. + Gets the direction score. + |
+ ||||||||||||||||||
| + scoreMagnitude + | +
+
+ number
+
+ + Gets the magnitude score. + |
+ ||||||||||||||||||
| + estimatedValue + | +
+
+ number
+
+ + Gets the estimated value of this insight in the account currency. + |
+ ||||||||||||||||||
| + tag + | +
+
+ string
+
+ + The insight's tag containing additional information. |
||||||||||||||||||
- ReadLiveOrdersRequest
+ ReadLiveLogsRequest
- Model - Request to read orders from a live algorithm.
+ Model - Request to read the logs of a specific algorithm.
|
|||||||||||||||||||
| - algorithmId + format |
- string
+ object
- Deploy Id (Algorithm Id) of the live running algorithm. + Format of the log results. |
||||||||||||||||||
| - start + projectId |
@@ -79304,21 +81495,21 @@
- Starting index of the orders to be fetched. + Id of the project that contains the live running algorithm. |
||||||||||||||||||
| - end + algorithmId |
- integer
+ string
- Last index of the orders to be fetched. Note that end - start must be <= 1,000. + Deploy Id (Algorithm Id) of the live running algorithm. |
||||||||||||||||||
| - projectId + startLine |
@@ -79349,15 +81540,39 @@
+ + Start line (inclusive) of logs to read. The lines numbers start at 0. + |
+ ||||||||||||||||||
| + endLine + | +
+
+ integer
- Id of the project from which to read the live algorithm. + End line (exclusive) of logs to read, where endLine - startLine <= 250. + |
+ ||||||||||||||||||
| + deploymentLogs + | +
+
+ boolean
+
+ + Indicates if only the given deployment logs should be included in the response. |
||||||||||||||||||
- Orders of the live algorithm within range.
+
+ ReadLiveLogsResponse
+
+ Model - Logs from a live algorithm.
|
|||||||||||||||||||
-
- UnauthorizedError
-
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
- |
- |
|---|---|
| + logs + | +
+
+ string Array
+
+ + List of logs from the live algorithm. + |
+
| + length + | +
+
+ integer
+
+ + Total amount of rows in the logs across all live deployments for this project. + |
+
| + deploymentOffset + | +
+
+ integer
+
+ + Number of log rows before the given deployment (the `algorithmId` in the request). + |
+
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "logs": [
+ "string"
+ ],
+ "length": 0,
+ "deploymentOffset": 0,
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
| - www_authenticate - | -+ |
- string
+ UnauthorizedError
- - Header - - | |
|---|---|---|---|
+ string
+
+ - +
+ The QuantConnect REST API lets you update your live algorithms on our cloud servers through URL endpoints. +
++ +
- Read out the insights of a live algorithm. The snapshot updates about every 10 minutes. + Liquidate a live algorithm from the specified project Id.
@@ -79598,9 +81943,9 @@
- Fetch the insights of a live algorithm for the project Id and steps provided. The
+ Information about the live algorithm to liquidate. The
- /live/insights/read
+ /live/update/liquidate
API accepts requests in the following format:
- ReadLiveInsightsRequest
+ LiquidateLiveAlgorithmRequest
- Model - Request to read insights from a live algorithm.
+ Model - Request to liquidate a live algorithm.
- string
-
-
-
- example: L-6e9d8a78f5af89d401f630585be90e43
-
-
-
-
- integer
-
-
-
- example: 0
-
-
-
-
- integer
-
-
-
- required
-
-
-
-
-
- example: 100
-
-
-
-
{
- "algorithmId": "L-6e9d8a78f5af89d401f630585be90e43",
- "start": 0,
- "end": 100,
"projectId": 23456789
}
The
- /live/insights/read
+ /live/update/liquidate
API provides a response in the following format:
- LiveInsightsResponse
+ RestResponse
- Model - Contains insights and the number of insights of the live algorithm in the request criteria.
+ Model - Base API response class for the QuantConnect API.
- Insight Array
-
-
- integer
+ boolean
- boolean
+ string Array
{
- "insights": [
- {
- "id": "81ff7c1daf404ee39d612df321df5931",
- "groupId": "string",
- "sourceModel": "952d6ff7-e513-4971-aa50-cbe13bf56898",
- "generatedTime": 1753714506,
- "closeTime": 1753800906,
- "symbol": "BTCUSD 2XR",
- "ticker": "BTCUSD",
- "type": "price",
- "reference": 118159.19,
- "referenceFinal": 0,
- "direction": "down",
- "period": 0,
- "magnitude": 0,
- "confidence": 0,
- "weight": 0,
- "scoreFinal": true,
- "scoreDirection": 0,
- "scoreMagnitude": 0,
- "estimatedValue": 0,
- "tag": "string"
- }
- ],
- "length": 0,
- "success": true
+ "success": true,
+ "errors": [
+ "string"
+ ]
}
- Insight
+ UnauthorizedError
- Model - Insight struct for emitting new prediction.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - id - | -
-
- string
-
- - Id of the insight. - |
-
| - groupId + www_authenticate |
string
- Id of the group of insights. + Header |
+ The following example demonstates creating, reading, updating, and listing live algorithms of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Create Live Algorithm
+# Define placeholder IDs for compilation and node (replace with actual values)
+project_id = 12345678
+compile_id = "compile_id..."
+node_id = "node_id..."
+# Prepare the data payload for creating a live algorithm with necessary details
+payload = {
+ "versionId": "-1", # Use the latest version of the algorithm
+ "projectId": project_id, # ID of the project to deploy as a live algorithm
+ "compileId": compile_id, # Compilation ID for the algorithm code
+ "nodeId": node_id, # Node ID where the algorithm will run
+ "brokerage": { # Brokerage configuration for live trading
+ "id": "QuantConnectBrokerage", # Brokerage identifier
+ "user": "", # Brokerage username (replace with actual value)
+ "password": "", # Brokerage password (replace with actual value)
+ "environment": "live-paper", # Trading environment (live or paper)
+ "account": "" # Brokerage account ID (replace with actual value)
+ },
+ "dataProviders": { # Data provider configuration
+ "QuantConnectBrokerage": {
+ "id": "QuantConnectBrokerage" # Data provider identifier
+ }
+ },
+ "parameters": {}, # Optional algorithm parameters (empty in this example)
+ "notification": {} # Optional notification settings (empty in this example)
+}
+# Send a POST request to the /live/create endpoint to deploy the algorithm
+response = post(f'{BASE_URL}/live/create', headers=get_headers(), json=data)
+# Parse the JSON response into python managable dict from the API
+result = response.json()
+# Extract the deploy ID from the response for future operations
+deploy_id = result['deployId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Created Successfully:")
+ print(result)
+
+### Read Live Algorithm Statistics
+# Prepare data payload with project and deploy IDs to fetch statistics
+payload = {
+ "projectId": project_id, # ID of the project
+ "deployId": deploy_id # ID of the deployed live algorithm
+}
+# Send a POST request to the /live/read endpoint to get algorithm statistics
+response = post(f'{BASE_URL}/live/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the statistics
+if result['success']:
+ print("Live Algorithm Statistics:")
+ print(result)
+
+### Liquidate Live Algorithm
+# Prepare data payload with project ID to liquidate the algorithm
+payload = {
+ "projectId": project_id # ID of the project to liquidate
+}
+# Send a POST request to the /live/update/liquidate endpoint to liquidate
+response = post(f'{BASE_URL}/live/update/liquidate', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Liquidated Successfully:")
+ print(result)
+
+### Stop Live Algorithm
+# Prepare data payload with project ID to stop the algorithm
+payload = {
+ "projectId": project_id # ID of the project to stop
+}
+# Send a POST request to the /live/update/stop endpoint to stop the algorithm
+response = post(f'{BASE_URL}/live/update/stop', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Live Algorithm Stopped Successfully:")
+ print(result)
+
+### List Live Algorithms
+# Prepare data payload with filters for listing live algorithms
+payload = {
+ "status": "Running", # Filter to show only running algorithms
+ "start": 1717801200, # Start time (Unix timestamp) for the list range
+ "end": 1743462000 # End time (Unix timestamp) for the list range
+}
+# Send a POST request to the /live/list endpoint to list algorithms
+response = post(f'{BASE_URL}/live/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Live Algorithms:")
+ print(result)
+ + +
+ Stop a live algorithm from the specified project Id. +
+ + + +
+ Information about the project to delete. The
+
+ /live/update/stop
+
+ API accepts requests in the following format:
+
+
+ StopLiveAlgorithmRequest
+
+ Model - Request to stop a live algorithm.
+ |
+ |
|---|---|
| - sourceModel + projectId |
- string
+ integer
- - An identifier for the source model that generated this insight. - |
-
| - generatedTime - | -
-
- integer
- Gets the Unix time this insight was generated. + Id of the project to stop trading live. |
| - closeTime + Example |
-
- integer
-
- - Gets the Unix time this insight was closed. +
+
+{
+ "projectId": 23456789
+}
+ |
+ The
+
+ /live/update/stop
+
+ API provides a response in the following format:
+
+
+ RestResponse
+
+ Model - Base API response class for the QuantConnect API.
+ |
+ |
|---|---|
| - symbol + success |
- string
-
- Gets the symbol Id this insight is for. + Indicate if the API request was successful. |
| - ticker + errors |
- string
-
- Gets the symbol ticker this insight is for. + List of errors with the API call. |
| - type - | -
-
- string Enum
-
- - Gets the type of insight. Options : ['price', 'volatility'] - |
-
| - reference - | -
-
- number
-
- - Gets the initial reference value this insight is predicting against. That is, the price of the asset when the insight was created. - |
-
| - referenceFinal - | -
-
- number
-
- - Gets the final reference value, used for scoring, this insight is predicting against. - |
-
| - direction - | -
-
- string Enum
-
- - Gets the predicted direction. Options : ['down', 'flat', 'up'] - |
-
| - period - | -
-
- integer
-
- - Gets the period, in seconds, over which this insight is expected to come to fruition. - |
-
| - magnitude - | -
-
- number
-
- - Gets the predicted percent change in the insight type (price/volatility). This value can be null. - |
-
| - confidence - | -
-
- number
-
- - Gets the confidence in this insight. This value can be null. - |
-
| - weight - | -
-
- number
-
- - Gets the portfolio weight of this insight. This value can be null. - |
-
| - scoreFinal - | -
-
- boolean
-
- - Gets whether or not this is the insight's final score. - |
-
| - scoreDirection - | -
-
- number
-
- - Gets the direction score. - |
-
| - scoreMagnitude - | -
-
- number
-
- - Gets the magnitude score. - |
-
| - estimatedValue - | -
-
- number
-
- - Gets the estimated value of this insight in the account currency. - |
-
| - tag - | -
-
- string
-
- - The insight's tag containing additional information. - |
-
| - Example + Example |
{
- "id": "81ff7c1daf404ee39d612df321df5931",
- "groupId": "string",
- "sourceModel": "952d6ff7-e513-4971-aa50-cbe13bf56898",
- "generatedTime": 1753714506,
- "closeTime": 1753800906,
- "symbol": "BTCUSD 2XR",
- "ticker": "BTCUSD",
- "type": "price",
- "reference": 118159.19,
- "referenceFinal": 0,
- "direction": "down",
- "period": 0,
- "magnitude": 0,
- "confidence": 0,
- "weight": 0,
- "scoreFinal": true,
- "scoreDirection": 0,
- "scoreMagnitude": 0,
- "estimatedValue": 0,
- "tag": "string"
+ "success": true,
+ "errors": [
+ "string"
+ ]
}
|
@@ -80318,11 +82559,11 @@
- ReadLiveLogsRequest
+ ListLiveAlgorithmsRequest
- Model - Request to read the logs of a specific algorithm.
+ Model - Request for a list of past and present live deployments.
|
|
| - format + projectId |
- object
+ integer
- Format of the log results. + Id of the project to include in response. If you omit this property, the response includes all your projects. |
| - projectId + status |
- integer
-
- Id of the project that contains the live running algorithm. + Status of the live deployments to include in the response. If you omit this property, the response includes deployments with any status. Options : ['Running', 'Stopped', 'RuntimeError', 'Liquidated'] |
| - algorithmId + Example |
-
- string
-
- - Deploy Id (Algorithm Id) of the live running algorithm. +
+
+{
+ "projectId": 23456789,
+ "status": "Running"
+}
+ |
+ The
+
+ /live/list
+
+ API provides a response in the following format:
+
+
+ LiveAlgorithmListResponse
+
+ Model - List of the live algorithms running which match the requested status.
+ |
+ |
|---|---|
| - startLine + live |
- integer
-
- Start line (inclusive) of logs to read. The lines numbers start at 0. + Live algorithms that pass the filters in the request. |
| - endLine + success |
- integer
-
- End line (exclusive) of logs to read, where endLine - startLine <= 250. + Indicate if the API request was successful. |
| - deploymentLogs + errors |
- boolean
+ string Array
- Indicates if only the given deployment logs should be included in the response. + List of errors with the API call. |
- The
-
- /live/logs/read
-
- API provides a response in the following format:
-
- ReadLiveLogsResponse
+ LiveAlgorithmSummary
- Model - Logs from a live algorithm.
+ Model - Summary of the live algorithm.
|
|
|---|---|
| - logs + projectId |
- string Array
+ integer
- List of logs from the live algorithm. + Id of the project. |
| - length + deployId |
- integer
+ string
- Total amount of rows in the logs across all live deployments for this project. + Id of the live deployment. |
| - deploymentOffset + status |
- integer
+ string
- Number of log rows before the given deployment (the `algorithmId` in the request). + The current status of the deployment. |
| - success + launched |
- boolean
+ string($date-time)
- Indicate if the API request was successful. + The date and time when the deployment was launched. |
| - errors + stopped + | +
+
+ string($date-time)
+
+ + The date and time when the deployment was stopped. + |
+
| + brokerage + | +
+
+ string
+
+ + The brokerage used for the deployment. + |
+
| + subscription + | +
+
+ string
+
+ + The chart to which you're subscribed. + |
+
| + equity + | +
+
+ number
+
+ + The equity value associated with the deployment. + |
+
| + environment + | +
+
+ string
+
+ + The environment in which the deployment is running. + |
+
| + description + | +
+
+ string
+
+ + The project description. + |
+
| + error + | +
+
+ string
+
+ + The error message if there was a runtime error. + |
+
| + leagues |
string Array
- List of errors with the API call. + Quant Leagues the algorithm is enrolled in. |
| + command + | +
+
+ object
+
+ + The command to run. |
- StopLiveAlgorithmRequest
+ BroadcastLiveCommandRequest
- Model - Request to stop a live algorithm.
+ Model - Request to create a live command.
|
|
| - projectId + organizationId |
- integer
+ string
+ + Organization Id of the projects we would like to broadcast the command to. + |
+
| + excludeProjectId + | +
+
+ integer
+
- Id of the project to stop trading live. + Project for the live instance we want to exclude from the broadcast list. If null, all projects will be included. + |
+
| + command + | +
+
+ object
+
+ + The command to run. |
- ListLiveAlgorithmsRequest
+ CreateOptimizationRequest
- Model - Request for a list of past and present live deployments.
+ Model - Request to create an optimization job.
|
|
| - status + name |
- string Enum
+ string
+
- Status of the live deployments to include in the response. If you omit this property, the response includes deployments with any status. Options : ['Running', 'Stopped', 'RuntimeError', 'Liquidated'] - |
-
| - Example - | -
-
-
+ Name of the optimization.
-{
- "projectId": 23456789,
- "status": "Running"
-}
- |
- The
-
- /live/list
-
- API provides a response in the following format:
-
-
- LiveAlgorithmListResponse
-
- Model - List of the live algorithms running which match the requested status.
- |
- |
|---|---|
| - live + target |
- LiveAlgorithmSummary Array
+ string Enum
- Live algorithms that pass the filters in the request. + Target statistic of the optimization to minimize or maximize. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] |
| - success + targetTo |
- boolean
+ string Enum
- Indicate if the API request was successful. + Target extremum of the optimization. Options : ['min', 'max'] |
| - errors + targetValue |
- string Array
+ number
+
- List of errors with the API call. + Desired value for the optimization target statistic. |
| - Example + strategy |
-
-
+
-{
- "live": [
- {
- "projectId": 0,
- "deployId": "string",
- "status": "string",
- "launched": "2021-11-26T15:18:27.693Z",
- "stopped": "2021-11-26T15:18:27.693Z",
- "brokerage": "string",
- "subscription": "string",
- "equity": 0,
- "environment": "string",
- "description": "string",
- "error": "string",
- "leagues": [
- "string"
- ]
- }
- ],
- "success": true,
- "errors": [
- "string"
- ]
-}
-
+ string Enum
+
+ + Optimization strategy. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] |
-
- LiveAlgorithmSummary
-
- Model - Summary of the live algorithm.
- |
- |
|---|---|
| - projectId + compileId |
- integer
+ string
+
- Id of the project. + Optimization compile Id. |
| - deployId + parameters |
- string
+ OptimizationParameter Array
+
- Id of the live deployment. + Optimization parameters. |
| - status + constraints |
- string
+ OptimizationConstraint Array
- The current status of the deployment. + Optimization constraints. |
| - launched + estimatedCost |
- string($date-time)
+ number
+
- The date and time when the deployment was launched. + Estimated cost for optimization. |
| - stopped + nodeType |
- string($date-time)
+ string Enum
- The date and time when the deployment was stopped. + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] |
| - brokerage + parallelNodes |
- string
+ integer
+
- The brokerage used for the deployment. + Number of parallel nodes for optimization. |
| - subscription + Example |
-
- string
-
- - The chart to which you're subscribed. +
+
+{
+ "projectId": 23456789,
+ "name": "Mia First Optimization Job",
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "targetTo": "min",
+ "targetValue": 1,
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
+ "compileId": "5d1f2cba3a0ec7407c566614300502b5-173e0419674daf4144ce7c9931155ca8",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ],
+ "constraints": [
+ {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+ }
+ ],
+ "estimatedCost": 10,
+ "nodeType": "O2-8",
+ "parallelNodes": 4
+}
+ |
+
+ OptimizationTargetStatistic
+
+ Model
+ |
+ |
|---|---|
| - equity + OptimizationNodeType |
- number
+ string Enum
- The equity value associated with the deployment. + /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] |
| - environment + Example |
-
- string
-
- - The environment in which the deployment is running. +
+
+{
+ "OptimizationNodeType": "TotalPerformance.PortfolioStatistics.SharpeRatio"
+}
+ |
+
+ OptimizationTargetTo
+
+ Model
+ |
+ |
|---|---|
| - description + OptimizationNodeType |
- string
+ string Enum
- The project description. + /. Options : ['min', 'max'] |
| - error + Example |
-
- string
-
- - The error message if there was a runtime error. +
+
+{
+ "OptimizationNodeType": "min"
+}
+ |
+
+ OptimizationStrategy
+
+ Model
+ |
+ |
|---|---|
| - leagues + OptimizationNodeType |
- string Array
+ string Enum
- Quant Leagues the algorithm is enrolled in. + /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] |
- UnauthorizedError
+ OptimizationParameter
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ Model
|
|
|---|---|
| - www_authenticate + name |
string
-
- - Header - |
+
| + min + | +
+
+ number
+
+ + Minimum value of optimization parameter, applicable for boundary conditions. + |
+
| + max + | +
+
+ number
+
+ + Maximum value of optimization parameter, applicable for boundary conditions. + |
+
| + step + | +
+
+ number
+
+ + Movement, should be positive. + |
+
| + minStep + | +
+
+ number
+
+ + Minimal possible movement for current parameter, should be positive. Used by +
+ Strategies.EulerSearchOptimizationStrategy
+
+ to determine when this parameter can no longer be optimized.
+ |
+
| + Example + | +
+
+
+
+{
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+}
+ |
+
+
+ OptimizationConstraint
+
+ Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ |
+ |
|---|---|
| + target + | +
+
+ string Enum
+
+ + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + operator + | +
+
+ string Enum
+
+ + The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] + |
+
| + targetValue + | +
+
+ number
+
+ + The threshold value for the target constraint. + |
+
| + Example + | +
+
+
+
+{
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+}
+ |
+
+
+ OptimizationNodeType
+
+ Model - Optimization node types available in QuantConnect Cloud.
+ |
+ |
|---|---|
| + OptimizationNodeType + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationNodeType": "O2-8"
+}
+ |
+
+ The
+
+ /optimizations/create
+
+ API provides a response in the following format:
+
+
+ ListOptimizationResponse
+
+ Model - Response received when creating an optimization or listing optimizations of a project.
+ |
+ |
|---|---|
| + optimizations + | +
+
+ CreateOptimizationResponse Array
+
+ + Collection of summarized optimization objects. + |
+
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "optimizations": [
+ {
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "projectId": 23456789,
+ "name": "string",
+ "status": ,
+ "nodeType": "O2-8",
+ "extremum": "min",
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0,
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ]
+ }
+ ],
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ CreateOptimizationResponse
+
+ Model - Response received when launching an optimization job or listing all the optimization jobs of a project.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization job. + |
+
| + projectId + | +
+
+ integer
+
+ + Id of the project the optimization belongs to. + |
+
| + name + | +
+
+ string
+
+ + Name of the optimization. + |
+
| + status + | +
+
+ OptimizationStatus object
+
+ + Status of the optimization. + |
+
| + nodeType + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + extremum + | +
+
+ string Enum
+
+ + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + criterion + | +
+
+ OptimizationTarget object
+
+ + Optimization statistical target. + |
+
| + created + | +
+
+ string($date-time)
+
+ + Date and time of when this optimization was created. + |
+
| + psr + | +
+
+ number
+
+ + Probabilistic Sharpe ratio statistic. + |
+
| + sharpeRatio + | +
+
+ number
+
+ + Sharpe ratio statistic. + |
+
| + trades + | +
+
+ integer
+
+ + Number of trades in the best backtest (based on the criterion) of the optimziation. + |
+
| + cloneId + | +
+
+ integer
+
+ + Id of project where this current project was originally cloned. + |
+
| + outOfSampleDays + | +
+
+ integer
+
+ + Number out-of-sample days. + |
+
| + outOfSampleMaxEndDate + | +
+
+ string($date-time)
+
+ + End date of out-of-sample data. + |
+
| + parameters + | +
+
+ OptimizationParameter Array
+
+ + Parameters used in this optimization. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "projectId": 23456789,
+ "name": "string",
+ "status": ,
+ "nodeType": "O2-8",
+ "extremum": "min",
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0,
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ]
+}
+ |
+
+
+ OptimizationNodeType
+
+ Model - Optimization node types available in QuantConnect Cloud.
+ |
+ |
|---|---|
| + OptimizationParameter + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationParameter": "O2-8"
+}
+ |
+
+
+ OptimizationTargetTo
+
+ Model
+ |
+ |
|---|---|
| + OptimizationParameter + | +
+
+ string Enum
+
+ + /. Options : ['min', 'max'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationParameter": "min"
+}
+ |
+
+
+ OptimizationTarget
+
+ Model
+ |
+ |
|---|---|
| + target + | +
+
+ string Enum
+
+ + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + extremum + | +
+
+ string Enum
+
+ + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + targetValue + | +
+
+ number
+
+ + Desired value for the optimization target statistic. + |
+
| + Example + | +
+
+
+
+{
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+}
+ |
+
+
+ OptimizationTargetStatistic
+
+ Model
+ |
+ |
|---|---|
| + OptimizationParameter + | +
+
+ string Enum
+
+ + /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationParameter": "TotalPerformance.PortfolioStatistics.SharpeRatio"
+}
+ |
+
+
+ OptimizationParameter
+
+ Model
+ |
+ |
|---|---|
| + name + | +
+
+ string
+
+ + Name of optimization parameter. + |
+
| + min + | +
+
+ number
+
+ + Minimum value of optimization parameter, applicable for boundary conditions. + |
+
| + max + | +
+
+ number
+
+ + Maximum value of optimization parameter, applicable for boundary conditions. + |
+
| + step + | +
+
+ number
+
+ + Movement, should be positive. + |
+
| + minStep + | +
+
+ number
+
+ + Minimal possible movement for current parameter, should be positive. Used by +
+ Strategies.EulerSearchOptimizationStrategy
+
+ to determine when this parameter can no longer be optimized.
+ |
+
| + Example + | +
+
+
+
+{
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The project ID of the project to manage an optimization job
+project_id = 12345678
+
+### Estimate Optimization Cost
+# Send a POST request to the /optimizations/estimate endpoint to estimate cost
+response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
+ "targetTo": "max", # Direction to optimize (maximize)
+ "targetValue": None, # Specific target value (None for max/min)
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
+ "compileId": compile_id, # Compilation ID for the optimization
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value for first parameter
+ "parameters[0][max]": 200, # Maximum value for first parameter
+ "parameters[0][step]": 50, # Step size for first parameter
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value for second parameter
+ "parameters[1][max]": 300, # Maximum value for second parameter
+ "parameters[1][step]": 50, # Step size for second parameter
+ "constraints": [{ # Constraints for the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the estimated cost
+if result['success']:
+ print("Optimization Cost Estimated Successfully:")
+ print(result)
+
+### Create Optimization
+# Send a POST request to the /optimizations/create endpoint to create an optimization
+response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
+ "targetTo": "max", # Direction to optimize
+ "targetValue": None, # Specific target value
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
+ "compileId": compile_id, # Compilation ID
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value
+ "parameters[0][max]": 200, # Maximum value
+ "parameters[0][step]": 50, # Step size
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value
+ "parameters[1][max]": 300, # Maximum value
+ "parameters[1][step]": 50, # Step size
+ "constraints": [{ # Constraints
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }],
+ "estimatedCost": 10, # Estimated cost of optimization
+ "nodeType": "O2-8", # Node type for optimization
+ "parallelNodes": 4 # Number of parallel nodes
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the optimization ID from the response
+optimization_id = result['optimizations'][0]['optimizationId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Created Successfully:")
+ print(result)
+
+### Update Optimization
+# Send a POST request to the /optimizations/update endpoint to update the optimization
+response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
+ "optimizationId": optimization_id, # ID of the optimization to update
+ "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Updated Successfully:")
+ print(result)
+
+### Read Optimization
+# Prepare data payload to read optimization details
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to read
+}
+# Send a POST request to the /optimizations/read endpoint to get details
+response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the details
+if result['success']:
+ print("Optimization Details:")
+ print(result)
+
+### Abort Optimization
+# Prepare data payload to abort the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to abort
+}
+# Send a POST request to the /optimizations/abort endpoint to abort
+response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Aborted Successfully:")
+ print(result)
+
+### Delete Optimization
+# Prepare data payload to delete the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to delete
+}
+# Send a POST request to the /optimizations/delete endpoint to delete
+response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Deleted Successfully:")
+ print(result)
+
+### List Optimizations
+# Prepare data payload to list optimizations
+payload = {
+ "projectId": project_id # ID of the project
+}
+# Send a POST request to the /optimizations/list endpoint to list optimizations
+response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Optimizations:")
+ print(result)
+ + +
+ Read an optimization. +
+ + + +
+ Id of the optimization to read. The
+
+ /optimizations/read
+
+ API accepts requests in the following format:
+
+
+ ReadOptimizationRequest
+
+ Model - Request to read an optimization from a project.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization to read. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd"
+}
+ |
+
+ The
+
+ /optimizations/read
+
+ API provides a response in the following format:
+
+
+ ReadOptimizationResponse
+
+ Model - Response received when reading an optimization.
+ |
+ |
|---|---|
| + optimization + | +
+
+ Optimization object
+
+ + Response received when reading an optimization job. + |
+
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "optimization": {
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "snapshotId": 24013333,
+ "projectId": 23456789,
+ "name": "string",
+ "extremum": "min",
+ "status": ,
+ "nodeType": "O2-8",
+ "parallelNodes": 4,
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "runtimeStatistics": {
+ "Completed": "string",
+ "Failed": "string",
+ "Running": "string",
+ "In Queue": "string",
+ "Average Length": "2021-11-26T15:18:27.693Z",
+ "Total Runtime": "2021-11-26T15:18:27.693Z",
+ "Total": "string",
+ "Consumed": "string"
+ },
+ "constraints": [
+ {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+ }
+ ],
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ],
+ "backtests": {
+ "name": "string",
+ "id": "string",
+ "progress": 0,
+ "exitCode": 0,
+ "statistics": [
+ "number"
+ ],
+ "parameterSet": ,
+ "equity": [
+ "array"
+ ],
+ "startDate": "2021-11-26T15:18:27.693Z",
+ "endDate": "2021-11-26T15:18:27.693Z",
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z"
+ },
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
+ "requested": "2021-11-26T15:18:27.693Z",
+ "optimizationTarget": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "targetValue": 1,
+ "gridLayout": [
+ {
+ "chartName": "string",
+ "width": 0,
+ "height": 0,
+ "row": 0,
+ "column": 0,
+ "sort": 0,
+ "definition": [
+ "string"
+ ]
+ }
+ ],
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "outOfSampleDays": 0,
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0
+ },
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ Optimization
+
+ Model - Response received when reading an optimization job.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization. + |
+
| + snapshotId + | +
+
+ integer
+
+ + Snapshot Id of this optimization. + |
+
| + projectId + | +
+
+ integer
+
+ + Id of the project the optimization belongs to. + |
+
| + name + | +
+
+ string
+
+ + Name of the optimization. + |
+
| + extremum + | +
+
+ string Enum
+
+ + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + status + | +
+
+ OptimizationStatus object
+
+ + Status of the optimization. + |
+
| + nodeType + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + parallelNodes + | +
+
+ integer
+
+ + Number of parallel nodes for the optimization. + |
+
| + criterion + | +
+
+ OptimizationTarget object
+
+ + Optimization statistical target. + |
+
| + runtimeStatistics + | +
+
+ OptimizationRuntimeStatistics object
+
+ + Dictionary representing a runtime banner/updating statistics for the optimization. + |
+
| + constraints + | +
+
+ OptimizationConstraint Array
+
+ + Optimization constraints. + |
+
| + parameters + | +
+
+ OptimizationParameter Array
+
+ + Optimization parameters. + |
+
| + backtests + | +
+
+ OptimizationBacktest object
+
+ + Dictionary of optimization backtests. + |
+
| + strategy + | +
+
+ string Enum
+
+ + Optimization strategy. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + |
+
| + requested + | +
+
+ string($date-time)
+
+ + Optimization requested date and time. + |
+
| + optimizationTarget + | +
+
+ string Enum
+
+ + Statistic to be optimized. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + targetValue + | +
+
+ number
+
+ + Desired value for the optimization target statistic. + |
+
| + gridLayout + | +
+
+ GridChart Array
+
+ + List with grid charts representing the grid layout. + |
+
| + outOfSampleMaxEndDate + | +
+
+ string($date-time)
+
+ + End date of out of sample data. + |
+
| + outOfSampleDays + | +
+
+ integer
+
+ + Number of days of out of sample days. + |
+
| + created + | +
+
+ string($date-time)
+
+ + Date and time of when this optimization was created. + |
+
| + psr + | +
+
+ number
+
+ + Probabilistic Sharpe ratio statistic. + |
+
| + sharpeRatio + | +
+
+ number
+
+ + Sharpe ratio statistic. + |
+
| + trades + | +
+
+ integer
+
+ + Number of trades in the best backtest (based on the criterion) of the optimziation. + |
+
| + cloneId + | +
+
+ integer
+
+ + Id of project where this current project was originally cloned. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "snapshotId": 24013333,
+ "projectId": 23456789,
+ "name": "string",
+ "extremum": "min",
+ "status": ,
+ "nodeType": "O2-8",
+ "parallelNodes": 4,
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "runtimeStatistics": {
+ "Completed": "string",
+ "Failed": "string",
+ "Running": "string",
+ "In Queue": "string",
+ "Average Length": "2021-11-26T15:18:27.693Z",
+ "Total Runtime": "2021-11-26T15:18:27.693Z",
+ "Total": "string",
+ "Consumed": "string"
+ },
+ "constraints": [
+ {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+ }
+ ],
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ],
+ "backtests": {
+ "name": "string",
+ "id": "string",
+ "progress": 0,
+ "exitCode": 0,
+ "statistics": [
+ "number"
+ ],
+ "parameterSet": ,
+ "equity": [
+ "array"
+ ],
+ "startDate": "2021-11-26T15:18:27.693Z",
+ "endDate": "2021-11-26T15:18:27.693Z",
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z"
+ },
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
+ "requested": "2021-11-26T15:18:27.693Z",
+ "optimizationTarget": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "targetValue": 1,
+ "gridLayout": [
+ {
+ "chartName": "string",
+ "width": 0,
+ "height": 0,
+ "row": 0,
+ "column": 0,
+ "sort": 0,
+ "definition": [
+ "string"
+ ]
+ }
+ ],
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "outOfSampleDays": 0,
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0
+}
+ |
+
+
+ OptimizationTargetTo
+
+ Model
+ |
+ |
|---|---|
| + GridChart + | +
+
+ string Enum
+
+ + /. Options : ['min', 'max'] + |
+
| + Example + | +
+
+
+
+{
+ "GridChart": "min"
+}
+ |
+
+
+ OptimizationNodeType
+
+ Model - Optimization node types available in QuantConnect Cloud.
+ |
+ |
|---|---|
| + GridChart + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + Example + | +
+
+
+
+{
+ "GridChart": "O2-8"
+}
+ |
+
+
+ OptimizationTarget
+
+ Model
+ |
+ |
|---|---|
| + target + | +
+
+ string Enum
+
+ + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + extremum + | +
+
+ string Enum
+
+ + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + targetValue + | +
+
+ number
+
+ + Desired value for the optimization target statistic. + |
+
| + Example + | +
+
+
+
+{
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+}
+ |
+
+
+ OptimizationTargetStatistic
+
+ Model
+ |
+ |
|---|---|
| + GridChart + | +
+
+ string Enum
+
+ + /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + Example + | +
+
+
+
+{
+ "GridChart": "TotalPerformance.PortfolioStatistics.SharpeRatio"
+}
+ |
+
+
+ OptimizationRuntimeStatistics
+
+ Model
+ |
+ |
|---|---|
| + Completed + | +
+
+ string
+
+ + Number of completed backtests in the optimization job. + |
+
| + Failed + | +
+
+ string
+
+ + Number of failed backtests in the optimization job. + |
+
| + Running + | +
+
+ string
+
+ + Number of running backtests in the optimization job. + |
+
| + In Queue + | +
+
+ string
+
+ + Number of backtests waiting in-queue in the optimization job. + |
+
| + Average Length + | +
+
+ string($time)
+
+ + The average time of each backtest in the optimization job (HH:MM:SS). + |
+
| + Total Runtime + | +
+
+ string($time)
+
+ + The total runtime of the optimization (HH:MM:SS). + |
+
| + Total + | +
+
+ string
+
+ + Number of backtests in the optimization job. + |
+
| + Consumed + | +
+
+ string
+
+ + Amount of QuantConnect Credit consumed by the optimization job. + |
+
| + Example + | +
+
+
+
+{
+ "Completed": "string",
+ "Failed": "string",
+ "Running": "string",
+ "In Queue": "string",
+ "Average Length": "2021-11-26T15:18:27.693Z",
+ "Total Runtime": "2021-11-26T15:18:27.693Z",
+ "Total": "string",
+ "Consumed": "string"
+}
+ |
+
+
+ OptimizationConstraint
+
+ Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ |
+ |
|---|---|
| + target + | +
+
+ string Enum
+
+ + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + operator + | +
+
+ string Enum
+
+ + The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] + |
+
| + targetValue + | +
+
+ number
+
+ + The threshold value for the target constraint. + |
+
| + Example + | +
+
+
+
+{
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+}
+ |
+
+
+ OptimizationParameter
+
+ Model
+ |
+ |
|---|---|
| + name + | +
+
+ string
+
+ + Name of optimization parameter. + |
+
| + min + | +
+
+ number
+
+ + Minimum value of optimization parameter, applicable for boundary conditions. + |
+
| + max + | +
+
+ number
+
+ + Maximum value of optimization parameter, applicable for boundary conditions. + |
+
| + step + | +
+
+ number
+
+ + Movement, should be positive. + |
+
| + minStep + | +
+
+ number
+
+ + Minimal possible movement for current parameter, should be positive. Used by +
+ Strategies.EulerSearchOptimizationStrategy
+
+ to determine when this parameter can no longer be optimized.
+ |
+
| + Example + | +
+
+
+
+{
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+}
+ |
+
+
+ OptimizationBacktest
+
+ Model
+ |
+ |
|---|---|
| + name + | +
+
+ string
+
+ + The backtest name. + |
+
| + id + | +
+
+ string
+
+ + Id of the backtest. + |
+
| + progress + | +
+
+ number
+
+ + Progress of the backtest as a percentage from 0-1 based on the days lapsed from start-finish. + |
+
| + exitCode + | +
+
+ integer
+
+ + The exit code of this backtest. + |
+
| + statistics + | +
+
+ number Array
+
+ + The backtest statistics results. [alpha, annual standard deviation, annual variance, average loss (%), average win (%), beta, compounding annual return (%), drawdown (%), estimated strategy capacity, expectancy, information ratio, loss rate (%), net profit (%), probabilistic sharpe ratio, profit-loss ratio, sharpe ratio, total fees, total orders, tracking error, treynor ratio, win rate (%)]. + |
+
| + parameterSet + | +
+
+ ParameterSet object
+
+ + Parameters used in the backtest. + |
+
| + equity + | +
+
+ array Array
+
+ + The backtest equity chart series. + |
+
| + startDate + | +
+
+ string($date-time)
+
+ + The backtest start date. + |
+
| + endDate + | +
+
+ string($date-time)
+
+ + The backtest end date. + |
+
| + outOfSampleDays + | +
+
+ integer
+
+ + The backtest out-of-sample day count. + |
+
| + outOfSampleMaxEndDate + | +
+
+ string($date-time)
+
+ + End date of out-of-sample data. + |
+
| + Example + | +
+
+
+
+{
+ "name": "string",
+ "id": "string",
+ "progress": 0,
+ "exitCode": 0,
+ "statistics": [
+ "number"
+ ],
+ "parameterSet": ,
+ "equity": [
+ "array"
+ ],
+ "startDate": "2021-11-26T15:18:27.693Z",
+ "endDate": "2021-11-26T15:18:27.693Z",
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z"
+}
+ |
+
+
+ OptimizationStrategy
+
+ Model
+ |
+ |
|---|---|
| + value + | +
+
+ string Enum
+
+ + /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + |
+
| + Example + | +
+
+
+
+{
+ "value": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy"
+}
+ |
+
+
+ GridChart
+
+ Model - The chart display properties.
+ |
+ |
|---|---|
| + chartName + | +
+
+ string
+
+ + The chart name. + |
+
| + width + | +
+
+ integer
+
+ + Width of the chart. + |
+
| + height + | +
+
+ integer
+
+ + Height of the chart. + |
+
| + row + | +
+
+ integer
+
+ + Number of rows of the chart. + |
+
| + column + | +
+
+ integer
+
+ + Number of columns of the chart. + |
+
| + sort + | +
+
+ integer
+
+ + Sort of the chart. + |
+
| + definition + | +
+
+ string Array
+
+ + The chart definition labels. + |
+
| + Example + | +
+
+
+
+{
+ "chartName": "string",
+ "width": 0,
+ "height": 0,
+ "row": 0,
+ "column": 0,
+ "sort": 0,
+ "definition": [
+ "string"
+ ]
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The project ID of the project to manage an optimization job
+project_id = 12345678
+
+### Estimate Optimization Cost
+# Send a POST request to the /optimizations/estimate endpoint to estimate cost
+response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
+ "targetTo": "max", # Direction to optimize (maximize)
+ "targetValue": None, # Specific target value (None for max/min)
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
+ "compileId": compile_id, # Compilation ID for the optimization
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value for first parameter
+ "parameters[0][max]": 200, # Maximum value for first parameter
+ "parameters[0][step]": 50, # Step size for first parameter
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value for second parameter
+ "parameters[1][max]": 300, # Maximum value for second parameter
+ "parameters[1][step]": 50, # Step size for second parameter
+ "constraints": [{ # Constraints for the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the estimated cost
+if result['success']:
+ print("Optimization Cost Estimated Successfully:")
+ print(result)
+
+### Create Optimization
+# Send a POST request to the /optimizations/create endpoint to create an optimization
+response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
+ "targetTo": "max", # Direction to optimize
+ "targetValue": None, # Specific target value
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
+ "compileId": compile_id, # Compilation ID
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value
+ "parameters[0][max]": 200, # Maximum value
+ "parameters[0][step]": 50, # Step size
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value
+ "parameters[1][max]": 300, # Maximum value
+ "parameters[1][step]": 50, # Step size
+ "constraints": [{ # Constraints
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }],
+ "estimatedCost": 10, # Estimated cost of optimization
+ "nodeType": "O2-8", # Node type for optimization
+ "parallelNodes": 4 # Number of parallel nodes
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the optimization ID from the response
+optimization_id = result['optimizations'][0]['optimizationId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Created Successfully:")
+ print(result)
+
+### Update Optimization
+# Send a POST request to the /optimizations/update endpoint to update the optimization
+response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
+ "optimizationId": optimization_id, # ID of the optimization to update
+ "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Updated Successfully:")
+ print(result)
+
+### Read Optimization
+# Prepare data payload to read optimization details
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to read
+}
+# Send a POST request to the /optimizations/read endpoint to get details
+response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the details
+if result['success']:
+ print("Optimization Details:")
+ print(result)
+
+### Abort Optimization
+# Prepare data payload to abort the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to abort
+}
+# Send a POST request to the /optimizations/abort endpoint to abort
+response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Aborted Successfully:")
+ print(result)
+
+### Delete Optimization
+# Prepare data payload to delete the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to delete
+}
+# Send a POST request to the /optimizations/delete endpoint to delete
+response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Deleted Successfully:")
+ print(result)
+
+### List Optimizations
+# Prepare data payload to list optimizations
+payload = {
+ "projectId": project_id # ID of the project
+}
+# Send a POST request to the /optimizations/list endpoint to list optimizations
+response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Optimizations:")
+ print(result)
+ + +
+ Update the name of an optimization. +
+ + + +
+ The
+
+ /optimizations/update
+
+ API accepts requests in the following format:
+
+
+ UpdateOptimizationRequest
+
+ Model - Update the name of an optimization.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization to update. + |
+
| + name + | +
+
+ string
+
+ + Name to assign to the optimization. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "name": "New Optimization Name"
+}
+ |
+
+ The
+
+ /optimizations/update
+
+ API provides a response in the following format:
+
+
+ RestResponse
+
+ Model - Base API response class for the QuantConnect API.
+ |
+ |
|---|---|
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The project ID of the project to manage an optimization job
+project_id = 12345678
+
+### Estimate Optimization Cost
+# Send a POST request to the /optimizations/estimate endpoint to estimate cost
+response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
+ "targetTo": "max", # Direction to optimize (maximize)
+ "targetValue": None, # Specific target value (None for max/min)
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
+ "compileId": compile_id, # Compilation ID for the optimization
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value for first parameter
+ "parameters[0][max]": 200, # Maximum value for first parameter
+ "parameters[0][step]": 50, # Step size for first parameter
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value for second parameter
+ "parameters[1][max]": 300, # Maximum value for second parameter
+ "parameters[1][step]": 50, # Step size for second parameter
+ "constraints": [{ # Constraints for the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the estimated cost
+if result['success']:
+ print("Optimization Cost Estimated Successfully:")
+ print(result)
+
+### Create Optimization
+# Send a POST request to the /optimizations/create endpoint to create an optimization
+response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
+ "targetTo": "max", # Direction to optimize
+ "targetValue": None, # Specific target value
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
+ "compileId": compile_id, # Compilation ID
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value
+ "parameters[0][max]": 200, # Maximum value
+ "parameters[0][step]": 50, # Step size
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value
+ "parameters[1][max]": 300, # Maximum value
+ "parameters[1][step]": 50, # Step size
+ "constraints": [{ # Constraints
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }],
+ "estimatedCost": 10, # Estimated cost of optimization
+ "nodeType": "O2-8", # Node type for optimization
+ "parallelNodes": 4 # Number of parallel nodes
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the optimization ID from the response
+optimization_id = result['optimizations'][0]['optimizationId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Created Successfully:")
+ print(result)
+
+### Update Optimization
+# Send a POST request to the /optimizations/update endpoint to update the optimization
+response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
+ "optimizationId": optimization_id, # ID of the optimization to update
+ "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Updated Successfully:")
+ print(result)
+
+### Read Optimization
+# Prepare data payload to read optimization details
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to read
+}
+# Send a POST request to the /optimizations/read endpoint to get details
+response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the details
+if result['success']:
+ print("Optimization Details:")
+ print(result)
+
+### Abort Optimization
+# Prepare data payload to abort the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to abort
+}
+# Send a POST request to the /optimizations/abort endpoint to abort
+response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Aborted Successfully:")
+ print(result)
+
+### Delete Optimization
+# Prepare data payload to delete the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to delete
+}
+# Send a POST request to the /optimizations/delete endpoint to delete
+response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Deleted Successfully:")
+ print(result)
+
+### List Optimizations
+# Prepare data payload to list optimizations
+payload = {
+ "projectId": project_id # ID of the project
+}
+# Send a POST request to the /optimizations/list endpoint to list optimizations
+response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Optimizations:")
+ print(result)
+ + +
+ Delete an optimization. +
+ + + +
+ The
+
+ /optimizations/delete
+
+ API accepts requests in the following format:
+
+
+ DeleteOptimizationRequest
+
+ Model - Delete an optimization.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization to delete. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd"
+}
+ |
+
+ The
+
+ /optimizations/delete
+
+ API provides a response in the following format:
+
+
+ RestResponse
+
+ Model - Base API response class for the QuantConnect API.
+ |
+ |
|---|---|
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
- The following example demonstates creating, reading, updating, and listing live algorithms of a project through the cloud API. + The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The project ID of the project to manage an optimization job
+project_id = 12345678
+
+### Estimate Optimization Cost
+# Send a POST request to the /optimizations/estimate endpoint to estimate cost
+response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
+ "targetTo": "max", # Direction to optimize (maximize)
+ "targetValue": None, # Specific target value (None for max/min)
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
+ "compileId": compile_id, # Compilation ID for the optimization
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value for first parameter
+ "parameters[0][max]": 200, # Maximum value for first parameter
+ "parameters[0][step]": 50, # Step size for first parameter
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value for second parameter
+ "parameters[1][max]": 300, # Maximum value for second parameter
+ "parameters[1][step]": 50, # Step size for second parameter
+ "constraints": [{ # Constraints for the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the estimated cost
+if result['success']:
+ print("Optimization Cost Estimated Successfully:")
+ print(result)
+
+### Create Optimization
+# Send a POST request to the /optimizations/create endpoint to create an optimization
+response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
+ "targetTo": "max", # Direction to optimize
+ "targetValue": None, # Specific target value
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
+ "compileId": compile_id, # Compilation ID
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value
+ "parameters[0][max]": 200, # Maximum value
+ "parameters[0][step]": 50, # Step size
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value
+ "parameters[1][max]": 300, # Maximum value
+ "parameters[1][step]": 50, # Step size
+ "constraints": [{ # Constraints
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }],
+ "estimatedCost": 10, # Estimated cost of optimization
+ "nodeType": "O2-8", # Node type for optimization
+ "parallelNodes": 4 # Number of parallel nodes
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the optimization ID from the response
+optimization_id = result['optimizations'][0]['optimizationId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Created Successfully:")
+ print(result)
+
+### Update Optimization
+# Send a POST request to the /optimizations/update endpoint to update the optimization
+response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
+ "optimizationId": optimization_id, # ID of the optimization to update
+ "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Updated Successfully:")
+ print(result)
+
+### Read Optimization
+# Prepare data payload to read optimization details
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to read
+}
+# Send a POST request to the /optimizations/read endpoint to get details
+response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the details
+if result['success']:
+ print("Optimization Details:")
+ print(result)
+
+### Abort Optimization
+# Prepare data payload to abort the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to abort
+}
+# Send a POST request to the /optimizations/abort endpoint to abort
+response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Aborted Successfully:")
+ print(result)
+
+### Delete Optimization
+# Prepare data payload to delete the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to delete
+}
+# Send a POST request to the /optimizations/delete endpoint to delete
+response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Deleted Successfully:")
+ print(result)
+
+### List Optimizations
+# Prepare data payload to list optimizations
+payload = {
+ "projectId": project_id # ID of the project
+}
+# Send a POST request to the /optimizations/list endpoint to list optimizations
+response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Optimizations:")
+ print(result)
+ + +
+ Abort an optimization. +
+ + + +
+ The
+
+ /optimizations/abort
+
+ API accepts requests in the following format:
+
+
+ AbortOptimizationRequest
+
+ Model - Abort an optimization.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization to abort. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd"
+}
+ |
+
+ The
+
+ /optimizations/abort
+
+ API provides a response in the following format:
+
+
+ RestResponse
+
+ Model - Base API response class for the QuantConnect API.
+ |
+ |
|---|---|
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API.
from base64 import b64encode @@ -81893,235 +88278,639 @@Examples
# -------------------- -### Create Live Algorithm -# Define placeholder IDs for compilation and node (replace with actual values) -project_id = 12345678 -compile_id = "compile_id..." -node_id = "node_id..." -# Prepare the data payload for creating a live algorithm with necessary details -payload = { - "versionId": "-1", # Use the latest version of the algorithm - "projectId": project_id, # ID of the project to deploy as a live algorithm - "compileId": compile_id, # Compilation ID for the algorithm code - "nodeId": node_id, # Node ID where the algorithm will run - "brokerage": { # Brokerage configuration for live trading - "id": "QuantConnectBrokerage", # Brokerage identifier - "user": "", # Brokerage username (replace with actual value) - "password": "", # Brokerage password (replace with actual value) - "environment": "live-paper", # Trading environment (live or paper) - "account": "" # Brokerage account ID (replace with actual value) - }, - "dataProviders": { # Data provider configuration - "QuantConnectBrokerage": { - "id": "QuantConnectBrokerage" # Data provider identifier - } - }, - "parameters": {}, # Optional algorithm parameters (empty in this example) - "notification": {} # Optional notification settings (empty in this example) -} -# Send a POST request to the /live/create endpoint to deploy the algorithm -response = post(f'{BASE_URL}/live/create', headers=get_headers(), json=data) -# Parse the JSON response into python managable dict from the API +# The project ID of the project to manage an optimization job +project_id = 12345678 + +### Estimate Optimization Cost +# Send a POST request to the /optimizations/estimate endpoint to estimate cost +response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={ + "projectId": project_id, # ID of the project + "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix) + "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric + "targetTo": "max", # Direction to optimize (maximize) + "targetValue": None, # Specific target value (None for max/min) + "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy + "compileId": compile_id, # Compilation ID for the optimization + "parameters[0][key]": "ema_fast", # First parameter key + "parameters[0][min]": 100, # Minimum value for first parameter + "parameters[0][max]": 200, # Maximum value for first parameter + "parameters[0][step]": 50, # Step size for first parameter + "parameters[1][key]": "ema_slow", # Second parameter key + "parameters[1][min]": 200, # Minimum value for second parameter + "parameters[1][max]": 300, # Maximum value for second parameter + "parameters[1][step]": 50, # Step size for second parameter + "constraints": [{ # Constraints for the optimization + "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", + "operator": "greater", + "target-value": 1 + }] +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the estimated cost +if result['success']: + print("Optimization Cost Estimated Successfully:") + print(result) + +### Create Optimization +# Send a POST request to the /optimizations/create endpoint to create an optimization +response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={ + "projectId": project_id, # ID of the project + "name": f"Optimization_{compileId[:5]}", # Name of the optimization + "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target + "targetTo": "max", # Direction to optimize + "targetValue": None, # Specific target value + "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy + "compileId": compile_id, # Compilation ID + "parameters[0][key]": "ema_fast", # First parameter key + "parameters[0][min]": 100, # Minimum value + "parameters[0][max]": 200, # Maximum value + "parameters[0][step]": 50, # Step size + "parameters[1][key]": "ema_slow", # Second parameter key + "parameters[1][min]": 200, # Minimum value + "parameters[1][max]": 300, # Maximum value + "parameters[1][step]": 50, # Step size + "constraints": [{ # Constraints + "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", + "operator": "greater", + "target-value": 1 + }], + "estimatedCost": 10, # Estimated cost of optimization + "nodeType": "O2-8", # Node type for optimization + "parallelNodes": 4 # Number of parallel nodes +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the optimization ID from the response +optimization_id = result['optimizations'][0]['optimizationId'] +# Check if the request was successful and print the result +if result['success']: + print("Optimization Created Successfully:") + print(result) + +### Update Optimization +# Send a POST request to the /optimizations/update endpoint to update the optimization +response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={ + "optimizationId": optimization_id, # ID of the optimization to update + "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization +}) +# Parse the JSON response into python managable dict result = response.json() -# Extract the deploy ID from the response for future operations -deploy_id = result['deployId'] # Check if the request was successful and print the result if result['success']: - print("Live Algorithm Created Successfully:") + print("Optimization Updated Successfully:") print(result) -### Read Live Algorithm Statistics -# Prepare data payload with project and deploy IDs to fetch statistics +### Read Optimization +# Prepare data payload to read optimization details payload = { - "projectId": project_id, # ID of the project - "deployId": deploy_id # ID of the deployed live algorithm + "optimizationId": optimization_id # ID of the optimization to read } -# Send a POST request to the /live/read endpoint to get algorithm statistics -response = post(f'{BASE_URL}/live/read', headers=get_headers(), json=payload) +# Send a POST request to the /optimizations/read endpoint to get details +response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the statistics +# Check if the request was successful and print the details if result['success']: - print("Live Algorithm Statistics:") + print("Optimization Details:") print(result) -### Liquidate Live Algorithm -# Prepare data payload with project ID to liquidate the algorithm +### Abort Optimization +# Prepare data payload to abort the optimization payload = { - "projectId": project_id # ID of the project to liquidate + "optimizationId": optimization_id # ID of the optimization to abort } -# Send a POST request to the /live/update/liquidate endpoint to liquidate -response = post(f'{BASE_URL}/live/update/liquidate', headers=get_headers(), json=payload) +# Send a POST request to the /optimizations/abort endpoint to abort +response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the result if result['success']: - print("Live Algorithm Liquidated Successfully:") + print("Optimization Aborted Successfully:") print(result) -### Stop Live Algorithm -# Prepare data payload with project ID to stop the algorithm +### Delete Optimization +# Prepare data payload to delete the optimization payload = { - "projectId": project_id # ID of the project to stop + "optimizationId": optimization_id # ID of the optimization to delete } -# Send a POST request to the /live/update/stop endpoint to stop the algorithm -response = post(f'{BASE_URL}/live/update/stop', headers=get_headers(), json=payload) +# Send a POST request to the /optimizations/delete endpoint to delete +response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the result if result['success']: - print("Live Algorithm Stopped Successfully:") + print("Optimization Deleted Successfully:") print(result) -### List Live Algorithms -# Prepare data payload with filters for listing live algorithms +### List Optimizations +# Prepare data payload to list optimizations payload = { - "status": "Running", # Filter to show only running algorithms - "start": 1717801200, # Start time (Unix timestamp) for the list range - "end": 1743462000 # End time (Unix timestamp) for the list range + "projectId": project_id # ID of the project } -# Send a POST request to the /live/list endpoint to list algorithms -response = post(f'{BASE_URL}/live/list', headers=get_headers(), json=payload) +# Send a POST request to the /optimizations/list endpoint to list optimizations +response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the list if result['success']: - print("List of Live Algorithms:") + print("List of Optimizations:") print(result)
- +
- The QuantConnect REST API send commands to live algorithms on our cloud servers through URL endpoints. -
-+ List all the optimizations for a project. +
-- -
- Send a live command to a live trading algorithm.
+ If of the Project to get a list of optimizations for. The
+
+ /optimizations/list
+
+ API accepts requests in the following format:
+
+ ListOptimizationRequest
+
+ Model - Id of the Project to get a list of optimizations for.
+ |
+ |
|---|---|
| + projectId + | +
+
+ integer
+
+ + Id of the Project to get a list of optimizations for. + |
+
| + Example + | +
+
+
+
+{
+ "projectId": 23456789
+}
+ |
+
- Sends a command to a live deployment to trigger an action such as placing orders. The
+ The
- /live/commands/create
+ /optimizations/list
- API accepts requests in the following format:
+ API provides a response in the following format:
+
+ ListOptimizationResponse
+
+ Model - Response received when creating an optimization or listing optimizations of a project.
+ |
+ |
|---|---|
| + optimizations + | +
+
+ CreateOptimizationResponse Array
+
+ + Collection of summarized optimization objects. + |
+
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+
| + Example + | +
+
+
+
+{
+ "optimizations": [
+ {
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "projectId": 23456789,
+ "name": "string",
+ "status": ,
+ "nodeType": "O2-8",
+ "extremum": "min",
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0,
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ]
+ }
+ ],
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+
+ CreateOptimizationResponse
+
+ Model - Response received when launching an optimization job or listing all the optimization jobs of a project.
+ |
+ |
|---|---|
| + optimizationId + | +
+
+ string
+
+ + Id of the optimization job. + |
+
| + projectId + | +
+
+ integer
+
+ + Id of the project the optimization belongs to. + |
+
| + name + | +
+
+ string
+
+ + Name of the optimization. + |
+
| + status + | +
+
+ OptimizationStatus object
+
+ + Status of the optimization. + |
+
| + nodeType + | +
+
+ string Enum
+
+ + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + |
+
| + extremum + | +
+
+ string Enum
+
+ + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + criterion + | +
+
+ OptimizationTarget object
+
+ + Optimization statistical target. + |
+
| + created + | +
+
+ string($date-time)
+
+ + Date and time of when this optimization was created. + |
+
| + psr + | +
+
+ number
+
+ + Probabilistic Sharpe ratio statistic. + |
+
| + sharpeRatio + | +
+
+ number
+
+ + Sharpe ratio statistic. + |
+
| + trades + | +
+
+ integer
+
+ + Number of trades in the best backtest (based on the criterion) of the optimziation. + |
+
| + cloneId + | +
+
+ integer
+
+ + Id of project where this current project was originally cloned. + |
+
| + outOfSampleDays + | +
+
+ integer
+
+ + Number out-of-sample days. + |
+
| + outOfSampleMaxEndDate + | +
+
+ string($date-time)
+
+ + End date of out-of-sample data. + |
+
| + parameters + | +
+
+ OptimizationParameter Array
+
+ + Parameters used in this optimization. + |
+
| + Example + | +
+
+
+
+{
+ "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
+ "projectId": 23456789,
+ "name": "string",
+ "status": ,
+ "nodeType": "O2-8",
+ "extremum": "min",
+ "criterion": {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "extremum": "min",
+ "targetValue": 1
+ },
+ "created": "2021-11-26T15:18:27.693Z",
+ "psr": 0,
+ "sharpeRatio": 0,
+ "trades": 0,
+ "cloneId": 0,
+ "outOfSampleDays": 0,
+ "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ]
+}
+ |
+
- CreateLiveCommandRequest
+ OptimizationNodeType
- Model - Request to create a live command.
+ Model - Optimization node types available in QuantConnect Cloud.
|
|
|---|---|
| - projectId + OptimizationParameter |
- integer
-
- Project for the live instance we want to run the command against. + Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] |
| - command + Example + | +
+
+
+
+{
+ "OptimizationParameter": "O2-8"
+}
+ |
+
+
+ OptimizationTargetTo
+
+ Model
+ |
+ |
|---|---|
| + OptimizationParameter |
- object
-
- The command to run. + /. Options : ['min', 'max'] |
- The
-
- /live/commands/create
-
- API provides a response in the following format:
-
- RestResponse
+ OptimizationTarget
- Model - Base API response class for the QuantConnect API.
+ Model
|
|
|---|---|
| - success + target |
- boolean
+ string Enum
- Indicate if the API request was successful. + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] |
| - errors + extremum |
- string Array
+ string Enum
- List of errors with the API call. + Defines the direction of optimization. Options : ['min', 'max'] + |
+
| + targetValue + | +
+
+ number
+
+ + Desired value for the optimization target statistic. |
- UnauthorizedError
+ OptimizationTargetStatistic
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ Model
|
|
|---|---|
| - www_authenticate + OptimizationParameter |
- string
+ string Enum
- Header + /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + Example + | +
+
+
+{
+ "OptimizationParameter": "TotalPerformance.PortfolioStatistics.SharpeRatio"
+}
+ |
- The following example demonstates creating, reading, updating, and listing live algorithms of a project through the cloud API. -
-from base64 import b64encode
-from hashlib import sha256
-from time import time
-from requests import get, post
-BASE_URL = 'https://www.quantconnect.com/api/v2/'
-
-# You need to replace these with your actual credentials.
-# You can request your credentials at https://www.quantconnect.com/settings/
-# You can find our organization ID at https://www.quantconnect.com/organization/
-USER_ID = 0
-API_TOKEN = '____'
-ORGANIZATION_ID = '____'
-
-def get_headers():
- # Get timestamp
- timestamp = f'{int(time())}'
- time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
-
- # Get hased API token
- hashed_token = sha256(time_stamped_token).hexdigest()
- authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
- authentication = b64encode(authentication).decode('ascii')
-
- # Create headers dictionary.
- return {
- 'Authorization': f'Basic {authentication}',
- 'Timestamp': timestamp
- }
-
-# Authenticate to verify credentials
-response = post(f'{BASE_URL}/authenticate', headers = get_headers())
-print(response.json())
-
-# --------------------
-
-
-### Create Live Algorithm
-# Define placeholder IDs for compilation and node (replace with actual values)
-project_id = 12345678
-compile_id = "compile_id..."
-node_id = "node_id..."
-# Prepare the data payload for creating a live algorithm with necessary details
-payload = {
- "versionId": "-1", # Use the latest version of the algorithm
- "projectId": project_id, # ID of the project to deploy as a live algorithm
- "compileId": compile_id, # Compilation ID for the algorithm code
- "nodeId": node_id, # Node ID where the algorithm will run
- "brokerage": { # Brokerage configuration for live trading
- "id": "QuantConnectBrokerage", # Brokerage identifier
- "user": "", # Brokerage username (replace with actual value)
- "password": "", # Brokerage password (replace with actual value)
- "environment": "live-paper", # Trading environment (live or paper)
- "account": "" # Brokerage account ID (replace with actual value)
- },
- "dataProviders": { # Data provider configuration
- "QuantConnectBrokerage": {
- "id": "QuantConnectBrokerage" # Data provider identifier
- }
- },
- "parameters": {}, # Optional algorithm parameters (empty in this example)
- "notification": {} # Optional notification settings (empty in this example)
-}
-# Send a POST request to the /live/create endpoint to deploy the algorithm
-response = post(f'{BASE_URL}/live/create', headers=get_headers(), json=data)
-# Parse the JSON response into python managable dict from the API
-result = response.json()
-# Extract the deploy ID from the response for future operations
-deploy_id = result['deployId']
-# Check if the request was successful and print the result
-if result['success']:
- print("Live Algorithm Created Successfully:")
- print(result)
-
-### Read Live Algorithm Statistics
-# Prepare data payload with project and deploy IDs to fetch statistics
-payload = {
- "projectId": project_id, # ID of the project
- "deployId": deploy_id # ID of the deployed live algorithm
-}
-# Send a POST request to the /live/read endpoint to get algorithm statistics
-response = post(f'{BASE_URL}/live/read', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the statistics
-if result['success']:
- print("Live Algorithm Statistics:")
- print(result)
-
-### Liquidate Live Algorithm
-# Prepare data payload with project ID to liquidate the algorithm
-payload = {
- "projectId": project_id # ID of the project to liquidate
-}
-# Send a POST request to the /live/update/liquidate endpoint to liquidate
-response = post(f'{BASE_URL}/live/update/liquidate', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Live Algorithm Liquidated Successfully:")
- print(result)
-
-### Stop Live Algorithm
-# Prepare data payload with project ID to stop the algorithm
-payload = {
- "projectId": project_id # ID of the project to stop
-}
-# Send a POST request to the /live/update/stop endpoint to stop the algorithm
-response = post(f'{BASE_URL}/live/update/stop', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Live Algorithm Stopped Successfully:")
- print(result)
-
-### List Live Algorithms
-# Prepare data payload with filters for listing live algorithms
-payload = {
- "status": "Running", # Filter to show only running algorithms
- "start": 1717801200, # Start time (Unix timestamp) for the list range
- "end": 1743462000 # End time (Unix timestamp) for the list range
-}
-# Send a POST request to the /live/list endpoint to list algorithms
-response = post(f'{BASE_URL}/live/list', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the list
-if result['success']:
- print("List of Live Algorithms:")
- print(result)
- - -
- Broadcast a live command to all live algorithms in the organization. -
- - - -
- Broadcasts a command to all live deployments in the organization. The
-
- /live/commands/broadcast
-
- API accepts requests in the following format:
-
- BroadcastLiveCommandRequest
+ OptimizationParameter
- Model - Request to create a live command.
+ Model
|
|
|---|---|
| - organizationId + name |
@@ -82447,39 +89060,45 @@
- Organization Id of the projects we would like to broadcast the command to. + Name of optimization parameter. |
| - excludeProjectId + min |
- integer
+ number
- Project for the live instance we want to exclude from the broadcast list. If null, all projects will be included. + Minimum value of optimization parameter, applicable for boundary conditions. |
| - command + max |
- object
+ number
- - The command to run. - |
-
| - Example - | -
-
-
-
-{
- "organizationId": "5cad178b20a1d52567b534553413b691",
- "excludeProjectId": 23456789,
- "command": {
- "$type": "OrderCommand",
- "symbol": {
- "id": "BTCUSD 2XR",
- "value": "BTCUSD"
- },
- "order_type": "market",
- "quantity": "0.1",
- "limit_price": 0,
- "stop_price": 0,
- "tag": ""
-}
-}
- |
-
- The
-
- /live/commands/broadcast
-
- API provides a response in the following format:
-
-
- RestResponse
-
- Model - Base API response class for the QuantConnect API.
- |
- |
|---|---|
| - success + step |
- boolean
+ number
+
- Indicate if the API request was successful. + Movement, should be positive. |
| - errors + minStep |
- string Array
+ number
+
- List of errors with the API call. + Minimal possible movement for current parameter, should be positive. Used by +
+ Strategies.EulerSearchOptimizationStrategy
+
+ to determine when this parameter can no longer be optimized.
|
- CreateOptimizationRequest
+ EstimateOptimizationRequest
- Model - Request to create an optimization job.
+ Model - Request to estimate the cost of an optimization job.
|
compileId | +
+
+ string
+
+ + Optimization compile Id. + |
+
+
| + parameters + | +
+
+ OptimizationParameter Array
+
+ + Optimization parameters. + |
+
| + constraints + | +
+
+ OptimizationConstraint Array
+
+ + Optimization constraints. + |
+
| + Example + | +
+
+
+
+{
+ "projectId": 23456789,
+ "name": "Mia First Optimization Job",
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "targetTo": "min",
+ "targetValue": 1,
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
+ "compileId": "5d1f2cba3a0ec7407c566614300502b5-173e0419674daf4144ce7c9931155ca8",
+ "parameters": [
+ {
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+ }
+ ],
+ "constraints": [
+ {
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "LessOrEqual",
+ "targetValue": 1
+ }
+ ]
+}
+ |
+
+
+ OptimizationTargetStatistic
+
+ Model
+ |
+ |
|---|---|
| + OptimizationConstraint + | +
+
+ string Enum
+
+ + /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationConstraint": "TotalPerformance.PortfolioStatistics.SharpeRatio"
+}
+ |
+
+
+ OptimizationTargetTo
+
+ Model
+ |
+ |
|---|---|
| + OptimizationConstraint + | +
+
+ string Enum
+
+ + /. Options : ['min', 'max'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationConstraint": "min"
+}
+ |
+
+
+ OptimizationStrategy
+
+ Model
+ |
+ |
|---|---|
| + OptimizationConstraint + | +
+
+ string Enum
+
+ + /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + |
+
| + Example + | +
+
+
+
+{
+ "OptimizationConstraint": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy"
+}
+ |
+
+
+ OptimizationParameter
+
+ Model
+ |
+ |
|---|---|
| + name + |
string
@@ -82930,87 +89759,174 @@
+ + Name of optimization parameter. + |
+
| + min + | +
+
+ number
+
+ + Minimum value of optimization parameter, applicable for boundary conditions. + |
+
| + max + | +
+
+ number
+
+ + Maximum value of optimization parameter, applicable for boundary conditions. + |
+
| + step + | +
+
+ number
+
- Optimization compile Id. + Movement, should be positive. |
| - parameters + minStep |
- OptimizationParameter Array
+ number
- Optimization parameters. + Minimal possible movement for current parameter, should be positive. Used by +
+ Strategies.EulerSearchOptimizationStrategy
+
+ to determine when this parameter can no longer be optimized.
|
| - constraints + Example |
-
- OptimizationConstraint Array
-
- - Optimization constraints. +
+
+{
+ "name": "rsi_period",
+ "min": 10,
+ "max": 20,
+ "step": 1,
+ "minStep": 1
+}
+ |
+
+ OptimizationConstraint
+
+ Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ |
+ |
|---|---|
| - estimatedCost + target |
- number
-
- Estimated cost for optimization. + The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] |
| - nodeType + operator |
string Enum
+
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] |
| - parallelNodes + targetValue |
- integer
+ number
- Number of parallel nodes for optimization. + The threshold value for the target constraint. |
+ The
+
+ /optimizations/estimate
+
+ API provides a response in the following format:
+
- OptimizationTargetStatistic
+ EstimateOptimizationResponse
- Model
+ Model - Response received when estimating the cost of an optimization.
|
|
|---|---|
| - OptimizationNodeType + estimate |
- string Enum
+ Estimate object
- /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + Response received when estimating the time to run an optimization job. |
| - Example + success |
-
-
+
-{
- "OptimizationNodeType": "TotalPerformance.PortfolioStatistics.SharpeRatio"
-}
-
+ boolean
+
+ + Indicate if the API request was successful. |
-
- OptimizationTargetTo
-
- Model
- |
- |
|---|---|
| - OptimizationNodeType + errors |
- string Enum
+ string Array
- /. Options : ['min', 'max'] + List of errors with the API call. |
- OptimizationStrategy
+ Estimate
- Model
+ Model - Response received when estimating the time to run an optimization job.
|
|
| - OptimizationNodeType + estimateId |
- string Enum
+ string
- /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + Estimate Id. + |
+
| + time + | +
+
+ integer
+
+ + Estimated time in seconds to run the optimization job. + |
+
| + balance + | +
+
+ integer
+
+ + The organization's QCC balance. |
- OptimizationParameter
+ UnauthorizedError
- Model
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - name + www_authenticate |
string
-
- - Name of optimization parameter. - |
-
| - min - | -
-
- number
-
- Minimum value of optimization parameter, applicable for boundary conditions. + Header |
+ The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The project ID of the project to manage an optimization job
+project_id = 12345678
+
+### Estimate Optimization Cost
+# Send a POST request to the /optimizations/estimate endpoint to estimate cost
+response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
+ "targetTo": "max", # Direction to optimize (maximize)
+ "targetValue": None, # Specific target value (None for max/min)
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
+ "compileId": compile_id, # Compilation ID for the optimization
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value for first parameter
+ "parameters[0][max]": 200, # Maximum value for first parameter
+ "parameters[0][step]": 50, # Step size for first parameter
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value for second parameter
+ "parameters[1][max]": 300, # Maximum value for second parameter
+ "parameters[1][step]": 50, # Step size for second parameter
+ "constraints": [{ # Constraints for the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the estimated cost
+if result['success']:
+ print("Optimization Cost Estimated Successfully:")
+ print(result)
+
+### Create Optimization
+# Send a POST request to the /optimizations/create endpoint to create an optimization
+response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
+ "projectId": project_id, # ID of the project
+ "name": f"Optimization_{compileId[:5]}", # Name of the optimization
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
+ "targetTo": "max", # Direction to optimize
+ "targetValue": None, # Specific target value
+ "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
+ "compileId": compile_id, # Compilation ID
+ "parameters[0][key]": "ema_fast", # First parameter key
+ "parameters[0][min]": 100, # Minimum value
+ "parameters[0][max]": 200, # Maximum value
+ "parameters[0][step]": 50, # Step size
+ "parameters[1][key]": "ema_slow", # Second parameter key
+ "parameters[1][min]": 200, # Minimum value
+ "parameters[1][max]": 300, # Maximum value
+ "parameters[1][step]": 50, # Step size
+ "constraints": [{ # Constraints
+ "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
+ "operator": "greater",
+ "target-value": 1
+ }],
+ "estimatedCost": 10, # Estimated cost of optimization
+ "nodeType": "O2-8", # Node type for optimization
+ "parallelNodes": 4 # Number of parallel nodes
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the optimization ID from the response
+optimization_id = result['optimizations'][0]['optimizationId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Created Successfully:")
+ print(result)
+
+### Update Optimization
+# Send a POST request to the /optimizations/update endpoint to update the optimization
+response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
+ "optimizationId": optimization_id, # ID of the optimization to update
+ "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Updated Successfully:")
+ print(result)
+
+### Read Optimization
+# Prepare data payload to read optimization details
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to read
+}
+# Send a POST request to the /optimizations/read endpoint to get details
+response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the details
+if result['success']:
+ print("Optimization Details:")
+ print(result)
+
+### Abort Optimization
+# Prepare data payload to abort the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to abort
+}
+# Send a POST request to the /optimizations/abort endpoint to abort
+response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Aborted Successfully:")
+ print(result)
+
+### Delete Optimization
+# Prepare data payload to delete the optimization
+payload = {
+ "optimizationId": optimization_id # ID of the optimization to delete
+}
+# Send a POST request to the /optimizations/delete endpoint to delete
+response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Optimization Deleted Successfully:")
+ print(result)
+
+### List Optimizations
+# Prepare data payload to list optimizations
+payload = {
+ "projectId": project_id # ID of the project
+}
+# Send a POST request to the /optimizations/list endpoint to list optimizations
+response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Optimizations:")
+ print(result)
+ + +
+ Upload files to the Object Store. +
+ + + +
+ Upload files to the Object Store. The
+
+ /object/set
+
+ API accepts requests in the following format:
+
+ The
+
+ /object/set
+
+ API requires a file request in the following format:
+
+
+ ObjectStoreBinaryFile
+
+ Model - Represents a binary file we we'd like to upload the file to upload to the Object Store.
+ |
+ |
|---|---|
| - max + organizationId |
- number
+ string
- Maximum value of optimization parameter, applicable for boundary conditions. + Orgainization ID. |
| - step + key |
- number
+ string
- Movement, should be positive. + Unique key to access the object in Object Store. |
| - minStep + objectData |
- number
+ binary
- Minimal possible movement for current parameter, should be positive. Used by -
- Strategies.EulerSearchOptimizationStrategy
-
- to determine when this parameter can no longer be optimized.
+ Object data to be stored.
|
+ The
+
+ /object/set
+
+ API provides a response in the following format:
+
- OptimizationConstraint
+ RestResponse
- Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ Model - Base API response class for the QuantConnect API.
|
|
|---|---|
| - target - | -
-
- string Enum
-
- - The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] - |
-
| - operator + success |
- string Enum
-
- The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] + Indicate if the API request was successful. |
| - targetValue + errors |
- number
-
- The threshold value for the target constraint. + List of errors with the API call. |
- OptimizationNodeType
+ UnauthorizedError
- Model - Optimization node types available in QuantConnect Cloud.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - OptimizationNodeType + www_authenticate |
- string Enum
+ string
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + Header + |
+
+ The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The key of the object wishes to manipulate
+key = "..."
+
+### Upload Object Store File
+# Send a POST request to the /object/set endpoint to upload a file
+response = post(f'{BASE_URL}/object/set', headers=get_headers(),
+ data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
+ files={"objectData": b"Hello, world!"}) # File content as bytes
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Uploaded Successfully:")
+ print(result)
+
+### Get Object Store Metadata
+# Prepare data payload to get object metadata
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to get metadata for
+}
+# Send a POST request to the /object/properties endpoint to get metadata
+response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the metadata
+if result['success']:
+ print("Object Store Metadata:")
+ print(result)
+
+### Get Object Store File
+# Prepare data payload to retrieve the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "keys": [key] # List of keys to retrieve (single key in this case)
+}
+# Send a POST request to the /object/get endpoint to get the object
+response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the file content
+if result['success']:
+ print("Object Store File Content:")
+ print(result)
+
+### Delete Object Store File
+# Prepare data payload to delete the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to delete
+}
+# Send a POST request to the /object/delete endpoint to delete the object
+response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Deleted Successfully:")
+ print(result)
+
+### List Object Store Files
+# Define an empty path to list all objects (replace with specific path if needed)
+path = ""
+# Prepare data payload to list objects
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "path": path # Path to list objects from
+}
+# Send a POST request to the /object/list endpoint to list objects
+response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Object Store Files:")
+ print(result)
+ + +
+ Get Object Store properties of a specific organization and key. It doesn't work if the key is a directory in the Object Store. +
+ + + +
+ Get Object Store properties of a specific organization and key. The
+
+ /object/properties
+
+ API accepts requests in the following format:
+
+
+ GetObjectStorePropertiesRequest
+
+ Model - Request to get Object Store properties of a specific organization and key.
+ |
+ |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| + organizationId + | +
+
+ string
+
+ + Id of the organization that owns the Object Store. + |
+ ||||||||||||||||||||||||||||||||
| + key + | +
+
+ string
+
+ + Key in the Object Store. |
||||||||||||||||||||||||||||||||
- ListOptimizationResponse
+ GetObjectStorePropertiesResponse
- Model - Response received when creating an optimization or listing optimizations of a project.
+ Model - Response received when fetching Object Store file properties.
|
|||||||||||||||||||||||||||||||||
| - optimizations + metadata |
- CreateOptimizationResponse Array
+ ObjectStoreProperties object
- Collection of summarized optimization objects. + Object Store file properties. |
||||||||||||||||||||||||||||||||
- CreateOptimizationResponse
+ ObjectStoreProperties
- Model - Response received when launching an optimization job or listing all the optimization jobs of a project.
+ Model - Object Store file properties.
|
|||||||||||||||||||||||||||||||||
| - optimizationId - | -
-
- string
-
- - Id of the optimization job. - |
- ||||||||||||||||||||||||||||||||
| - projectId - | -
-
- integer
-
- - Id of the project the optimization belongs to. - |
- ||||||||||||||||||||||||||||||||
| - name + key |
string
- Name of the optimization. - |
- ||||||||||||||||||||||||||||||||
| - status - | -
-
- OptimizationStatus object
-
- - Status of the optimization. - |
- ||||||||||||||||||||||||||||||||
| - nodeType - | -
-
- string Enum
-
- - Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] - |
- ||||||||||||||||||||||||||||||||
| - extremum - | -
-
- string Enum
-
- - Defines the direction of optimization. Options : ['min', 'max'] + Object Store key. |
||||||||||||||||||||||||||||||||
| - criterion + modified |
- OptimizationTarget object
+ string($date-time)
- Optimization statistical target. + Last time it was modified. |
||||||||||||||||||||||||||||||||
| - psr - | -
-
- number
-
- - Probabilistic Sharpe ratio statistic. - |
- ||||||||||||||||||||||||||||||||
| - sharpeRatio - | -
-
- number
-
- - Sharpe ratio statistic. - |
- ||||||||||||||||||||||||||||||||
| - trades - | -
-
- integer
-
- - Number of trades in the best backtest (based on the criterion) of the optimziation. + Date this project was created. |
||||||||||||||||||||||||||||||||
| - cloneId + size |
- integer
+ number
+
- Id of project where this current project was originally cloned. + Object Store file size. |
||||||||||||||||||||||||||||||||
| - outOfSampleDays + md5 |
- integer
+ string
- Number out-of-sample days. + MD5 (hashing algorithm) hash authentication code. |
||||||||||||||||||||||||||||||||
| - outOfSampleMaxEndDate + mime |
- string($date-time)
+ string
- End date of out-of-sample data. + MIME type. |
||||||||||||||||||||||||||||||||
| - parameters + preview |
- OptimizationParameter Array
+ string
- Parameters used in this optimization. + Preview of the Object Store file content. |
||||||||||||||||||||||||||||||||
- OptimizationNodeType
+ UnauthorizedError
- Model - Optimization node types available in QuantConnect Cloud.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - OptimizationParameter + www_authenticate |
- string Enum
+ string
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] - |
-
| - Example - | -
-
-
+ Header
-{
- "OptimizationParameter": "O2-8"
-}
- |
+ The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The key of the object wishes to manipulate
+key = "..."
+
+### Upload Object Store File
+# Send a POST request to the /object/set endpoint to upload a file
+response = post(f'{BASE_URL}/object/set', headers=get_headers(),
+ data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
+ files={"objectData": b"Hello, world!"}) # File content as bytes
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Uploaded Successfully:")
+ print(result)
+
+### Get Object Store Metadata
+# Prepare data payload to get object metadata
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to get metadata for
+}
+# Send a POST request to the /object/properties endpoint to get metadata
+response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the metadata
+if result['success']:
+ print("Object Store Metadata:")
+ print(result)
+
+### Get Object Store File
+# Prepare data payload to retrieve the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "keys": [key] # List of keys to retrieve (single key in this case)
+}
+# Send a POST request to the /object/get endpoint to get the object
+response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the file content
+if result['success']:
+ print("Object Store File Content:")
+ print(result)
+
+### Delete Object Store File
+# Prepare data payload to delete the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to delete
+}
+# Send a POST request to the /object/delete endpoint to delete the object
+response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Deleted Successfully:")
+ print(result)
+
+### List Object Store Files
+# Define an empty path to list all objects (replace with specific path if needed)
+path = ""
+# Prepare data payload to list objects
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "path": path # Path to list objects from
+}
+# Send a POST request to the /object/list endpoint to list objects
+response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Object Store Files:")
+ print(result)
+ + +
+ Get Object Store file of a specific organization and key. +
+ + + +
+ Get Object Store files of a specific organization and key. The
+
+ /object/get
+
+ API accepts requests in the following format:
+
| + Get Object Store files of a specific organization and key. + | +
|---|
+ The
+
+ /object/get
+
+ API provides a response in the following format:
+
- OptimizationTargetTo
+ GetObjectStoreResponse
- Model
+ Model - Response received when fetching an Object Store file.
|
|
|---|---|
| - OptimizationParameter + jobId |
- string Enum
+ string
- /. Options : ['min', 'max'] - |
-
| - Example - | -
-
-
+ Id of the job, which you can use to request a download URL.
-{
- "OptimizationParameter": "min"
-}
- |
-
- OptimizationTarget
-
- Model
- |
- |
|---|---|
| - target + url |
- string Enum
+ string
- The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + The URL to download the object. This can also be null. To download the object, paste the full URL (including the URL parameters) into a browser. |
| - extremum + success |
- string Enum
+ boolean
- Defines the direction of optimization. Options : ['min', 'max'] + Indicate if the API request was successful. |
| - targetValue + errors |
- number
-
- Desired value for the optimization target statistic. + List of errors with the API call. |
- OptimizationTargetStatistic
+ UnauthorizedError
- Model
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - OptimizationParameter + www_authenticate |
- string Enum
+ string
- /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] - |
-
| - Example - | -
-
-
+ Header
-{
- "OptimizationParameter": "TotalPerformance.PortfolioStatistics.SharpeRatio"
-}
- |
+ The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The key of the object wishes to manipulate
+key = "..."
+
+### Upload Object Store File
+# Send a POST request to the /object/set endpoint to upload a file
+response = post(f'{BASE_URL}/object/set', headers=get_headers(),
+ data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
+ files={"objectData": b"Hello, world!"}) # File content as bytes
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Uploaded Successfully:")
+ print(result)
+
+### Get Object Store Metadata
+# Prepare data payload to get object metadata
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to get metadata for
+}
+# Send a POST request to the /object/properties endpoint to get metadata
+response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the metadata
+if result['success']:
+ print("Object Store Metadata:")
+ print(result)
+
+### Get Object Store File
+# Prepare data payload to retrieve the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "keys": [key] # List of keys to retrieve (single key in this case)
+}
+# Send a POST request to the /object/get endpoint to get the object
+response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the file content
+if result['success']:
+ print("Object Store File Content:")
+ print(result)
+
+### Delete Object Store File
+# Prepare data payload to delete the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to delete
+}
+# Send a POST request to the /object/delete endpoint to delete the object
+response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Deleted Successfully:")
+ print(result)
+
+### List Object Store Files
+# Define an empty path to list all objects (replace with specific path if needed)
+path = ""
+# Prepare data payload to list objects
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "path": path # Path to list objects from
+}
+# Send a POST request to the /object/list endpoint to list objects
+response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Object Store Files:")
+ print(result)
+ + +
+ Delete the Object Store file of a specific organization and key. +
+ + + +
+ Delete the Object Store file of a specific organization and key. The
+
+ /object/delete
+
+ API accepts requests in the following format:
+
- OptimizationParameter
+ DeleteObjectStoreRequest
- Model
+ Model - Request to delete an object in the Object Store for a specific organization and key.
|
|
|---|---|
| - name + organizationId |
@@ -84005,21 +91503,21 @@
- Name of optimization parameter. + Id of the organization that owns the Object Store. |
| - min + key |
- number
+ string
- Minimum value of optimization parameter, applicable for boundary conditions. + Key of the Object Store file to delete. |
| - max + Example |
-
- number
-
- - Maximum value of optimization parameter, applicable for boundary conditions. +
+
+{
+ "organizationId": "5cad178b20a1d52567b534553413b691",
+ "key": "key1"
+}
+ |
+ The
+
+ /object/delete
+
+ API provides a response in the following format:
+
+
+ RestResponse
+
+ Model - Base API response class for the QuantConnect API.
+ |
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - step + success |
- number
-
- Movement, should be positive. + Indicate if the API request was successful. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - minStep + errors |
- number
-
- Minimal possible movement for current parameter, should be positive. Used by -
- Strategies.EulerSearchOptimizationStrategy
-
- to determine when this parameter can no longer be optimized.
+ List of errors with the API call.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ReadOptimizationRequest
+ ListObjectStoreRequest
- Model - Request to read an optimization from a project.
+ Model - Request to list the Object Store files under a specific directory in an organization.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - optimizationId + organizationId |
@@ -84396,12 +91828,30 @@
- Id of the optimization to read. + Id of the organization to list the Object Store files from. + |
+ ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + path + | +
+
+ string
+
+ + Path to a directory in the Object Store. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-
- ReadOptimizationResponse
-
- Model - Response received when reading an optimization.
- |
- |
|---|---|
| - optimization - | -
-
- Optimization object
-
- - Response received when reading an optimization job. - |
-
| - success - | -
-
- boolean
-
- - Indicate if the API request was successful. - |
-
| - errors - | -
-
- string Array
-
- - List of errors with the API call. - |
-
| - Example - | -
-
-
-
-{
- "optimization": {
- "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
- "snapshotId": 24013333,
- "projectId": 23456789,
- "name": "string",
- "extremum": "min",
- "status": ,
- "nodeType": "O2-8",
- "parallelNodes": 4,
- "criterion": {
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "extremum": "min",
- "targetValue": 1
- },
- "runtimeStatistics": {
- "Completed": "string",
- "Failed": "string",
- "Running": "string",
- "In Queue": "string",
- "Average Length": "2021-11-26T15:18:27.693Z",
- "Total Runtime": "2021-11-26T15:18:27.693Z",
- "Total": "string",
- "Consumed": "string"
- },
- "constraints": [
- {
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "operator": "LessOrEqual",
- "targetValue": 1
- }
- ],
- "parameters": [
- {
- "name": "rsi_period",
- "min": 10,
- "max": 20,
- "step": 1,
- "minStep": 1
- }
- ],
- "backtests": {
- "name": "string",
- "id": "string",
- "progress": 0,
- "exitCode": 0,
- "statistics": [
- "number"
- ],
- "parameterSet": ,
- "equity": [
- "array"
- ],
- "startDate": "2021-11-26T15:18:27.693Z",
- "endDate": "2021-11-26T15:18:27.693Z",
- "outOfSampleDays": 0,
- "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z"
- },
- "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
- "requested": "2021-11-26T15:18:27.693Z",
- "optimizationTarget": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "targetValue": 1,
- "gridLayout": [
- {
- "chartName": "string",
- "width": 0,
- "height": 0,
- "row": 0,
- "column": 0,
- "sort": 0,
- "definition": [
- "string"
- ]
- }
- ],
- "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
- "outOfSampleDays": 0
- },
- "success": true,
- "errors": [
- "string"
- ]
-}
- |
-
-
- Optimization
-
- Model - Response received when reading an optimization job.
- |
- |||||||
|---|---|---|---|---|---|---|---|
| - optimizationId - | -
-
- string
-
- - Id of the optimization. - |
- ||||||
| - snapshotId - | -
-
- integer
-
- - Snapshot Id of this optimization. - |
- ||||||
+
+ ListObjectStoreResponse
+
+ Model - Response received containing a list of stored objects metadata, as well as the total size of all of them.
+ |
+ |
|---|---|
| - projectId + path |
- integer
-
- Id of the project the optimization belongs to. + Path to the directory in the Object Store. |
| - name + objects |
- string
-
- Name of the optimization. + List of directories and files stored in the directory at the given path. If the path contains directories, this list of objects doesn't contain the children of those directories. |
| - extremum + page |
- string Enum
+ integer
- Defines the direction of optimization. Options : ['min', 'max'] + The current page number in the paginated response. |
| - status + totalPages |
- OptimizationStatus object
-
- Status of the optimization. + The total number of pages in the paginated response. |
| - nodeType + objectStorageUsed |
- string Enum
+ integer
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + Size of all objects stored in bytes. |
| - parallelNodes + objectStorageUsedHuman |
- integer
+ string
- Number of parallel nodes for the optimization. + Size of all the objects stored in human-readable format. |
| - criterion + success |
- OptimizationTarget object
-
- Optimization statistical target. + Indicate if the API request was successful. |
| - runtimeStatistics + errors |
- OptimizationRuntimeStatistics object
+ string Array
- Dictionary representing a runtime banner/updating statistics for the optimization. + List of errors with the API call. |
| - constraints + Example |
-
- OptimizationConstraint Array
-
- - Optimization constraints. +
+
+{
+ "path": "Mia",
+ "objects": [
+ {
+ "key": "Mia/Test",
+ "name": "string",
+ "modified": "2021-11-26T15:18:27.693Z",
+ "mime": "application/json",
+ "folder": true,
+ "size": 13
+ }
+ ],
+ "page": 0,
+ "totalPages": 0,
+ "objectStorageUsed": 0,
+ "objectStorageUsedHuman": "2.27 GB",
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+
+ ObjectStoreSummary
+
+ Model - Summary information of the Object Store.
+ |
+ |
|---|---|
| - parameters + key |
- OptimizationParameter Array
+ string
- Optimization parameters. - |
-
| - backtests - | -
-
- OptimizationBacktest object
-
- - Dictionary of optimization backtests. + Object Store key. |
| - strategy + name |
- string Enum
+ string
- Optimization strategy. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + File or folder name. |
| - requested + modified |
string($date-time)
- Optimization requested date and time. - |
-
| - optimizationTarget - | -
-
- string Enum
-
- - Statistic to be optimized. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + Last time it was modified. |
| - targetValue + mime |
- number
+ string
- Desired value for the optimization target statistic. - |
-
| - gridLayout - | -
-
- GridChart Array
-
- - List with grid charts representing the grid layout. + MIME type. |
| - outOfSampleMaxEndDate + folder |
- string($date-time)
-
- End date of out of sample data. + True if it is a folder, false otherwise. |
| - outOfSampleDays + size |
- integer
+ number
- Number of days of out of sample days. + Object Store file size. |
- OptimizationTargetTo
+ UnauthorizedError
- Model
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+# The key of the object wishes to manipulate
+key = "..."
+
+### Upload Object Store File
+# Send a POST request to the /object/set endpoint to upload a file
+response = post(f'{BASE_URL}/object/set', headers=get_headers(),
+ data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
+ files={"objectData": b"Hello, world!"}) # File content as bytes
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Uploaded Successfully:")
+ print(result)
+
+### Get Object Store Metadata
+# Prepare data payload to get object metadata
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to get metadata for
+}
+# Send a POST request to the /object/properties endpoint to get metadata
+response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the metadata
+if result['success']:
+ print("Object Store Metadata:")
+ print(result)
+
+### Get Object Store File
+# Prepare data payload to retrieve the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "keys": [key] # List of keys to retrieve (single key in this case)
+}
+# Send a POST request to the /object/get endpoint to get the object
+response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the file content
+if result['success']:
+ print("Object Store File Content:")
+ print(result)
+
+### Delete Object Store File
+# Prepare data payload to delete the object
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "key": key # Key of the object to delete
+}
+# Send a POST request to the /object/delete endpoint to delete the object
+response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Object Store File Deleted Successfully:")
+ print(result)
+
+### List Object Store Files
+# Define an empty path to list all objects (replace with specific path if needed)
+path = ""
+# Prepare data payload to list objects
+payload = {
+ "organizationId": ORGANIZATION_ID, # ID of the organization
+ "path": path # Path to list objects from
+}
+# Send a POST request to the /object/list endpoint to list objects
+response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Object Store Files:")
+ print(result)
+ + +
+ Run a backtest for a few seconds to initialize the algorithm and get initialization errors if any. +
+ + + +
+ Run a backtest for a few seconds to initialize the algorithm and get initialization errors if any. The
+
+ /ai/tools/backtest-init
+
+ API accepts requests in the following format:
+
+
+ BasicFilesRequest
+
+ Model - Request to process files.
|
|||||
|---|---|---|---|---|---|
| - GridChart + language + | +
+
+ string Enum
+
+ + Programming language. Options : ['C#', 'Py'] + |
+ ||||
| + files |
- string Enum
+ File Array
+
- /. Options : ['min', 'max'] + Files to process. |
||||
- OptimizationNodeType
+ File
- Model - Optimization node types available in QuantConnect Cloud.
+ Model - File for a AI.
|
|||||
| - GridChart + name |
- string Enum
+ string
+
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] + Name of a file. + |
+ ||||
| + content + | +
+
+ string
+
+ + Contents of the file. |
||||
+ The
+
+ /ai/tools/backtest-init
+
+ API provides a response in the following format:
+
- OptimizationTarget
+ BacktestInitResponse
- Model
+ Model - Response to a backtest initialization request.
|
|
|---|---|
| - target + state |
string Enum
- The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + State of the backtest. Options : ['End', 'Error'] |
| - extremum + version |
- string Enum
+ number
+
- Defines the direction of optimization. Options : ['min', 'max'] + Version of the response. |
| - targetValue + payload |
- number
+ string
+
+ + Information about the backtest initialization. + |
+
| + payloadType + | +
+
+ string
- Desired value for the optimization target statistic. + Type of the payload. |
- OptimizationTargetStatistic
+ UnauthorizedError
- Model
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - GridChart + www_authenticate + | +
+
+ string
+
+ + Header + |
+
+ The following example demonstates initializing a backtest for a specific algorithm through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Initialize Backtest
+# Send a POST request to the /ai/tools/backtest-init endpoint to initialize a backtest
+response = post(f'{BASE_URL}/ai/tools/backtest-init', headers=get_headers(), json={
+ "language": "Python", # Programming language of the algorithm
+ "files": [ # List of files for the backtest
+ {
+ "name": "utils.py", # Name of the file
+ "content": '''
+# region imports
+from AlgorithmImports import *
+# endregion
+
+class Project(QCAlgorithm):
+
+ def Initialize(self):
+ self.AddEquity("SPY", Resolution.Minute)
+''' # Content of the file (Python code)
+ }
+ ]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the backtest initialization result
+if result['success']:
+ print("Backtest Initialized Successfully:")
+ print(result)
+ + +
+ Show the code completion for a specific text input. +
+ + + +
+ Show the code completion for a specific text input. The
+
+ /ai/tools/complete
+
+ API accepts requests in the following format:
+
+
+ CodeCompletionRequest
+
+ Model - Request to show code completion for a specific text input.
+ |
+ |
|---|---|
| + language |
string Enum
+
- /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + Programming language for the code completion. Options : ['C#', 'Py'] + |
+
| + sentence + | +
+
+ string
+
+ + Sentence to complete. + |
+
| + responseSizeLimit + | +
+
+ integer
+
+ + Maximum size of the responses. |
+ The
+
+ /ai/tools/complete
+
+ API provides a response in the following format:
+
- OptimizationRuntimeStatistics
+ CodeCompletionResponse
- Model
+ Model - Response to a code completion request.
|
|
|---|---|
| - Completed + state |
- string
+ string Enum
- Number of completed backtests in the optimization job. + State of the code completion. Options : ['End'] |
| - Failed + version |
- string
+ number
+
- Number of failed backtests in the optimization job. + Version of the response. |
| - Running + payload |
- string
+ string Array
- Number of running backtests in the optimization job. + Code completion suggestions. |
| - In Queue + payloadType |
string
+
- Number of backtests waiting in-queue in the optimization job. + Type of the payload. |
| - Average Length + Example |
-
- string($time)
-
- - The average time of each backtest in the optimization job (HH:MM:SS). +
+
+{
+ "state": "End",
+ "version": 2.0,
+ "payload": [
+ "string"
+ ],
+ "payloadType": "StringArray"
+ ]
+}
+ |
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| - Total Runtime + www_authenticate |
- string($time)
+ string
- The total runtime of the optimization (HH:MM:SS). + Header |
+ The following example demonstates code completion for a specific algorithm attribute through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Code Completion
+# Send a POST request to the /ai/tools/complete endpoint to get code completion
+response = post(f'{BASE_URL}/ai/tools/complete', headers=get_headers(), json={
+ "language": "Python", # Programming language for code completion
+ "sentence": "self.add_equity('AAPL", # Partial code to complete
+ "responseSizeLimit": 30 # Maximum size of the completion response
+})
+# Parse the JSON response
+result = response.json()
+# Check if the request was successful and print the code completion results
+if result['success']:
+ print("Code Completion Results:")
+ print(result)
+ + +
+ Show additional context and suggestions for error messages. +
+ + + +
+ Show additional context and suggestions for error messages. The
+
+ /ai/tools/error-enhance
+
+ API accepts requests in the following format:
+
+
+ ErrorEnhanceRequest
+
+ Model - Request to show additional context and suggestions for error messages.
+ |
+ |||||||
|---|---|---|---|---|---|---|---|
| - Total + language |
- string
+ string Enum
+
- Number of backtests in the optimization job. + Programming language for the code completion. Options : ['C#', 'Py'] |
||||||
| - Consumed + error |
- string
+ Error object
+
- Amount of QuantConnect Credit consumed by the optimization job. + Error information. |
||||||
- OptimizationConstraint
+ Error
- Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ Model - Error information.
|
|||||||
| - target - | -
-
- string Enum
-
- - The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] - |
- ||||||
| - operator + message |
- string Enum
+ string
- The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] + Error message. |
||||||
| - targetValue + stacktrace |
- number
-
- The threshold value for the target constraint. + Stack trace of the error. |
||||||
+ The
+
+ /ai/tools/error-enhance
+
+ API provides a response in the following format:
+
- OptimizationParameter
+ ErrorEnhanceResponse
- Model
+ Model - Response to error enhancement request.
|
|
|---|---|
| - name + state |
@@ -85409,23 +93206,17 @@
- Name of optimization parameter. + State of the code completion. |
| - min + version |
@@ -85433,88 +93224,219 @@
- Minimum value of optimization parameter, applicable for boundary conditions. + Version of the response. |
| - max + payload |
- number
-
- Maximum value of optimization parameter, applicable for boundary conditions. + Error message suggestions. |
| - step + payloadType |
- number
-
- Movement, should be positive. + Type of the payload. |
| - minStep + Example + | +
+
+
+
+{
+ "state": "End",
+ "version": 2.0,
+ "payload": "string",
+ "payloadType": "String"
+}
+ |
+
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| + www_authenticate |
- number
+ string
+
+ + Header + |
+
+ The following example demonstates how to get additional context and suggestions for error messages through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Error Enhancement
+# Send a POST request to the /ai/tools/error-enhance endpoint to enhance error message
+response = post(f'{BASE_URL}/ai/tools/error-enhance/', headers=get_headers(), json={
+ "language": "Python", # Programming language of the code
+ "error": { # Error details
+ "message": ''' at initialize
+ self._option = self.add_index_option("SPX", Resolution.MINUTE, "SPXW").symbol
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ in c1afe80a-e056-4841-b0c1-d9c562cf2bd8.py: line 15
+ The specified market wasn't found in the markets lookup. Requested: spxw. You can add markets by calling QuantConnect.Market.Add(string,int) (Parameter 'market')''', # Error message
+ "stacktrace": "" # Stacktrace (empty in this case)
+ }
+})
+# Parse the JSON response
+result = response.json()
+# Check if the request was successful and print the enhanced error details
+if result['success']:
+ print("Enhanced Error Details:")
+ print(result)
+ + +
+ Update Python code to follow PEP8 style. +
+ + + +
+ Update Python code to follow PEP8 style. The
+
+ /ai/tools/pep8-convert
+
+ API accepts requests in the following format:
+
+
+ PEP8ConvertRequest
+
+ Model - Request to convert Python code to PEP8 style.
+ |
+ ||
|---|---|---|
| + files + | +
+
+ File Array
- Minimal possible movement for current parameter, should be positive. Used by -
- Strategies.EulerSearchOptimizationStrategy
-
- to determine when this parameter can no longer be optimized.
+ Files of the project.
|
|
- OptimizationBacktest
+ File
- Model
+ Model - File for a AI.
|
string
+
- The backtest name. + Name of a file. |
|
| - id + content |
string
- Id of the backtest. + Contents of the file. |
|
| - progress + Example |
-
- number
-
- - Progress of the backtest as a percentage from 0-1 based on the days lapsed from start-finish. +
+
+{
+ "name": "main.py",
+ "content": "string"
+}
+ |
|
+ The
+
+ /ai/tools/pep8-convert
+
+ API provides a response in the following format:
+
+
+ PEP8ConvertResponse
+
+ Model - Response to a PEP8 conversion request.
+ |
+ |
|---|---|
| - exitCode + state |
- integer
+ string
+
- The exit code of this backtest. + State of PEP8 conversion. |
| - statistics + version |
- number Array
+ number
+
- The backtest statistics results. [alpha, annual standard deviation, annual variance, average loss (%), average win (%), beta, compounding annual return (%), drawdown (%), estimated strategy capacity, expectancy, information ratio, loss rate (%), net profit (%), probabilistic sharpe ratio, profit-loss ratio, sharpe ratio, total fees, total orders, tracking error, treynor ratio, win rate (%)]. + Version of the response. |
| - parameterSet + payload |
- ParameterSet object
+ object
+
- Parameters used in the backtest. + A dictionary where the key is the file name and the value is the PEP8 converted code of that file. |
| - equity + payloadType |
- array Array
+ string
+
- The backtest equity chart series. + Type of the payload. |
| - startDate + Example |
-
- string($date-time)
-
- - The backtest start date. +
+
+{
+ "state": "End",
+ "version": 2.0,
+ "payload": {
+ "utils.py": "def add(a,b):\n return a+b\n"
+ },
+ "payloadType": "StringDict"
+}
+ |
+
+ UnauthorizedError
+
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ |
+ |
|---|---|
| - endDate + www_authenticate |
- string($date-time)
+ string
- The backtest end date. + Header |
+ The following example demonstates PEP8 conversion of python codes through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### PEP8 Conversion
+# Send a POST request to the /ai/tools/pep8-convert endpoint to convert code to PEP8 syntax
+response = post(f'{BASE_URL}/ai/tools/pep8-convert', headers=get_headers(), json={
+ "files": [ # List of files to convert
+ {
+ "name": "utils.py", # Name of the file
+ "content": '''
+# region imports
+from AlgorithmImports import *
+# endregion
+
+class Project(QCAlgorithm):
+
+ def Initialize(self):
+ self.AddEquity("SPY", Resolution.Minute)
+''' # Content of the file (Python code)
+ }
+ ]
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the PEP8 conversion results
+if result['success']:
+ print("PEP8 Conversion Results:")
+ print(result)
+ + +
+ Check the syntax of a code. +
+ + + +
+ Check the syntax of a code. The
+
+ /ai/tools/syntax-check
+
+ API accepts requests in the following format:
+
+
+ BasicFilesRequest
+
+ Model - Request to process files.
+ |
+ |||||
|---|---|---|---|---|---|
| - outOfSampleDays + language |
- integer
+ string Enum
+
- The backtest out-of-sample day count. + Programming language. Options : ['C#', 'Py'] |
||||
| - outOfSampleMaxEndDate + files |
- string($date-time)
+ File Array
+
- End date of out-of-sample data. + Files to process. |
||||
- OptimizationStrategy
+ File
- Model
+ Model - File for a AI.
|
|||||
| - value + name |
- string Enum
+ string
+
- /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + Name of a file. + |
+ ||||
| + content + | +
+
+ string
+
+ + Contents of the file. |
||||
+ The
+
+ /ai/tools/syntax-check
+
+ API provides a response in the following format:
+
- GridChart
+ SyntaxCheckResponse
- Model - The chart display properties.
+ Model - Response to a syntax check request.
|
|
|---|---|
| - chartName - | -
-
- string
-
- - The chart name. - |
-
| - width + state |
- integer
-
- Width of the chart. + State of the syntax check. Options : ['End', 'Error'] |
| - height + version |
- integer
+ number
- Height of the chart. + Version of the response. |
| - row + payload |
- integer
-
- Number of rows of the chart. + Code completion suggestions. |
| - column + payloadType |
- integer
+ string
- Number of columns of the chart. - |
-
| - sort - | -
-
- integer
-
- - Sort of the chart. - |
-
| - definition - | -
-
- string Array
-
- - The chart definition labels. + Type of the payload. |
- UpdateOptimizationRequest
+ SearchRequest
+
+ Model - Request to search content in QuantConnect.
+ |
+ |
| + language + | +
+
+ string Enum
+
+ + Programming language of the content to search. Options : ['C#', 'Py'] + |
+
| + criteria + | +
+
+ SearchCriteria Array
+
+ + Criteria for the search. + |
+
| + Example + | +
+
+
+
+{
+ "language": "Py",
+ "criteria": [
+ {
+ "input": "option",
+ "type": "Stubs",
+ "count": 1
+ }
+ ]
+}
+ |
+
+
+ SearchCriteria
- Model - Update the name of an optimization.
+ Model - Search criteria.
|
|||||||
|---|---|---|---|---|---|---|---|
| - optimizationId + input |
@@ -86161,36 +94232,54 @@
- Id of the optimization to update. + Input for the search. |
||||||
| - name + type |
- string
+ string Enum
+ + Type of the search criteria. Options : ['Stubs', 'Forum', 'Docs', 'Examples'] + |
+ ||||||
| + count + | +
+
+ integer
- Name to assign to the optimization. + Number of results to return. |
||||||
- RestResponse
+ SearchResponse
- Model - Base API response class for the QuantConnect API.
+ Model - Response to a search request.
|
|||||||
| - success + state |
- boolean
+ string Enum
- Indicate if the API request was successful. + State of the search. Options : ['End', 'Error'] |
||||||
| - errors + version |
- string Array
+ number
+
- List of errors with the API call. + Version of the response. |
||||||
| - Example + retrivals |
-
-
+
-{
- "success": true,
- "errors": [
- "string"
- ]
-}
-
+ SearchRetrieval Array
+
+ + List of search results. |
||||||
-
- UnauthorizedError
-
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
- |
- |
|---|---|
| - www_authenticate + messageId |
- string
+ integer
+
- Header + Id of the message. |
- The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. -
-from base64 import b64encode
-from hashlib import sha256
-from time import time
-from requests import get, post
-BASE_URL = 'https://www.quantconnect.com/api/v2/'
-
-# You need to replace these with your actual credentials.
-# You can request your credentials at https://www.quantconnect.com/settings/
-# You can find our organization ID at https://www.quantconnect.com/organization/
-USER_ID = 0
-API_TOKEN = '____'
-ORGANIZATION_ID = '____'
-
-def get_headers():
- # Get timestamp
- timestamp = f'{int(time())}'
- time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
-
- # Get hased API token
- hashed_token = sha256(time_stamped_token).hexdigest()
- authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
- authentication = b64encode(authentication).decode('ascii')
-
- # Create headers dictionary.
- return {
- 'Authorization': f'Basic {authentication}',
- 'Timestamp': timestamp
+
+
+ Example
+
+
+
+
+{
+ "state": "End",
+ "version": 2.0,
+ "retrivals": [
+ {
+ "url": "[Index Options - QuantConnect.com](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/index-options)",
+ "score": 0.320344448,
+ "content": "string",
+ "type": 2
}
-
-# Authenticate to verify credentials
-response = post(f'{BASE_URL}/authenticate', headers = get_headers())
-print(response.json())
-
-# --------------------
-
-
-# The project ID of the project to manage an optimization job
-project_id = 12345678
-
-### Estimate Optimization Cost
-# Send a POST request to the /optimizations/estimate endpoint to estimate cost
-response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={
- "projectId": project_id, # ID of the project
- "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix)
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric
- "targetTo": "max", # Direction to optimize (maximize)
- "targetValue": None, # Specific target value (None for max/min)
- "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy
- "compileId": compile_id, # Compilation ID for the optimization
- "parameters[0][key]": "ema_fast", # First parameter key
- "parameters[0][min]": 100, # Minimum value for first parameter
- "parameters[0][max]": 200, # Maximum value for first parameter
- "parameters[0][step]": 50, # Step size for first parameter
- "parameters[1][key]": "ema_slow", # Second parameter key
- "parameters[1][min]": 200, # Minimum value for second parameter
- "parameters[1][max]": 300, # Maximum value for second parameter
- "parameters[1][step]": 50, # Step size for second parameter
- "constraints": [{ # Constraints for the optimization
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "operator": "greater",
- "target-value": 1
- }]
-})
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the estimated cost
-if result['success']:
- print("Optimization Cost Estimated Successfully:")
- print(result)
-
-### Create Optimization
-# Send a POST request to the /optimizations/create endpoint to create an optimization
-response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={
- "projectId": project_id, # ID of the project
- "name": f"Optimization_{compileId[:5]}", # Name of the optimization
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target
- "targetTo": "max", # Direction to optimize
- "targetValue": None, # Specific target value
- "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy
- "compileId": compile_id, # Compilation ID
- "parameters[0][key]": "ema_fast", # First parameter key
- "parameters[0][min]": 100, # Minimum value
- "parameters[0][max]": 200, # Maximum value
- "parameters[0][step]": 50, # Step size
- "parameters[1][key]": "ema_slow", # Second parameter key
- "parameters[1][min]": 200, # Minimum value
- "parameters[1][max]": 300, # Maximum value
- "parameters[1][step]": 50, # Step size
- "constraints": [{ # Constraints
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "operator": "greater",
- "target-value": 1
- }],
- "estimatedCost": 10, # Estimated cost of optimization
- "nodeType": "O2-8", # Node type for optimization
- "parallelNodes": 4 # Number of parallel nodes
-})
-# Parse the JSON response into python managable dict
-result = response.json()
-# Extract the optimization ID from the response
-optimization_id = result['optimizations'][0]['optimizationId']
-# Check if the request was successful and print the result
-if result['success']:
- print("Optimization Created Successfully:")
- print(result)
-
-### Update Optimization
-# Send a POST request to the /optimizations/update endpoint to update the optimization
-response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={
- "optimizationId": optimization_id, # ID of the optimization to update
- "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization
-})
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Optimization Updated Successfully:")
- print(result)
-
-### Read Optimization
-# Prepare data payload to read optimization details
-payload = {
- "optimizationId": optimization_id # ID of the optimization to read
-}
-# Send a POST request to the /optimizations/read endpoint to get details
-response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the details
-if result['success']:
- print("Optimization Details:")
- print(result)
-
-### Abort Optimization
-# Prepare data payload to abort the optimization
-payload = {
- "optimizationId": optimization_id # ID of the optimization to abort
-}
-# Send a POST request to the /optimizations/abort endpoint to abort
-response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Optimization Aborted Successfully:")
- print(result)
-
-### Delete Optimization
-# Prepare data payload to delete the optimization
-payload = {
- "optimizationId": optimization_id # ID of the optimization to delete
-}
-# Send a POST request to the /optimizations/delete endpoint to delete
-response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Optimization Deleted Successfully:")
- print(result)
-
-### List Optimizations
-# Prepare data payload to list optimizations
-payload = {
- "projectId": project_id # ID of the project
-}
-# Send a POST request to the /optimizations/list endpoint to list optimizations
-response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the list
-if result['success']:
- print("List of Optimizations:")
- print(result)
-
-
-
-
-
-
-
-
- Optimization Management
- Delete Optimization
-
-
-Introduction
-
-
-
-
- Delete an optimization.
-
-
-
-
-Request
-
-
-
-
- The
-
- /optimizations/delete
-
- API accepts requests in the following format:
-
+ ],
+ "messageId": 0
+}
+
+
+
+
- DeleteOptimizationRequest
+ SearchRetrieval
- Model - Delete an optimization.
+ Model - Search criteria.
|
|
|---|---|
| - optimizationId + url |
@@ -86542,84 +94431,60 @@
- Id of the optimization to delete. + Input for the search. |
| - Example + score |
-
-
+
-{
- "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd"
-}
-
+ number
+
+ + Relevance score of the search result. |
- The
-
- /optimizations/delete
-
- API provides a response in the following format:
-
-
- RestResponse
-
- Model - Base API response class for the QuantConnect API.
- |
- |||||||||
|---|---|---|---|---|---|---|---|---|---|
| - success + content |
- boolean
+ string
- Indicate if the API request was successful. + Content of the search result. |
||||||||
| - errors + type |
- string Array
+ number
+
- List of errors with the API call. + Type of the search result. 0=Stubs, 1=Forum, 2=Docs, 3=Examples. |
||||||||
- AbortOptimizationRequest
+ BacktestReportRequest
- Model - Abort an optimization.
+ Model - Request to read out the report of a backtest.
|
|||||||||
| - optimizationId + projectId + | +
+
+ integer
+
+ + Id of the project to read. + |
+ ||||||||
| + backtestId |
@@ -86910,12 +94712,12 @@
- Id of the optimization to abort. + Id of the backtest to read. |
||||||||
- RestResponse
+ BacktestReportGeneratingResponse
- Model - Base API response class for the QuantConnect API.
+ Model - Backtest Report Response wrapper.
+ |
+ |||||||||
| + generating + | +
+
+ boolean
+
+ + Indicate if the report is generating. + |
+ ||||||||
| + success + | +
+
+ boolean
+
+ + Indicate if the API request was successful. + |
+ ||||||||
| + errors + | +
+
+ string Array
+
+ + List of errors with the API call. + |
+ ||||||||
| + Example + | +
+
+
+
+{
+ "generating": true,
+ "success": true,
+ "errors": [
+ "string"
+ ]
+}
+ |
+ ||||||||
+
+ BacktestReport
+
+ Model - Backtest Report Response wrapper.
|
||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| + report + | +
+
+ string
+
+ + HTML data of the report with embedded base64 images. + |
+ |||||||||||||||||||||||||||||||||||||||||||||||
success
@@ -86992,6 +94872,7 @@
{
+ "report": "string",
"success": true,
"errors": [
"string"
@@ -87035,7 +94916,7 @@
Responses
The
|
- ListOptimizationResponse
+ AccountResponse
- Model - Response received when creating an optimization or listing optimizations of a project.
+ Model - Account information for an organization.
- optimizations
+ organizationId
|
|
- CreateOptimizationResponse Array
+ string
+
- Collection of summarized optimization objects. + The organization Id.
- success
+ creditBalance
|
|
- boolean
+ number
- Indicate if the API request was successful. + The current account balance.
- errors
+ card
|
|
- string Array
+ Card object
- List of errors with the API call. + Credit card information. | |||||||||||||||||||||||||||||||||||||||||
{
- "optimizations": [
- {
- "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
- "projectId": 23456789,
- "name": "string",
- "status": ,
- "nodeType": "O2-8",
- "extremum": "min",
- "criterion": {
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "extremum": "min",
- "targetValue": 1
- },
- "created": "2021-11-26T15:18:27.693Z",
- "psr": 0,
- "sharpeRatio": 0,
- "trades": 0,
- "cloneId": 0,
- "outOfSampleDays": 0,
- "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
- "parameters": [
- {
- "name": "rsi_period",
- "min": 10,
- "max": 20,
- "step": 1,
- "minStep": 1
- }
- ]
- }
- ],
- "success": true,
- "errors": [
- "string"
- ]
+ "organizationId": "5cad178b20a1d52567b534553413b691",
+ "creditBalance": 0,
+ "card": {
+ "brand": "string",
+ "expiration": "12/27",
+ "last4": "string"
+ }
}
- CreateOptimizationResponse
+ Card
- Model - Response received when launching an optimization job or listing all the optimization jobs of a project.
+ Model - Credit card information.
string
-
-
-
- example: O-401d3d40b5a0e9f8c46c954a303f3ddd
-
-
- integer
+ string
- example: 23456789
+ example: 12/27
string
- OptimizationStatus object
-
-
- string Enum
-
-
- string Enum
-
-
- OptimizationTarget object
-
-
- string($date-time)
-
-
- number
-
-
- number
-
-
- integer
-
-
- integer
-
-
- integer
-
-
- string($date-time)
-
-
- OptimizationParameter Array
-
-
{
- "optimizationId": "O-401d3d40b5a0e9f8c46c954a303f3ddd",
- "projectId": 23456789,
- "name": "string",
- "status": ,
- "nodeType": "O2-8",
- "extremum": "min",
- "criterion": {
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "extremum": "min",
- "targetValue": 1
- },
- "created": "2021-11-26T15:18:27.693Z",
- "psr": 0,
- "sharpeRatio": 0,
- "trades": 0,
- "cloneId": 0,
- "outOfSampleDays": 0,
- "outOfSampleMaxEndDate": "2021-11-26T15:18:27.693Z",
- "parameters": [
- {
- "name": "rsi_period",
- "min": 10,
- "max": 20,
- "step": 1,
- "minStep": 1
- }
- ]
+ "brand": "string",
+ "expiration": "12/27",
+ "last4": "string"
}
- OptimizationNodeType
+ UnauthorizedError
- Model - Optimization node types available in QuantConnect Cloud.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - OptimizationParameter + www_authenticate |
- string Enum
+ string
- Optimization node types available in QuantConnect Cloud. Options : ['O2-8', 'O4-12', 'O8-16'] - |
-
| - Example - | -
-
-
+ Header
-{
- "OptimizationParameter": "O2-8"
-}
- |
+ The following example demonstates reading the organization account status through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### Read Account Status
+# Send a POST request to the /account/read endpoint to read account status
+response = post(f'{BASE_URL}/account/read', headers=get_headers())
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the account status
+if result['success']:
+ print("Account Status:")
+ print(result)
+ + +
+ Returns a list of lean versions with basic information for each version. +
+ + + +
+ The
+
+ /lean/versions/read
+
+ API accepts requests in the following format:
+
| + |
- OptimizationTargetTo
+ /lean/versions/read
- Model
+ Method
|
|
|---|---|---|
| - OptimizationParameter - | -
-
- string Enum
-
- - /. Options : ['min', 'max'] - |
- |
| - Example - | -
-
-
-
-{
- "OptimizationParameter": "min"
-}
- |
-
+
+ /lean/versions/read
+
+ method takes no parameters.
+ |
+ The
+
+ /lean/versions/read
+
+ API provides a response in the following format:
+
- OptimizationTarget
+ LeanVersionsResponse
- Model
+ Model - Contains the LEAN versions with their basic descriptions.
|
|||||
|---|---|---|---|---|---|
| - target + versions |
- string Enum
+ LeanVersion Array
- The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + List of LEAN versions with their basic descriptions. |
||||
| - extremum + success |
- string Enum
+ boolean
- Defines the direction of optimization. Options : ['min', 'max'] + Indicate if the API request was successful. |
||||
| - targetValue + errors |
- number
-
- Desired value for the optimization target statistic. + List of errors with the API call. |
||||
- OptimizationTargetStatistic
+ LeanVersion
Model
|
@@ -87805,157 +95491,98 @@ |||||
| - OptimizationParameter + id |
- string Enum
+ integer
- /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + Id of the LEAN version. |
||||
| - Example + created |
-
-
-
-{
- "OptimizationParameter": "TotalPerformance.PortfolioStatistics.SharpeRatio"
-}
- |
- ||||
-
- OptimizationParameter
-
- Model
- |
- |
|---|---|
| - name + description |
string
-
- Name of optimization parameter. + Description of the LEAN version. |
| - min + leanHash |
- number
-
- Minimum value of optimization parameter, applicable for boundary conditions. + Commit Hash in the LEAN repository. |
| - max + leanCloudHash |
- number
-
- Maximum value of optimization parameter, applicable for boundary conditions. + Commit Hash in the LEAN Cloud repository. |
| - step + name |
- number
-
- Movement, should be positive. + Name of the branch where the commit is. |
| - minStep + ref |
- number
-
- Minimal possible movement for current parameter, should be positive. Used by + Reference to the branch where the commit is. + |
+
| + public + | +
- Strategies.EulerSearchOptimizationStrategy
+ boolean
- to determine when this parameter can no longer be optimized.
+ + Indicates if the version is available for the public. |
-
- UnauthorizedError
-
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
- |
- |
|---|---|
| - www_authenticate - | -
-
- string
-
- - Header - |
-
- The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. + The following example demonstates getting a list of Lean versions through the cloud API.
from base64 import b64encode @@ -88049,154 +95652,39 @@Examples
# -------------------- -# The project ID of the project to manage an optimization job -project_id = 12345678 - -### Estimate Optimization Cost -# Send a POST request to the /optimizations/estimate endpoint to estimate cost -response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={ - "projectId": project_id, # ID of the project - "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix) - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric - "targetTo": "max", # Direction to optimize (maximize) - "targetValue": None, # Specific target value (None for max/min) - "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy - "compileId": compile_id, # Compilation ID for the optimization - "parameters[0][key]": "ema_fast", # First parameter key - "parameters[0][min]": 100, # Minimum value for first parameter - "parameters[0][max]": 200, # Maximum value for first parameter - "parameters[0][step]": 50, # Step size for first parameter - "parameters[1][key]": "ema_slow", # Second parameter key - "parameters[1][min]": 200, # Minimum value for second parameter - "parameters[1][max]": 300, # Maximum value for second parameter - "parameters[1][step]": 50, # Step size for second parameter - "constraints": [{ # Constraints for the optimization - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", - "operator": "greater", - "target-value": 1 - }] -}) -# Parse the JSON response into python managable dict -result = response.json() -# Check if the request was successful and print the estimated cost -if result['success']: - print("Optimization Cost Estimated Successfully:") - print(result) - -### Create Optimization -# Send a POST request to the /optimizations/create endpoint to create an optimization -response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={ - "projectId": project_id, # ID of the project - "name": f"Optimization_{compileId[:5]}", # Name of the optimization - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target - "targetTo": "max", # Direction to optimize - "targetValue": None, # Specific target value - "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy - "compileId": compile_id, # Compilation ID - "parameters[0][key]": "ema_fast", # First parameter key - "parameters[0][min]": 100, # Minimum value - "parameters[0][max]": 200, # Maximum value - "parameters[0][step]": 50, # Step size - "parameters[1][key]": "ema_slow", # Second parameter key - "parameters[1][min]": 200, # Minimum value - "parameters[1][max]": 300, # Maximum value - "parameters[1][step]": 50, # Step size - "constraints": [{ # Constraints - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", - "operator": "greater", - "target-value": 1 - }], - "estimatedCost": 10, # Estimated cost of optimization - "nodeType": "O2-8", # Node type for optimization - "parallelNodes": 4 # Number of parallel nodes -}) -# Parse the JSON response into python managable dict -result = response.json() -# Extract the optimization ID from the response -optimization_id = result['optimizations'][0]['optimizationId'] -# Check if the request was successful and print the result -if result['success']: - print("Optimization Created Successfully:") - print(result) - -### Update Optimization -# Send a POST request to the /optimizations/update endpoint to update the optimization -response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={ - "optimizationId": optimization_id, # ID of the optimization to update - "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization -}) -# Parse the JSON response into python managable dict -result = response.json() -# Check if the request was successful and print the result -if result['success']: - print("Optimization Updated Successfully:") - print(result) - -### Read Optimization -# Prepare data payload to read optimization details -payload = { - "optimizationId": optimization_id # ID of the optimization to read -} -# Send a POST request to the /optimizations/read endpoint to get details -response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload) -# Parse the JSON response into python managable dict -result = response.json() -# Check if the request was successful and print the details -if result['success']: - print("Optimization Details:") - print(result) - -### Abort Optimization -# Prepare data payload to abort the optimization -payload = { - "optimizationId": optimization_id # ID of the optimization to abort -} -# Send a POST request to the /optimizations/abort endpoint to abort -response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload) -# Parse the JSON response into python managable dict -result = response.json() -# Check if the request was successful and print the result -if result['success']: - print("Optimization Aborted Successfully:") - print(result) - -### Delete Optimization -# Prepare data payload to delete the optimization -payload = { - "optimizationId": optimization_id # ID of the optimization to delete -} -# Send a POST request to the /optimizations/delete endpoint to delete -response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload) -# Parse the JSON response into python managable dict -result = response.json() -# Check if the request was successful and print the result -if result['success']: - print("Optimization Deleted Successfully:") - print(result) - -### List Optimizations -# Prepare data payload to list optimizations -payload = { - "projectId": project_id # ID of the project -} -# Send a POST request to the /optimizations/list endpoint to list optimizations -response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload) +### Get Lean Versions +# Send a POST request to the /lean/versions/read endpoint to get Lean versions +response = post(f'{BASE_URL}/lean/versions/read', headers=get_headers()) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the list +# Check if the request was successful and print the versions if result['success']: - print("List of Optimizations:") + print("Lean Versions:") print(result)
- +
- Estimate the execution time of an optimization with the specified parameters. + Create a new agent.
@@ -88214,9 +95702,9 @@
- Project, compile, and optimization parameters for estimating the execution time of an optimization job. The
+ Definition of the agent to create. The
- /optimizations/estimate
+ /agents/create
API accepts requests in the following format:
- EstimateOptimizationRequest
+ CreateAgentRequest
- Model - Request to estimate the cost of an optimization job.
+ Model - Request body for creating an agent.
- integer
+ string
@@ -88247,12 +95735,12 @@ Request
- example: 23456789
+ example: 3b137fed57f2326cc68e746f4eb99639
- string Enum
+ string
- string Enum
+ string
- number
-
-
-
- example: 1
-
-
+ string
string Enum
+ integer
+
+
@@ -88343,101 +95837,150 @@ Request
- example: 5d1f2cba3a0ec7407c566614300502b5-173e0419674daf4144ce7c9931155ca8
+ example: auto
- OptimizationParameter Array
+ string Array
+
+
+ boolean
+
+
+ string
- required
+ example: claude-opus-4-7
- OptimizationConstraint Array
+ AgentChainedEntry Array
-{
- "projectId": 23456789,
- "name": "Mia First Optimization Job",
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "targetTo": "min",
- "targetValue": 1,
- "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy",
- "compileId": "5d1f2cba3a0ec7407c566614300502b5-173e0419674daf4144ce7c9931155ca8",
- "parameters": [
- {
- "name": "rsi_period",
- "min": 10,
- "max": 20,
- "step": 1,
- "minStep": 1
- }
- ],
- "constraints": [
- {
- "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
- "operator": "LessOrEqual",
- "targetValue": 1
- }
- ]
-}
-
+ AgentSubAgentEntry Array
+
+
-
- OptimizationTargetStatistic
-
- Model
- |
- |
|---|---|
| - OptimizationConstraint + token |
- string Enum
+ AgentToken object
- /. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + User-supplied LLM provider credentials attached to an agent. + |
+
| + useQCC + | +
+
+ boolean
+
+ + Whether to run the agent on the QuantConnect Cloud LLM provider. When false, supply a token. + |
+
| + pipeline + | +
+
+ string
+
+ + Pipeline to assign to the agent. + |
+
| + author + | +
+
+ AgentTaskOwner object
+
+ + Owner of an agent task. + |
+
| + organization + | +
+
+ AgentOrganization object
+
+ + Organization summary embedded on an agent. + |
+
| + node + | +
+
+ AgentNode object
+
+ + Compute node bound to an agent. |
- OptimizationTargetTo
+ AgentChainedEntry
- Model
+ Model - One entry in an agent's chain of follow-up agents.
|
|
| - OptimizationConstraint + agentId |
- string Enum
+ integer
+
- /. Options : ['min', 'max'] + Identifier of the chained agent. |
| - Example + step |
-
-
+
-{
- "OptimizationConstraint": "min"
-}
-
+ integer
+
+ + Ordinal position of the agent in the chain. |
-
- OptimizationStrategy
-
- Model
- |
- |
|---|---|
| - OptimizationConstraint + agent |
- string Enum
+ object
- /. Options : ['QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy'] + Embedded agent definition, populated when the chain entry is expanded. |
- OptimizationParameter
+ AgentSubAgentEntry
- Model
+ Model - One sub-agent reference attached to an agent.
|
|
| - name + agentId |
- string
+ integer
- Name of optimization parameter. + Identifier of the sub-agent. |
| - min + callableCount |
- number
-
- Minimum value of optimization parameter, applicable for boundary conditions. + Maximum number of times this sub-agent can be invoked per deployment. |
| - max + Example |
-
- number
-
- - Maximum value of optimization parameter, applicable for boundary conditions. +
+
+{
+ "agentId": 105,
+ "callableCount": 1
+}
+ |
+
+ AgentToken
+
+ Model - User-supplied LLM provider credentials attached to an agent.
+ |
+ |
|---|---|
| - step + llmApiTokenUser |
- number
-
- Movement, should be positive. + API token supplied by the user for the chosen LLM provider. |
| - minStep + llmProviderApi |
- number
+ string
- Minimal possible movement for current parameter, should be positive. Used by -
- Strategies.EulerSearchOptimizationStrategy
-
- to determine when this parameter can no longer be optimized.
+ Identifier of the LLM provider the token is for.
|
- OptimizationConstraint
+ AgentTaskOwner
- Model - Backtests in the optimization job that don't respect this constraint are excluded from the optimization result.
+ Model - Owner of an agent task.
|
|
| - target + publicId |
- string Enum
+ string
+
- The target statistic to track. Options : ['TotalPerformance.PortfolioStatistics.SharpeRatio', 'TotalPerformance.PortfolioStatistics.CompoundingAnnualReturn', 'TotalPerformance.PortfolioStatistics.ProbabilisticSharpeRatio', 'TotalPerformance.PortfolioStatistics.Drawdown'] + Public profile slug of the user. |
| - operator + name |
- string Enum
+ string
- The target comparison operation. Options : ['LessOrEqual', 'Less', 'GreaterOrEqual', 'Greater', 'NotEqual', 'Equals'] + Display name of the user. |
| - targetValue + image |
- number
-
- The threshold value for the target constraint. + Filename of the user's profile image. |
- The
-
- /optimizations/estimate
-
- API provides a response in the following format:
-
- EstimateOptimizationResponse
+ AgentOrganization
- Model - Response received when estimating the cost of an optimization.
+ Model - Organization summary embedded on an agent.
|
|||||||
|---|---|---|---|---|---|---|---|
| - estimate + id |
- Estimate object
+ string
+
- Response received when estimating the time to run an optimization job. + Identifier of the organization. |
||||||
| - success + name |
- boolean
+ string
+
- Indicate if the API request was successful. + Display name of the organization. |
||||||
| - errors + profile |
- string Array
+ string
+
- List of errors with the API call. + Filename of the organization's profile image. |
||||||
- Estimate
+ AgentNode
- Model - Response received when estimating the time to run an optimization job.
+ Model - Compute node bound to an agent.
|
|||||||
| - estimateId - | -
-
- string
-
- - Estimate Id. - |
- ||||||
| - time + id |
@@ -88875,30 +96442,30 @@
- Estimated time in seconds to run the optimization job. + Identifier of the compute node assigned to the agent, or 0 when not pinned. |
||||||
| - balance + sku |
- integer
+ string
- The organization's QCC balance. + SKU of the compute node assigned to the agent. |
||||||
+ The
+
+ /agents/create
+
+ API provides a response in the following format:
+
- The following example demonstates creating, reading, updating, deleting, aborting and listing backtests of a project through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -88990,161 +96573,254 @@Examples
# -------------------- -# The project ID of the project to manage an optimization job -project_id = 12345678 - -### Estimate Optimization Cost -# Send a POST request to the /optimizations/estimate endpoint to estimate cost -response = post(f'{BASE_URL}/optimizations/estimate', headers=get_headers(), json={ - "projectId": project_id, # ID of the project - "name": f"Optimization_{compileId[:5]}", # Name of the optimization (using compile ID prefix) - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target metric - "targetTo": "max", # Direction to optimize (maximize) - "targetValue": None, # Specific target value (None for max/min) - "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Optimization strategy - "compileId": compile_id, # Compilation ID for the optimization - "parameters[0][key]": "ema_fast", # First parameter key - "parameters[0][min]": 100, # Minimum value for first parameter - "parameters[0][max]": 200, # Maximum value for first parameter - "parameters[0][step]": 50, # Step size for first parameter - "parameters[1][key]": "ema_slow", # Second parameter key - "parameters[1][min]": 200, # Minimum value for second parameter - "parameters[1][max]": 300, # Maximum value for second parameter - "parameters[1][step]": 50, # Step size for second parameter - "constraints": [{ # Constraints for the optimization - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", - "operator": "greater", - "target-value": 1 - }] +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list }) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the estimated cost +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list if result['success']: - print("Optimization Cost Estimated Successfully:") + print("List of Agents:") print(result) -### Create Optimization -# Send a POST request to the /optimizations/create endpoint to create an optimization -response = post(f'{BASE_URL}/optimizations/create', headers=get_headers(), json={ - "projectId": project_id, # ID of the project - "name": f"Optimization_{compileId[:5]}", # Name of the optimization - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", # Optimization target - "targetTo": "max", # Direction to optimize - "targetValue": None, # Specific target value - "strategy": "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy", # Strategy - "compileId": compile_id, # Compilation ID - "parameters[0][key]": "ema_fast", # First parameter key - "parameters[0][min]": 100, # Minimum value - "parameters[0][max]": 200, # Maximum value - "parameters[0][step]": 50, # Step size - "parameters[1][key]": "ema_slow", # Second parameter key - "parameters[1][min]": 200, # Minimum value - "parameters[1][max]": 300, # Maximum value - "parameters[1][step]": 50, # Step size - "constraints": [{ # Constraints - "target": "TotalPerformance.PortfolioStatistics.SharpeRatio", - "operator": "greater", - "target-value": 1 - }], - "estimatedCost": 10, # Estimated cost of optimization - "nodeType": "O2-8", # Node type for optimization - "parallelNodes": 4 # Number of parallel nodes +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read }) # Parse the JSON response into python managable dict result = response.json() -# Extract the optimization ID from the response -optimization_id = result['optimizations'][0]['optimizationId'] -# Check if the request was successful and print the result +# Check if the request was successful and print the agent's model if result['success']: - print("Optimization Created Successfully:") + print(f"Agent model: {result['agent']['model']}") print(result) -### Update Optimization -# Send a POST request to the /optimizations/update endpoint to update the optimization -response = post(f'{BASE_URL}/optimizations/update', headers=get_headers(), json={ - "optimizationId": optimization_id, # ID of the optimization to update - "name": f"Optimization_{optimizationId[:5]}" # New name for the optimization +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment }) # Parse the JSON response into python managable dict result = response.json() +# Extract the task ID from the response +task_id = result['task']['id'] # Check if the request was successful and print the result if result['success']: - print("Optimization Updated Successfully:") + print("Task Created Successfully:") print(result) -### Read Optimization -# Prepare data payload to read optimization details -payload = { - "optimizationId": optimization_id # ID of the optimization to read -} -# Send a POST request to the /optimizations/read endpoint to get details -response = post(f'{BASE_URL}/optimizations/read', headers=get_headers(), json=payload) +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the task name from the response +task_name = result['task']['name'] # Check if the request was successful and print the details if result['success']: - print("Optimization Details:") + print("Task Details:") print(result) -### Abort Optimization -# Prepare data payload to abort the optimization -payload = { - "optimizationId": optimization_id # ID of the optimization to abort -} -# Send a POST request to the /optimizations/abort endpoint to abort -response = post(f'{BASE_URL}/optimizations/abort', headers=get_headers(), json=payload) +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the result if result['success']: - print("Optimization Aborted Successfully:") + print("Task Updated Successfully:") print(result) -### Delete Optimization -# Prepare data payload to delete the optimization -payload = { - "optimizationId": optimization_id # ID of the optimization to delete -} -# Send a POST request to the /optimizations/delete endpoint to delete -response = post(f'{BASE_URL}/optimizations/delete', headers=get_headers(), json=payload) +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] # Check if the request was successful and print the result if result['success']: - print("Optimization Deleted Successfully:") + print("Deployment Created Successfully:") print(result) -### List Optimizations -# Prepare data payload to list optimizations -payload = { - "projectId": project_id # ID of the project -} -# Send a POST request to the /optimizations/list endpoint to list optimizations -response = post(f'{BASE_URL}/optimizations/list', headers=get_headers(), json=payload) +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the list if result['success']: - print("List of Optimizations:") + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- -
- Upload files to the Object Store. + Read an agent by Id.
@@ -89162,162 +96838,39 @@
- Upload files to the Object Store. The
-
- /object/set
-
- API accepts requests in the following format:
-
- The
-
- /object/set
-
- API requires a file request in the following format:
-
-
- ObjectStoreBinaryFile
-
- Model - Represents a binary file we we'd like to upload the file to upload to the Object Store.
- |
- |
|---|---|
| - organizationId - | -
-
- string
-
- - Orgainization ID. - |
-
| - key - | -
-
- string
-
- - Unique key to access the object in Object Store. - |
-
| - objectData - | -
-
- binary
-
- - Object data to be stored. - |
-
| - Example - | -
-
-
-
-{
- "organizationId": "5cad178b20a1d52567b534553413b691",
- "key": "key1",
- "objectData": b"Hello, world!"
-}
- |
-
- The
+ Id of the agent to read. The
- /object/set
+ /agents/read
- API provides a response in the following format:
+ API accepts requests in the following format:
- RestResponse
+ ReadAgentRequest
- Model - Base API response class for the QuantConnect API.
+ Model - Request body for reading an agent.
|
|
|---|---|
| - success - | -
-
- boolean
-
- - Indicate if the API request was successful. - |
-
| - errors + agentId |
- string Array
+ integer
+
- List of errors with the API call. + Identifier of the agent to read. |
+ The
+
+ /agents/read
+
+ API provides a response in the following format:
+
- The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -89410,92 +96977,254 @@Examples
# -------------------- -# The key of the object wishes to manipulate -key = "..." +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list +if result['success']: + print("List of Agents:") + print(result) -### Upload Object Store File -# Send a POST request to the /object/set endpoint to upload a file -response = post(f'{BASE_URL}/object/set', headers=get_headers(), - data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object - files={"objectData": b"Hello, world!"}) # File content as bytes +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) + +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the task ID from the response +task_id = result['task']['id'] # Check if the request was successful and print the result if result['success']: - print("Object Store File Uploaded Successfully:") + print("Task Created Successfully:") print(result) -### Get Object Store Metadata -# Prepare data payload to get object metadata -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "key": key # Key of the object to get metadata for -} -# Send a POST request to the /object/properties endpoint to get metadata -response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload) +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the metadata +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details if result['success']: - print("Object Store Metadata:") + print("Task Details:") print(result) -### Get Object Store File -# Prepare data payload to retrieve the object -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "keys": [key] # List of keys to retrieve (single key in this case) -} -# Send a POST request to the /object/get endpoint to get the object -response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload) +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the file content +# Check if the request was successful and print the result if result['success']: - print("Object Store File Content:") + print("Task Updated Successfully:") print(result) -### Delete Object Store File -# Prepare data payload to delete the object -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "key": key # Key of the object to delete -} -# Send a POST request to the /object/delete endpoint to delete the object -response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload) +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] # Check if the request was successful and print the result if result['success']: - print("Object Store File Deleted Successfully:") + print("Deployment Created Successfully:") print(result) -### List Object Store Files -# Define an empty path to list all objects (replace with specific path if needed) -path = "" -# Prepare data payload to list objects -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "path": path # Path to list objects from -} -# Send a POST request to the /object/list endpoint to list objects -response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload) +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the list if result['success']: - print("List of Object Store Files:") + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- +
- Get Object Store properties of a specific organization and key. It doesn't work if the key is a directory in the Object Store. + Update an existing agent.
@@ -89513,9 +97242,9 @@
- Get Object Store properties of a specific organization and key. The
+ Id of the agent to update and the fields to change. The
- /object/properties
+ /agents/update
API accepts requests in the following format:
- GetObjectStorePropertiesRequest
+ UpdateAgentRequest
- Model - Request to get Object Store properties of a specific organization and key.
+ Model - Request body for updating an agent.
- string
+ integer
required
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string
+
+
+ string Enum
+
+
+ integer
+
+
+ string
+
+
+ string Array
+
+
+ boolean
+
+
+ string
- example: 5cad178b20a1d52567b534553413b691
+ example: claude-opus-4-7
+ AgentChainedEntry Array
+
+
+ AgentSubAgentEntry Array
+
+
+ AgentToken object
+
+
+ boolean
+
+
string
+
+
+ AgentTaskOwner object
+
+
+ AgentOrganization object
+
+
+ AgentNode object
+
+
+{
+ "agentId": 0,
+ "name": "string",
+ "description": "string",
+ "profileImage": "string",
+ "systemPrompt": "string",
+ "reasoningEffort": "low",
+ "maxTurns": 0,
+ "toolChoice": "string",
+ "tools": [
+ "string"
+ ],
+ "public": true,
+ "model": "claude-opus-4-7",
+ "chainedAgents": [
+ {
+ "agentId": 105,
+ "step": 1,
+ "agent":
+ }
+ ],
+ "subAgents": [
+ {
+ "agentId": 105,
+ "callableCount": 1
+ }
+ ],
+ "token": {
+ "llmApiTokenUser": "sk-ant-api03-u78VgglQR-EkS-ymkG0QPoSJMl7G0z6mwC5Z3LrpAZ88TCdGpAVa1TQ4SzKIhh3aPhmrmI_A-tznXzcKcRQTBTkXaiVv4AA",
+ "llmProviderApi": "anthropic"
+ },
+ "useQCC": true,
+ "pipeline": "string",
+ "author": {
+ "publicId": "alexandre_catarino",
+ "name": "Alexandre Catarino",
+ "image": "e76004d3a79bb421536616863.jpeg"
+ },
+ "organization": {
+ "id": "3b137fed57f2326cc68e746f4eb99639",
+ "name": "QuantConnect",
+ "profile": "167df5c7cd6b3171771270587.png"
+ },
+ "node": {
+ "id": 0,
+ "sku": "A-8"
+ }
+}
+
+
+ AgentChainedEntry
+
+ Model - One entry in an agent's chain of follow-up agents.
+ |
+ |
|---|---|
| + agentId + | +
+
+ integer
- Key in the Object Store. + Identifier of the chained agent. + |
+
| + step + | +
+
+ integer
+
+ + Ordinal position of the agent in the chain. + |
+
| + agent + | +
+
+ object
+
+ + Embedded agent definition, populated when the chain entry is expanded. |
- The
-
- /object/properties
-
- API provides a response in the following format:
-
- GetObjectStorePropertiesResponse
+ AgentSubAgentEntry
- Model - Response received when fetching Object Store file properties.
+ Model - One sub-agent reference attached to an agent.
|
|
|---|---|
| - metadata + agentId |
- ObjectStoreProperties object
+ integer
+
- Object Store file properties. + Identifier of the sub-agent. |
| - success + callableCount |
- boolean
+ integer
+
+ + Maximum number of times this sub-agent can be invoked per deployment. + |
+
| + Example + | +
+
+
+
+{
+ "agentId": 105,
+ "callableCount": 1
+}
+ |
+
+
+ AgentToken
+
+ Model - User-supplied LLM provider credentials attached to an agent.
+ |
+ |||||||||
|---|---|---|---|---|---|---|---|---|---|
| + llmApiTokenUser + | +
+
+ string
+
- Indicate if the API request was successful. + API token supplied by the user for the chosen LLM provider. |
||||||||
| - errors + llmProviderApi |
- string Array
+ string
+
- List of errors with the API call. + Identifier of the LLM provider the token is for. |
||||||||
- ObjectStoreProperties
+ AgentTaskOwner
- Model - Object Store file properties.
+ Model - Owner of an agent task.
|
|||||||||
| - key + publicId |
string
+
- Object Store key. + Public profile slug of the user. |
||||||||
| - modified + name |
- string($date-time)
+ string
+
- Last time it was modified. + Display name of the user. |
||||||||
| - created + image |
- string($date-time)
+ string
+
- Date this project was created. + Filename of the user's profile image. |
||||||||
| - size + Example |
-
- number
-
- - Object Store file size. +
+
+{
+ "publicId": "alexandre_catarino",
+ "name": "Alexandre Catarino",
+ "image": "e76004d3a79bb421536616863.jpeg"
+}
+ |
||||||||
+
+ AgentOrganization
+
+ Model - Organization summary embedded on an agent.
+ |
+ |
|---|---|
| - md5 + id |
string
+
- MD5 (hashing algorithm) hash authentication code. + Identifier of the organization. |
| - mime + name |
string
+
- MIME type. + Display name of the organization. |
| - preview + profile |
string
+
- Preview of the Object Store file content. + Filename of the organization's profile image. |
- UnauthorizedError
+ AgentNode
- Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
+ Model - Compute node bound to an agent.
|
|
|---|---|
| - www_authenticate + id + | +
+
+ integer
+
+ + Identifier of the compute node assigned to the agent, or 0 when not pinned. + |
+
| + sku |
string
+
- Header + SKU of the compute node assigned to the agent. + |
+
| + Example + | +
+
+
+{
+ "id": 0,
+ "sku": "A-8"
+}
+ |
- The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. -
-from base64 import b64encode
-from hashlib import sha256
-from time import time
-from requests import get, post
-BASE_URL = 'https://www.quantconnect.com/api/v2/'
-
-# You need to replace these with your actual credentials.
-# You can request your credentials at https://www.quantconnect.com/settings/
-# You can find our organization ID at https://www.quantconnect.com/organization/
-USER_ID = 0
-API_TOKEN = '____'
-ORGANIZATION_ID = '____'
-
-def get_headers():
- # Get timestamp
- timestamp = f'{int(time())}'
- time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
-
- # Get hased API token
- hashed_token = sha256(time_stamped_token).hexdigest()
- authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
- authentication = b64encode(authentication).decode('ascii')
-
- # Create headers dictionary.
- return {
- 'Authorization': f'Basic {authentication}',
- 'Timestamp': timestamp
- }
-
-# Authenticate to verify credentials
-response = post(f'{BASE_URL}/authenticate', headers = get_headers())
-print(response.json())
-
-# --------------------
-
-
-# The key of the object wishes to manipulate
-key = "..."
-
-### Upload Object Store File
-# Send a POST request to the /object/set endpoint to upload a file
-response = post(f'{BASE_URL}/object/set', headers=get_headers(),
- data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
- files={"objectData": b"Hello, world!"}) # File content as bytes
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Object Store File Uploaded Successfully:")
- print(result)
-
-### Get Object Store Metadata
-# Prepare data payload to get object metadata
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "key": key # Key of the object to get metadata for
-}
-# Send a POST request to the /object/properties endpoint to get metadata
-response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the metadata
-if result['success']:
- print("Object Store Metadata:")
- print(result)
-
-### Get Object Store File
-# Prepare data payload to retrieve the object
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "keys": [key] # List of keys to retrieve (single key in this case)
-}
-# Send a POST request to the /object/get endpoint to get the object
-response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the file content
-if result['success']:
- print("Object Store File Content:")
- print(result)
-
-### Delete Object Store File
-# Prepare data payload to delete the object
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "key": key # Key of the object to delete
-}
-# Send a POST request to the /object/delete endpoint to delete the object
-response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the result
-if result['success']:
- print("Object Store File Deleted Successfully:")
- print(result)
-
-### List Object Store Files
-# Define an empty path to list all objects (replace with specific path if needed)
-path = ""
-# Prepare data payload to list objects
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "path": path # Path to list objects from
-}
-# Send a POST request to the /object/list endpoint to list objects
-response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
-# Parse the JSON response into python managable dict
-result = response.json()
-# Check if the request was successful and print the list
-if result['success']:
- print("List of Object Store Files:")
- print(result)
- - -
- Get Object Store file of a specific organization and key. -
- - - -
- Get Object Store files of a specific organization and key. The
-
- /object/get
-
- API accepts requests in the following format:
-
| - Get Object Store files of a specific organization and key. - | -
|---|
The
- /object/get
+ /agents/update
API provides a response in the following format:
- GetObjectStoreResponse
+ RestResponse
- Model - Response received when fetching an Object Store file.
+ Model - Base API response class for the QuantConnect API.
- string
-
-
- string
-
-
{
- "jobId": "string",
- "url": "string",
"success": true,
"errors": [
"string"
@@ -90124,7 +98102,7 @@ Examples
- The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API.
+ The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode
@@ -90163,92 +98141,254 @@ Examples
# --------------------
-# The key of the object wishes to manipulate
-key = "..."
+### List Agents
+# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent
+response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose agents to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Search the returned agents for one already named "My Claude"
+my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None)
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Agents:")
+ print(result)
-### Upload Object Store File
-# Send a POST request to the /object/set endpoint to upload a file
-response = post(f'{BASE_URL}/object/set', headers=get_headers(),
- data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object
- files={"objectData": b"Hello, world!"}) # File content as bytes
+### Create Agent (only when "My Claude" does not exist yet)
+if not my_claude:
+ # Send a POST request to the /agents/create endpoint to create a new agent
+ response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the agent
+ "name": "Agent Placeholder", # Placeholder name; renamed below
+ "description": "Customize your assistant's capabilities.",
+ "systemPrompt": "I am a bot", # System prompt for the agent
+ "model": "claude-opus-4-7", # Model identifier the agent runs on
+ "reasoningEffort": "high", # Reasoning effort: low | medium | high
+ "maxTurns": 100, # Max agent turns per deployment
+ "toolChoice": "auto", # Tool selection policy
+ "public": False, # Keep the agent private
+ "useQCC": True # Use the QuantConnect Cloud LLM provider
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Capture the created agent
+ my_claude = result['agent']
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Created Successfully:")
+ print(result)
+
+ ### Update Agent (rename the new agent to "My Claude")
+ # Send a POST request to the /agents/update endpoint to rename the agent
+ response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={
+ "agentId": my_claude['id'], # ID of the agent to update
+ "name": "My Claude" # New name for the agent
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Updated Successfully:")
+ print(result)
+
+# Capture the agent ID for downstream calls
+agent_id = my_claude['id']
+
+### Read Agent
+# Send a POST request to the /agents/read endpoint and check the model the agent runs on
+response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={
+ "agentId": agent_id # ID of the agent to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the agent's model
+if result['success']:
+ print(f"Agent model: {result['agent']['model']}")
+ print(result)
+
+### Delete Agent (left here for reference; uncomment to delete the agent)
+# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={
+# "agentId": agent_id # ID of the agent to delete
+# })
+# result = response.json()
+# if result['success']:
+# print("Agent Deleted Successfully:")
+# print(result)
+
+### Create Task
+# Send a POST request to the /agents/tasks/create endpoint to create a task
+response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the task
+ "agentId": 47, # ID of the agent the task uses
+ "name": f"Task_{int(time())}", # Unique task name
+ "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run
+ "projectPreference": "project-each-task-deployment" # New project per deployment
+})
# Parse the JSON response into python managable dict
result = response.json()
+# Extract the task ID from the response
+task_id = result['task']['id']
# Check if the request was successful and print the result
if result['success']:
- print("Object Store File Uploaded Successfully:")
+ print("Task Created Successfully:")
print(result)
-### Get Object Store Metadata
-# Prepare data payload to get object metadata
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "key": key # Key of the object to get metadata for
-}
-# Send a POST request to the /object/properties endpoint to get metadata
-response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload)
+### Read Task
+# Send a POST request to the /agents/tasks/read endpoint to read task details
+response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to read
+})
# Parse the JSON response into python managable dict
result = response.json()
-# Check if the request was successful and print the metadata
+# Extract the task name from the response
+task_name = result['task']['name']
+# Check if the request was successful and print the details
if result['success']:
- print("Object Store Metadata:")
+ print("Task Details:")
print(result)
-### Get Object Store File
-# Prepare data payload to retrieve the object
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "keys": [key] # List of keys to retrieve (single key in this case)
-}
-# Send a POST request to the /object/get endpoint to get the object
-response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload)
+### Update Task
+# Send a POST request to the /agents/tasks/update endpoint to rename the task
+response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={
+ "taskId": task_id, # ID of the task to update
+ "name": f"Test - {task_name}" # Prepend "Test - " to the existing name
+})
# Parse the JSON response into python managable dict
result = response.json()
-# Check if the request was successful and print the file content
+# Check if the request was successful and print the result
if result['success']:
- print("Object Store File Content:")
+ print("Task Updated Successfully:")
print(result)
-### Delete Object Store File
-# Prepare data payload to delete the object
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "key": key # Key of the object to delete
-}
-# Send a POST request to the /object/delete endpoint to delete the object
-response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload)
+### List Tasks
+# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org
+response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose tasks to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Tasks:")
+ print(result)
+
+### Create Deployment
+# Send a POST request to the /agents/deployments/create endpoint to deploy the task
+response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to deploy
+})
# Parse the JSON response into python managable dict
result = response.json()
+# Extract the deployment ID from the response
+deployment_id = result['deployment']['deploymentId']
# Check if the request was successful and print the result
if result['success']:
- print("Object Store File Deleted Successfully:")
+ print("Deployment Created Successfully:")
print(result)
-### List Object Store Files
-# Define an empty path to list all objects (replace with specific path if needed)
-path = ""
-# Prepare data payload to list objects
-payload = {
- "organizationId": ORGANIZATION_ID, # ID of the organization
- "path": path # Path to list objects from
-}
-# Send a POST request to the /object/list endpoint to list objects
-response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload)
+### Read Deployment
+# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status
+from time import sleep
+while True:
+ response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to read
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ status = result['deployment']['status']
+ print(f"Deployment status: {status}")
+ # Stop polling once the deployment is no longer running
+ if status in ('Completed', 'Stopped', 'Failed'):
+ break
+ # Wait before polling again
+ sleep(10)
+# Print the final deployment details
+print("Deployment Details:")
+print(result)
+
+### List Deployments
+# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task
+response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={
+ "taskId": task_id # ID of the task whose deployments to list
+})
# Parse the JSON response into python managable dict
result = response.json()
# Check if the request was successful and print the list
if result['success']:
- print("List of Object Store Files:")
+ print("List of Deployments:")
+ print(result)
+
+### Update Deployment (send a follow-up prompt)
+# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt
+response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={
+ "deploymentId": deployment_id, # ID of the running deployment
+ "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Prompt Sent Successfully:")
+ print(result)
+
+### Read Conversation
+# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript
+response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment whose conversation to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the conversation
+if result['success']:
+ print("Conversation Transcript:")
+ print(result)
+
+### Stop Deployment
+# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment
+response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to stop
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Stopped Successfully:")
+ print(result)
+
+### Delete Deployment
+# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment
+response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Deleted Successfully:")
+ print(result)
+
+### Delete Task
+# Send a POST request to the /agents/tasks/delete endpoint to delete the task
+response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Deleted Successfully:")
print(result)
-
+
-
- Object Store Management
- Delete Object Store File
+
+ Agents
+ Delete Agent
Introduction
@@ -90256,79 +98396,49 @@ Introduction
- Delete the Object Store file of a specific organization and key.
+ Delete an agent.
-
-
-Request
-
-
-
-
- Delete the Object Store file of a specific organization and key. The
-
- /object/delete
-
- API accepts requests in the following format:
-
-
-
- DeleteObjectStoreRequest
-
- Model - Request to delete an object in the Object Store for a specific organization and key.
- |
- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - organizationId - | -
-
- string
-
- - Id of the organization that owns the Object Store. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ DeleteAgentRequest
+
+ Model - Request body for deleting an agent.
+ |
+ |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - key + agentId |
- string
+ integer
- Key of the Object Store file to delete. + Identifier of the agent to delete. |
||||||||||||||||||||||||||||||||
- ListObjectStoreRequest
+ ListAgentsRequest
- Model - Request to list the Object Store files under a specific directory in an organization.
+ Model - Request body for listing the agents of an organization.
|
|||||||||||||||||||||||||||||||||
| - path - | -
-
- string
-
- - Path to a directory in the Object Store. + Identifier of the organization whose agents to list. |
||||||||||||||||||||||||||||||||
- ListObjectStoreResponse
+ UnauthorizedError
- Model - Response received containing a list of stored objects metadata, as well as the total size of all of them.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - path - | -
-
- string
-
- - Path to the directory in the Object Store. - |
-
| - objects - | -
-
- ObjectStoreSummary Array
-
- - List of directories and files stored in the directory at the given path. If the path contains directories, this list of objects doesn't contain the children of those directories. - |
-
| - page - | -
-
- integer
-
- - The current page number in the paginated response. - |
-
| - totalPages - | -
-
- integer
-
- - The total number of pages in the paginated response. - |
-
| - objectStorageUsed - | -
-
- integer
-
- - Size of all objects stored in bytes. - |
-
| - objectStorageUsedHuman + www_authenticate |
string
-
- - Size of all the objects stored in human-readable format. - |
-
| - success - | -
-
- boolean
-
- - Indicate if the API request was successful. - |
-
| - errors - | -
-
- string Array
- List of errors with the API call. - |
-
| - Example - | -
-
-
+ Header
-{
- "path": "Mia",
- "objects": [
- {
- "key": "Mia/Test",
- "name": "string",
- "modified": "2021-11-26T15:18:27.693Z",
- "mime": "application/json",
- "folder": true,
- "size": 13
- }
- ],
- "page": 0,
- "totalPages": 0,
- "objectStorageUsed": 0,
- "objectStorageUsedHuman": "2.27 GB",
- "success": true,
- "errors": [
- "string"
- ]
-}
- |
+ The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### List Agents
+# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent
+response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose agents to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Search the returned agents for one already named "My Claude"
+my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None)
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Agents:")
+ print(result)
+
+### Create Agent (only when "My Claude" does not exist yet)
+if not my_claude:
+ # Send a POST request to the /agents/create endpoint to create a new agent
+ response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the agent
+ "name": "Agent Placeholder", # Placeholder name; renamed below
+ "description": "Customize your assistant's capabilities.",
+ "systemPrompt": "I am a bot", # System prompt for the agent
+ "model": "claude-opus-4-7", # Model identifier the agent runs on
+ "reasoningEffort": "high", # Reasoning effort: low | medium | high
+ "maxTurns": 100, # Max agent turns per deployment
+ "toolChoice": "auto", # Tool selection policy
+ "public": False, # Keep the agent private
+ "useQCC": True # Use the QuantConnect Cloud LLM provider
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Capture the created agent
+ my_claude = result['agent']
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Created Successfully:")
+ print(result)
+
+ ### Update Agent (rename the new agent to "My Claude")
+ # Send a POST request to the /agents/update endpoint to rename the agent
+ response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={
+ "agentId": my_claude['id'], # ID of the agent to update
+ "name": "My Claude" # New name for the agent
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Updated Successfully:")
+ print(result)
+
+# Capture the agent ID for downstream calls
+agent_id = my_claude['id']
+
+### Read Agent
+# Send a POST request to the /agents/read endpoint and check the model the agent runs on
+response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={
+ "agentId": agent_id # ID of the agent to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the agent's model
+if result['success']:
+ print(f"Agent model: {result['agent']['model']}")
+ print(result)
+
+### Delete Agent (left here for reference; uncomment to delete the agent)
+# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={
+# "agentId": agent_id # ID of the agent to delete
+# })
+# result = response.json()
+# if result['success']:
+# print("Agent Deleted Successfully:")
+# print(result)
+
+### Create Task
+# Send a POST request to the /agents/tasks/create endpoint to create a task
+response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the task
+ "agentId": 47, # ID of the agent the task uses
+ "name": f"Task_{int(time())}", # Unique task name
+ "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run
+ "projectPreference": "project-each-task-deployment" # New project per deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task ID from the response
+task_id = result['task']['id']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Created Successfully:")
+ print(result)
+
+### Read Task
+# Send a POST request to the /agents/tasks/read endpoint to read task details
+response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task name from the response
+task_name = result['task']['name']
+# Check if the request was successful and print the details
+if result['success']:
+ print("Task Details:")
+ print(result)
+
+### Update Task
+# Send a POST request to the /agents/tasks/update endpoint to rename the task
+response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={
+ "taskId": task_id, # ID of the task to update
+ "name": f"Test - {task_name}" # Prepend "Test - " to the existing name
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Updated Successfully:")
+ print(result)
+
+### List Tasks
+# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org
+response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose tasks to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Tasks:")
+ print(result)
+
+### Create Deployment
+# Send a POST request to the /agents/deployments/create endpoint to deploy the task
+response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to deploy
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the deployment ID from the response
+deployment_id = result['deployment']['deploymentId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Created Successfully:")
+ print(result)
+
+### Read Deployment
+# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status
+from time import sleep
+while True:
+ response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to read
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ status = result['deployment']['status']
+ print(f"Deployment status: {status}")
+ # Stop polling once the deployment is no longer running
+ if status in ('Completed', 'Stopped', 'Failed'):
+ break
+ # Wait before polling again
+ sleep(10)
+# Print the final deployment details
+print("Deployment Details:")
+print(result)
+
+### List Deployments
+# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task
+response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={
+ "taskId": task_id # ID of the task whose deployments to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Deployments:")
+ print(result)
+
+### Update Deployment (send a follow-up prompt)
+# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt
+response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={
+ "deploymentId": deployment_id, # ID of the running deployment
+ "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Prompt Sent Successfully:")
+ print(result)
+
+### Read Conversation
+# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript
+response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment whose conversation to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the conversation
+if result['success']:
+ print("Conversation Transcript:")
+ print(result)
+
+### Stop Deployment
+# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment
+response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to stop
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Stopped Successfully:")
+ print(result)
+
+### Delete Deployment
+# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment
+response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Deleted Successfully:")
+ print(result)
+
+### Delete Task
+# Send a POST request to the /agents/tasks/delete endpoint to delete the task
+response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Deleted Successfully:")
+ print(result)
+ + +
+ Create a new agent task. +
+ + + +
+ Organization, agent, name, prompt, and project preference for the new task. The
+
+ /agents/tasks/create
+
+ API accepts requests in the following format:
+
- ObjectStoreSummary
+ CreateAgentTaskRequest
- Model - Summary information of the Object Store.
+ Model - Request body for creating an agent task.
|
|
|---|---|
| - key + organizationId |
@@ -90854,41 +99300,41 @@
- Object Store key. - |
-
| - name - | -
-
- string
-
- - File or folder name. + Identifier of the organization that will own the task. |
| - modified + agentId |
- string($date-time)
+ integer
+
- Last time it was modified. + Identifier of the agent the task should use. |
| - mime + name |
@@ -90896,42 +99342,48 @@
- MIME type. + Name of the task. The platform may rewrite this to a normalized form on create. |
| - folder + prompt |
- boolean
+ string
+
- True if it is a folder, false otherwise. + Prompt the agent will execute when the task is deployed. |
| - size + projectPreference |
- number
+ string Enum
- Object Store file size. + How projects should be mapped to deployments of this task. Options : ['project-each-task-deployment', 'project-for-task'] |
+ The
+
+ /agents/tasks/create
+
+ API provides a response in the following format:
+
- The following example demonstates uploading, getting, deleting, and listing Object Store objects through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -91026,106 +99494,254 @@Examples
# -------------------- -# The key of the object wishes to manipulate -key = "..." +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list +if result['success']: + print("List of Agents:") + print(result) -### Upload Object Store File -# Send a POST request to the /object/set endpoint to upload a file -response = post(f'{BASE_URL}/object/set', headers=get_headers(), - data={"organizationId": ORGANIZATION_ID, "key": key}, # Organization ID and key for the object - files={"objectData": b"Hello, world!"}) # File content as bytes +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) + +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the task ID from the response +task_id = result['task']['id'] # Check if the request was successful and print the result if result['success']: - print("Object Store File Uploaded Successfully:") + print("Task Created Successfully:") print(result) -### Get Object Store Metadata -# Prepare data payload to get object metadata -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "key": key # Key of the object to get metadata for -} -# Send a POST request to the /object/properties endpoint to get metadata -response = post(f'{BASE_URL}/object/properties', headers=get_headers(), json=payload) +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the metadata +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details if result['success']: - print("Object Store Metadata:") + print("Task Details:") print(result) -### Get Object Store File -# Prepare data payload to retrieve the object -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "keys": [key] # List of keys to retrieve (single key in this case) -} -# Send a POST request to the /object/get endpoint to get the object -response = post(f'{BASE_URL}/object/get', headers=get_headers(), json=payload) +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the file content +# Check if the request was successful and print the result if result['success']: - print("Object Store File Content:") + print("Task Updated Successfully:") print(result) -### Delete Object Store File -# Prepare data payload to delete the object -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "key": key # Key of the object to delete -} -# Send a POST request to the /object/delete endpoint to delete the object -response = post(f'{BASE_URL}/object/delete', headers=get_headers(), json=payload) +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) # Parse the JSON response into python managable dict result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] # Check if the request was successful and print the result if result['success']: - print("Object Store File Deleted Successfully:") + print("Deployment Created Successfully:") print(result) -### List Object Store Files -# Define an empty path to list all objects (replace with specific path if needed) -path = "" -# Prepare data payload to list objects -payload = { - "organizationId": ORGANIZATION_ID, # ID of the organization - "path": path # Path to list objects from -} -# Send a POST request to the /object/list endpoint to list objects -response = post(f'{BASE_URL}/object/list', headers=get_headers(), json=payload) +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) # Parse the JSON response into python managable dict result = response.json() # Check if the request was successful and print the list if result['success']: - print("List of Object Store Files:") + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- -
- Run a backtest for a few seconds to initialize the algorithm and get initialization errors if any. + Read an agent task by Id.
@@ -91143,9 +99759,9 @@
- Run a backtest for a few seconds to initialize the algorithm and get initialization errors if any. The
+ Id of the task to read. The
- /ai/tools/backtest-init
+ /agents/tasks/read
API accepts requests in the following format:
- BasicFilesRequest
+ ReadAgentTaskRequest
- Model - Request to process files.
+ Model - Request body for reading an agent task.
- string Enum
-
-
-
- required
-
-
-
-
-
- example: Py
-
-
-
-
- File Array
+ integer
required
-
-
-
- example: [{"name": "file.py", "content": "fileContent"}]
-
-
-
-
-{
- "language": "Py",
- "files": "[{"name": "file.py", "content": "fileContent"}]"
- ]
-}
-
-
- File
-
- Model - File for a AI.
- |
- |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - name - | -
-
- string
-
- - Name of a file. - |
- ||||||||||||||||
| - content - | -
-
- string
- Contents of the file. + Identifier of the task to read. |
||||||||||||||||
-
- BacktestInitResponse
-
- Model - Response to a backtest initialization request.
- |
- |
|---|---|
| - state - | -
-
- string Enum
-
- - State of the backtest. Options : ['End', 'Error'] - |
-
| - version - | -
-
- number
-
- - Version of the response. - |
-
| - payload - | -
-
- string
-
- - Information about the backtest initialization. - |
-
| - payloadType - | -
-
- string
-
- - Type of the payload. - |
-
| - Example - | -
-
-
-
-{
- "state": "End",
- "version": 2.0,
- "payload": "string",
- "payloadType": "String"
-}
- |
-
- The following example demonstates initializing a backtest for a specific algorithm through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -91458,42 +99898,254 @@Examples
# -------------------- -### Initialize Backtest -# Send a POST request to the /ai/tools/backtest-init endpoint to initialize a backtest -response = post(f'{BASE_URL}/ai/tools/backtest-init', headers=get_headers(), json={ - "language": "Python", # Programming language of the algorithm - "files": [ # List of files for the backtest - { - "name": "utils.py", # Name of the file - "content": ''' -# region imports -from AlgorithmImports import * -# endregion +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list +if result['success']: + print("List of Agents:") + print(result) -class Project(QCAlgorithm): +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) - def Initialize(self): - self.AddEquity("SPY", Resolution.Minute) -''' # Content of the file (Python code) - } - ] +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment }) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the backtest initialization result +# Extract the task ID from the response +task_id = result['task']['id'] +# Check if the request was successful and print the result if result['success']: - print("Backtest Initialized Successfully:") + print("Task Created Successfully:") + print(result) + +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details +if result['success']: + print("Task Details:") + print(result) + +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Updated Successfully:") + print(result) + +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] +# Check if the request was successful and print the result +if result['success']: + print("Deployment Created Successfully:") + print(result) + +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- +
- Show the code completion for a specific text input. + Update an agent task.
@@ -91511,9 +100163,9 @@
- Show the code completion for a specific text input. The
+ Id and new name of the task to update. The
- /ai/tools/complete
+ /agents/tasks/update
API accepts requests in the following format:
- CodeCompletionRequest
+ UpdateAgentTaskRequest
- Model - Request to show code completion for a specific text input.
+ Model - Request body for updating an agent task.
- string Enum
-
-
-
- required
-
-
-
-
-
- example: Py
-
-
-
-
- string
+ integer
required
-
-
-
- example: self.add_eq
-
-
- integer
-
-
-
- example: 10
-
-
+ string
{
- "language": "Py",
- "sentence": "self.add_eq",
- "responseSizeLimit": 10
+ "taskId": 0,
+ "name": "string"
}
The
- /ai/tools/complete
+ /agents/tasks/update
API provides a response in the following format:
- CodeCompletionResponse
+ RestResponse
- Model - Response to a code completion request.
+ Model - Base API response class for the QuantConnect API.
- string Enum
-
-
- number
-
-
-
- example: 2.0
-
-
+ boolean
string Array
- string
-
-
-
- example: StringArray
-
-
-
-
{
- "state": "End",
- "version": 2.0,
- "payload": [
+ "success": true,
+ "errors": [
"string"
- ],
- "payloadType": "StringArray"
]
}
- The following example demonstates code completion for a specific algorithm attribute through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -91791,29 +100367,254 @@Examples
# -------------------- -### Code Completion -# Send a POST request to the /ai/tools/complete endpoint to get code completion -response = post(f'{BASE_URL}/ai/tools/complete', headers=get_headers(), json={ - "language": "Python", # Programming language for code completion - "sentence": "self.add_equity('AAPL", # Partial code to complete - "responseSizeLimit": 30 # Maximum size of the completion response +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list }) -# Parse the JSON response +# Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the code completion results +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list if result['success']: - print("Code Completion Results:") + print("List of Agents:") + print(result) + +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) + +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the task ID from the response +task_id = result['task']['id'] +# Check if the request was successful and print the result +if result['success']: + print("Task Created Successfully:") + print(result) + +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details +if result['success']: + print("Task Details:") + print(result) + +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Updated Successfully:") + print(result) + +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] +# Check if the request was successful and print the result +if result['success']: + print("Deployment Created Successfully:") + print(result) + +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- +
- Show additional context and suggestions for error messages. + Delete an agent task.
@@ -91831,9 +100632,9 @@
- Show additional context and suggestions for error messages. The
+ Id of the task to delete. The
- /ai/tools/error-enhance
+ /agents/tasks/delete
API accepts requests in the following format:
- ErrorEnhanceRequest
-
- Model - Request to show additional context and suggestions for error messages.
-
- string Enum
-
-
-
- required
-
-
-
-
-
- example: Py
-
-
-
-
- Error object
-
-
-
- required
-
-
-
-
-{
- "language": "Py",
- "error": {
- "message": "string",
- "stacktrace": "string"
- }
-}
-
-
- Error
+ DeleteAgentTaskRequest
- Model - Error information.
+ Model - Request body for deleting an agent task.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - message + taskId |
- string
+ integer
- Error message. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - stacktrace - | -
-
- string
-
- - Stack trace of the error. + Identifier of the task to delete. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ErrorEnhanceResponse
+ RestResponse
- Model - Response to error enhancement request.
+ Model - Base API response class for the QuantConnect API.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - state - | -
-
- string
-
- - State of the code completion. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - version - | -
-
- number
-
- - Version of the response. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - payload + success |
- string
+ boolean
- Error message suggestions. + Indicate if the API request was successful. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - payloadType + errors |
- string
-
- Type of the payload. + List of errors with the API call. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-
- PEP8ConvertRequest
-
- Model - Request to convert Python code to PEP8 style.
- |
- |
|---|---|
| - files - | -
-
- File Array
-
- - Files of the project. - |
-
| - Example - | -
-
-
-
-{
- "files": "[{"name": "file.py", "content": "fileContent"}]"
- ]
-}
- |
-
+ List the agent tasks of an organization. +
+ + + +
+ Id of the organization whose tasks to list. The
+
+ /agents/tasks/list
+
+ API accepts requests in the following format:
+
- File
+ ListAgentTasksRequest
- Model - File for a AI.
+ Model - Request body for listing the agent tasks of an organization.
|
|||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| - name + organizationId |
@@ -92271,24 +101115,12 @@
- Name of a file. - |
- ||||||||||
| - content - | -
-
- string
-
- - Contents of the file. + Identifier of the organization whose tasks to list. |
||||||||||
-
- PEP8ConvertResponse
-
- Model - Response to a PEP8 conversion request.
- |
- |
|---|---|
| - state - | -
-
- string
-
- - State of PEP8 conversion. - |
-
| - version - | -
-
- number
-
- - Version of the response. - |
-
| - payload - | -
-
- object
-
- - A dictionary where the key is the file name and the value is the PEP8 converted code of that file. - |
-
| - payloadType - | -
-
- string
-
- - Type of the payload. - |
-
| - Example - | -
-
-
-
-{
- "state": "End",
- "version": 2.0,
- "payload": {
- "utils.py": "def add(a,b):\n return a+b\n"
-},
- "payloadType": "StringDict"
-}
- |
-
- The following example demonstates PEP8 conversion of python codes through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -92498,41 +101227,261 @@Examples
# -------------------- -### PEP8 Conversion -# Send a POST request to the /ai/tools/pep8-convert endpoint to convert code to PEP8 syntax -response = post(f'{BASE_URL}/ai/tools/pep8-convert', headers=get_headers(), json={ - "files": [ # List of files to convert - { - "name": "utils.py", # Name of the file - "content": ''' -# region imports -from AlgorithmImports import * -# endregion +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list +if result['success']: + print("List of Agents:") + print(result) -class Project(QCAlgorithm): +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) - def Initialize(self): - self.AddEquity("SPY", Resolution.Minute) -''' # Content of the file (Python code) - } - ] +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment }) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the PEP8 conversion results +# Extract the task ID from the response +task_id = result['task']['id'] +# Check if the request was successful and print the result if result['success']: - print("PEP8 Conversion Results:") + print("Task Created Successfully:") + print(result) + +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details +if result['success']: + print("Task Details:") + print(result) + +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Updated Successfully:") + print(result) + +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] +# Check if the request was successful and print the result +if result['success']: + print("Deployment Created Successfully:") + print(result) + +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- +
- Check the syntax of a code. + Deploy an agent task.
@@ -92550,9 +101499,9 @@
- Check the syntax of a code. The
+ Id of the task to deploy. The
- /ai/tools/syntax-check
+ /agents/deployments/create
API accepts requests in the following format:
- BasicFilesRequest
+ CreateAgentDeploymentRequest
- Model - Request to process files.
+ Model - Request body for creating an agent deployment.
- string Enum
-
-
-
- required
-
-
-
-
-
- example: Py
-
-
-
-
- File Array
+ integer
required
-
-
-
- example: [{"name": "file.py", "content": "fileContent"}]
-
-
{
- "language": "Py",
- "files": "[{"name": "file.py", "content": "fileContent"}]"
- ]
+ "taskId": 0
}
+ The
+
+ /agents/deployments/create
+
+ API provides a response in the following format:
+
- File
+ UnauthorizedError
- Model - File for a AI.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - name - | -
-
- string
-
- - Name of a file. - |
-
| - content + www_authenticate |
string
- Contents of the file. - |
-
| - Example - | -
-
-
+ Header
-{
- "name": "main.py",
- "content": "string"
-}
- |
+ The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### List Agents
+# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent
+response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose agents to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Search the returned agents for one already named "My Claude"
+my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None)
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Agents:")
+ print(result)
+
+### Create Agent (only when "My Claude" does not exist yet)
+if not my_claude:
+ # Send a POST request to the /agents/create endpoint to create a new agent
+ response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the agent
+ "name": "Agent Placeholder", # Placeholder name; renamed below
+ "description": "Customize your assistant's capabilities.",
+ "systemPrompt": "I am a bot", # System prompt for the agent
+ "model": "claude-opus-4-7", # Model identifier the agent runs on
+ "reasoningEffort": "high", # Reasoning effort: low | medium | high
+ "maxTurns": 100, # Max agent turns per deployment
+ "toolChoice": "auto", # Tool selection policy
+ "public": False, # Keep the agent private
+ "useQCC": True # Use the QuantConnect Cloud LLM provider
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Capture the created agent
+ my_claude = result['agent']
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Created Successfully:")
+ print(result)
+
+ ### Update Agent (rename the new agent to "My Claude")
+ # Send a POST request to the /agents/update endpoint to rename the agent
+ response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={
+ "agentId": my_claude['id'], # ID of the agent to update
+ "name": "My Claude" # New name for the agent
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Updated Successfully:")
+ print(result)
+
+# Capture the agent ID for downstream calls
+agent_id = my_claude['id']
+
+### Read Agent
+# Send a POST request to the /agents/read endpoint and check the model the agent runs on
+response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={
+ "agentId": agent_id # ID of the agent to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the agent's model
+if result['success']:
+ print(f"Agent model: {result['agent']['model']}")
+ print(result)
+
+### Delete Agent (left here for reference; uncomment to delete the agent)
+# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={
+# "agentId": agent_id # ID of the agent to delete
+# })
+# result = response.json()
+# if result['success']:
+# print("Agent Deleted Successfully:")
+# print(result)
+
+### Create Task
+# Send a POST request to the /agents/tasks/create endpoint to create a task
+response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the task
+ "agentId": 47, # ID of the agent the task uses
+ "name": f"Task_{int(time())}", # Unique task name
+ "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run
+ "projectPreference": "project-each-task-deployment" # New project per deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task ID from the response
+task_id = result['task']['id']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Created Successfully:")
+ print(result)
+
+### Read Task
+# Send a POST request to the /agents/tasks/read endpoint to read task details
+response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task name from the response
+task_name = result['task']['name']
+# Check if the request was successful and print the details
+if result['success']:
+ print("Task Details:")
+ print(result)
+
+### Update Task
+# Send a POST request to the /agents/tasks/update endpoint to rename the task
+response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={
+ "taskId": task_id, # ID of the task to update
+ "name": f"Test - {task_name}" # Prepend "Test - " to the existing name
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Updated Successfully:")
+ print(result)
+
+### List Tasks
+# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org
+response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose tasks to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Tasks:")
+ print(result)
+
+### Create Deployment
+# Send a POST request to the /agents/deployments/create endpoint to deploy the task
+response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to deploy
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the deployment ID from the response
+deployment_id = result['deployment']['deploymentId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Created Successfully:")
+ print(result)
+
+### Read Deployment
+# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status
+from time import sleep
+while True:
+ response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to read
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ status = result['deployment']['status']
+ print(f"Deployment status: {status}")
+ # Stop polling once the deployment is no longer running
+ if status in ('Completed', 'Stopped', 'Failed'):
+ break
+ # Wait before polling again
+ sleep(10)
+# Print the final deployment details
+print("Deployment Details:")
+print(result)
+
+### List Deployments
+# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task
+response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={
+ "taskId": task_id # ID of the task whose deployments to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Deployments:")
+ print(result)
+
+### Update Deployment (send a follow-up prompt)
+# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt
+response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={
+ "deploymentId": deployment_id, # ID of the running deployment
+ "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Prompt Sent Successfully:")
+ print(result)
+
+### Read Conversation
+# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript
+response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment whose conversation to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the conversation
+if result['success']:
+ print("Conversation Transcript:")
+ print(result)
+
+### Stop Deployment
+# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment
+response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to stop
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Stopped Successfully:")
+ print(result)
+
+### Delete Deployment
+# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment
+response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Deleted Successfully:")
+ print(result)
+
+### Delete Task
+# Send a POST request to the /agents/tasks/delete endpoint to delete the task
+response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Deleted Successfully:")
+ print(result)
+ + +
- The + Read an agent deployment by Id. +
+ + + +
+ Id of the deployment to read. The
- /ai/tools/syntax-check
+ /agents/deployments/read
- API provides a response in the following format:
+ API accepts requests in the following format:
- SyntaxCheckResponse
+ ReadAgentDeploymentRequest
- Model - Response to a syntax check request.
+ Model - Request body for reading an agent deployment.
|
|
|---|---|
| - state - | -
-
- string Enum
-
- - State of the syntax check. Options : ['End', 'Error'] - |
-
| - version - | -
-
- number
-
- - Version of the response. - |
-
| - payload - | -
-
- string Array
-
- - Code completion suggestions. - |
-
| - payloadType + deploymentId |
@@ -92767,12 +101930,12 @@
- Type of the payload. + Identifier of the deployment to read. |
+ The
+
+ /agents/deployments/read
+
+ API provides a response in the following format:
+
- The following example demonstates syntax checking of codes through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -92868,42 +102042,254 @@Examples
# -------------------- -### Syntax Check -# Send a POST request to the /ai/tools/syntax-check endpoint to check code syntax if appropriate -response = post(f'{BASE_URL}/ai/tools/syntax-check', headers=get_headers(), json={ - "language": "Python", # Programming language of the code - "files": [ # List of files to check - { - "name": "utils.py", # Name of the file - "content": ''' -# region imports -from AlgorithmImports import * -# endregion +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list +if result['success']: + print("List of Agents:") + print(result) -class Project(QCAlgorithm): +### Create Agent (only when "My Claude" does not exist yet) +if not my_claude: + # Send a POST request to the /agents/create endpoint to create a new agent + response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the agent + "name": "Agent Placeholder", # Placeholder name; renamed below + "description": "Customize your assistant's capabilities.", + "systemPrompt": "I am a bot", # System prompt for the agent + "model": "claude-opus-4-7", # Model identifier the agent runs on + "reasoningEffort": "high", # Reasoning effort: low | medium | high + "maxTurns": 100, # Max agent turns per deployment + "toolChoice": "auto", # Tool selection policy + "public": False, # Keep the agent private + "useQCC": True # Use the QuantConnect Cloud LLM provider + }) + # Parse the JSON response into python managable dict + result = response.json() + # Capture the created agent + my_claude = result['agent'] + # Check if the request was successful and print the result + if result['success']: + print("Agent Created Successfully:") + print(result) + + ### Update Agent (rename the new agent to "My Claude") + # Send a POST request to the /agents/update endpoint to rename the agent + response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={ + "agentId": my_claude['id'], # ID of the agent to update + "name": "My Claude" # New name for the agent + }) + # Parse the JSON response into python managable dict + result = response.json() + # Check if the request was successful and print the result + if result['success']: + print("Agent Updated Successfully:") + print(result) + +# Capture the agent ID for downstream calls +agent_id = my_claude['id'] + +### Read Agent +# Send a POST request to the /agents/read endpoint and check the model the agent runs on +response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={ + "agentId": agent_id # ID of the agent to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the agent's model +if result['success']: + print(f"Agent model: {result['agent']['model']}") + print(result) - def Initialize(self): - self.AddEquity("SPY", Resolution.Minute) -''' # Content of the file (Python code) - } - ] +### Delete Agent (left here for reference; uncomment to delete the agent) +# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={ +# "agentId": agent_id # ID of the agent to delete +# }) +# result = response.json() +# if result['success']: +# print("Agent Deleted Successfully:") +# print(result) + +### Create Task +# Send a POST request to the /agents/tasks/create endpoint to create a task +response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID, # Organization that owns the task + "agentId": 47, # ID of the agent the task uses + "name": f"Task_{int(time())}", # Unique task name + "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run + "projectPreference": "project-each-task-deployment" # New project per deployment }) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the syntax check results +# Extract the task ID from the response +task_id = result['task']['id'] +# Check if the request was successful and print the result if result['success']: - print("Syntax Check Results:") + print("Task Created Successfully:") + print(result) + +### Read Task +# Send a POST request to the /agents/tasks/read endpoint to read task details +response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={ + "taskId": task_id # ID of the task to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the task name from the response +task_name = result['task']['name'] +# Check if the request was successful and print the details +if result['success']: + print("Task Details:") + print(result) + +### Update Task +# Send a POST request to the /agents/tasks/update endpoint to rename the task +response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={ + "taskId": task_id, # ID of the task to update + "name": f"Test - {task_name}" # Prepend "Test - " to the existing name +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Updated Successfully:") + print(result) + +### List Tasks +# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org +response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose tasks to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Tasks:") + print(result) + +### Create Deployment +# Send a POST request to the /agents/deployments/create endpoint to deploy the task +response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={ + "taskId": task_id # ID of the task to deploy +}) +# Parse the JSON response into python managable dict +result = response.json() +# Extract the deployment ID from the response +deployment_id = result['deployment']['deploymentId'] +# Check if the request was successful and print the result +if result['success']: + print("Deployment Created Successfully:") + print(result) + +### Read Deployment +# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status +from time import sleep +while True: + response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to read + }) + # Parse the JSON response into python managable dict + result = response.json() + status = result['deployment']['status'] + print(f"Deployment status: {status}") + # Stop polling once the deployment is no longer running + if status in ('Completed', 'Stopped', 'Failed'): + break + # Wait before polling again + sleep(10) +# Print the final deployment details +print("Deployment Details:") +print(result) + +### List Deployments +# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task +response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={ + "taskId": task_id # ID of the task whose deployments to list +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the list +if result['success']: + print("List of Deployments:") + print(result) + +### Update Deployment (send a follow-up prompt) +# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt +response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={ + "deploymentId": deployment_id, # ID of the running deployment + "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Prompt Sent Successfully:") + print(result) + +### Read Conversation +# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript +response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment whose conversation to read +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the conversation +if result['success']: + print("Conversation Transcript:") + print(result) + +### Stop Deployment +# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment +response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to stop +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Stopped Successfully:") + print(result) + +### Delete Deployment +# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment +response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={ + "deploymentId": deployment_id # ID of the deployment to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Deployment Deleted Successfully:") + print(result) + +### Delete Task +# Send a POST request to the /agents/tasks/delete endpoint to delete the task +response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={ + "taskId": task_id # ID of the task to delete +}) +# Parse the JSON response into python managable dict +result = response.json() +# Check if the request was successful and print the result +if result['success']: + print("Task Deleted Successfully:") print(result)
- +
- Search for content in QuantConnect. + Send a follow-up prompt to a running agent deployment.
@@ -92921,9 +102307,9 @@
- Search for content in QuantConnect. The
+ Id of the deployment and the new prompt to run. The
- /ai/tools/search
+ /agents/deployments/prompt
API accepts requests in the following format:
- SearchRequest
-
- Model - Request to search content in QuantConnect.
-
- string Enum
-
-
-
- required
-
-
-
-
-
- example: Py
-
-
-
-
- SearchCriteria Array
-
-
-
- required
-
-
-
-
-{
- "language": "Py",
- "criteria": [
- {
- "input": "option",
- "type": "Stubs",
- "count": 1
- }
- ]
-}
-
-
- SearchCriteria
+ UpdateAgentDeploymentRequest
- Model - Search criteria.
+ Model - Request body for sending a follow-up prompt to an agent deployment.
|
|||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - input + deploymentId |
@@ -93028,39 +102340,21 @@
- - Input for the search. - |
- ||||||||||||||||||||
| - type - | -
-
- string Enum
-
- Type of the search criteria. Options : ['Stubs', 'Forum', 'Docs', 'Examples'] + Identifier of the running deployment to send the follow-up prompt to. |
||||||||||||||||||||
| - count + prompt |
- integer
+ string
- Number of results to return. + New prompt for the deployment to run. |
||||||||||||||||||||
- SearchResponse
+ UnauthorizedError
- Model - Response to a search request.
+ Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash.
|
|
|---|---|
| - state - | -
-
- string Enum
-
- - State of the search. Options : ['End', 'Error'] - |
-
| - version - | -
-
- number
-
- - Version of the response. - |
-
| - retrivals - | -
-
- SearchRetrieval Array
-
- - List of search results. - |
-
| - messageId + www_authenticate |
- integer
-
- Id of the message. - |
-
| - Example - | -
-
-
+ Header
-{
- "state": "End",
- "version": 2.0,
- "retrivals": [
- {
- "url": "[Index Options - QuantConnect.com](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/index-options)",
- "score": 0.320344448,
- "content": "string",
- "type": 2
- }
- ],
- "messageId": 0
-}
- |
+ The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API. +
+from base64 import b64encode
+from hashlib import sha256
+from time import time
+from requests import get, post
+BASE_URL = 'https://www.quantconnect.com/api/v2/'
+
+# You need to replace these with your actual credentials.
+# You can request your credentials at https://www.quantconnect.com/settings/
+# You can find our organization ID at https://www.quantconnect.com/organization/
+USER_ID = 0
+API_TOKEN = '____'
+ORGANIZATION_ID = '____'
+
+def get_headers():
+ # Get timestamp
+ timestamp = f'{int(time())}'
+ time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
+
+ # Get hased API token
+ hashed_token = sha256(time_stamped_token).hexdigest()
+ authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
+ authentication = b64encode(authentication).decode('ascii')
+
+ # Create headers dictionary.
+ return {
+ 'Authorization': f'Basic {authentication}',
+ 'Timestamp': timestamp
+ }
+
+# Authenticate to verify credentials
+response = post(f'{BASE_URL}/authenticate', headers = get_headers())
+print(response.json())
+
+# --------------------
+
+
+### List Agents
+# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent
+response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose agents to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Search the returned agents for one already named "My Claude"
+my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None)
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Agents:")
+ print(result)
+
+### Create Agent (only when "My Claude" does not exist yet)
+if not my_claude:
+ # Send a POST request to the /agents/create endpoint to create a new agent
+ response = post(f'{BASE_URL}/agents/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the agent
+ "name": "Agent Placeholder", # Placeholder name; renamed below
+ "description": "Customize your assistant's capabilities.",
+ "systemPrompt": "I am a bot", # System prompt for the agent
+ "model": "claude-opus-4-7", # Model identifier the agent runs on
+ "reasoningEffort": "high", # Reasoning effort: low | medium | high
+ "maxTurns": 100, # Max agent turns per deployment
+ "toolChoice": "auto", # Tool selection policy
+ "public": False, # Keep the agent private
+ "useQCC": True # Use the QuantConnect Cloud LLM provider
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Capture the created agent
+ my_claude = result['agent']
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Created Successfully:")
+ print(result)
+
+ ### Update Agent (rename the new agent to "My Claude")
+ # Send a POST request to the /agents/update endpoint to rename the agent
+ response = post(f'{BASE_URL}/agents/update', headers=get_headers(), json={
+ "agentId": my_claude['id'], # ID of the agent to update
+ "name": "My Claude" # New name for the agent
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ # Check if the request was successful and print the result
+ if result['success']:
+ print("Agent Updated Successfully:")
+ print(result)
+
+# Capture the agent ID for downstream calls
+agent_id = my_claude['id']
+
+### Read Agent
+# Send a POST request to the /agents/read endpoint and check the model the agent runs on
+response = post(f'{BASE_URL}/agents/read', headers=get_headers(), json={
+ "agentId": agent_id # ID of the agent to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the agent's model
+if result['success']:
+ print(f"Agent model: {result['agent']['model']}")
+ print(result)
+
+### Delete Agent (left here for reference; uncomment to delete the agent)
+# response = post(f'{BASE_URL}/agents/delete', headers=get_headers(), json={
+# "agentId": agent_id # ID of the agent to delete
+# })
+# result = response.json()
+# if result['success']:
+# print("Agent Deleted Successfully:")
+# print(result)
+
+### Create Task
+# Send a POST request to the /agents/tasks/create endpoint to create a task
+response = post(f'{BASE_URL}/agents/tasks/create', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID, # Organization that owns the task
+ "agentId": 47, # ID of the agent the task uses
+ "name": f"Task_{int(time())}", # Unique task name
+ "prompt": "Build a buy and hold strategy for SPY", # Prompt the agent will run
+ "projectPreference": "project-each-task-deployment" # New project per deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task ID from the response
+task_id = result['task']['id']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Created Successfully:")
+ print(result)
+
+### Read Task
+# Send a POST request to the /agents/tasks/read endpoint to read task details
+response = post(f'{BASE_URL}/agents/tasks/read', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the task name from the response
+task_name = result['task']['name']
+# Check if the request was successful and print the details
+if result['success']:
+ print("Task Details:")
+ print(result)
+
+### Update Task
+# Send a POST request to the /agents/tasks/update endpoint to rename the task
+response = post(f'{BASE_URL}/agents/tasks/update', headers=get_headers(), json={
+ "taskId": task_id, # ID of the task to update
+ "name": f"Test - {task_name}" # Prepend "Test - " to the existing name
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Updated Successfully:")
+ print(result)
+
+### List Tasks
+# Send a POST request to the /agents/tasks/list endpoint to list tasks in the org
+response = post(f'{BASE_URL}/agents/tasks/list', headers=get_headers(), json={
+ "organizationId": ORGANIZATION_ID # Organization whose tasks to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Tasks:")
+ print(result)
+
+### Create Deployment
+# Send a POST request to the /agents/deployments/create endpoint to deploy the task
+response = post(f'{BASE_URL}/agents/deployments/create', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to deploy
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Extract the deployment ID from the response
+deployment_id = result['deployment']['deploymentId']
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Created Successfully:")
+ print(result)
+
+### Read Deployment
+# Poll the /agents/deployments/read endpoint until the deployment reaches a terminal status
+from time import sleep
+while True:
+ response = post(f'{BASE_URL}/agents/deployments/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to read
+ })
+ # Parse the JSON response into python managable dict
+ result = response.json()
+ status = result['deployment']['status']
+ print(f"Deployment status: {status}")
+ # Stop polling once the deployment is no longer running
+ if status in ('Completed', 'Stopped', 'Failed'):
+ break
+ # Wait before polling again
+ sleep(10)
+# Print the final deployment details
+print("Deployment Details:")
+print(result)
+
+### List Deployments
+# Send a POST request to the /agents/deployments/list endpoint to list deployments of the task
+response = post(f'{BASE_URL}/agents/deployments/list', headers=get_headers(), json={
+ "taskId": task_id # ID of the task whose deployments to list
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the list
+if result['success']:
+ print("List of Deployments:")
+ print(result)
+
+### Update Deployment (send a follow-up prompt)
+# Send a POST request to the /agents/deployments/prompt endpoint with a new prompt
+response = post(f'{BASE_URL}/agents/deployments/prompt', headers=get_headers(), json={
+ "deploymentId": deployment_id, # ID of the running deployment
+ "prompt": "Replace SPY for QQQ" # Follow-up prompt for the deployment
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Prompt Sent Successfully:")
+ print(result)
+
+### Read Conversation
+# Send a POST request to the /agents/deployments/conversation/read endpoint to read the transcript
+response = post(f'{BASE_URL}/agents/deployments/conversation/read', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment whose conversation to read
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the conversation
+if result['success']:
+ print("Conversation Transcript:")
+ print(result)
+
+### Stop Deployment
+# Send a POST request to the /agents/deployments/stop endpoint to stop the running deployment
+response = post(f'{BASE_URL}/agents/deployments/stop', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to stop
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Stopped Successfully:")
+ print(result)
+
+### Delete Deployment
+# Send a POST request to the /agents/deployments/delete endpoint to delete the deployment
+response = post(f'{BASE_URL}/agents/deployments/delete', headers=get_headers(), json={
+ "deploymentId": deployment_id # ID of the deployment to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Deployment Deleted Successfully:")
+ print(result)
+
+### Delete Task
+# Send a POST request to the /agents/tasks/delete endpoint to delete the task
+response = post(f'{BASE_URL}/agents/tasks/delete', headers=get_headers(), json={
+ "taskId": task_id # ID of the task to delete
+})
+# Parse the JSON response into python managable dict
+result = response.json()
+# Check if the request was successful and print the result
+if result['success']:
+ print("Task Deleted Successfully:")
+ print(result)
+ + +
+ List the deployments of an agent task. +
+ + + +
+ Id of the task whose deployments to list. The
+
+ /agents/deployments/list
+
+ API accepts requests in the following format:
+
- SearchRetrieval
+ ListAgentDeploymentsRequest
- Model - Search criteria.
+ Model - Request body for listing deployments of an agent task.
|
|
|---|---|
| - url - | -
-
- string
-
- - Input for the search. - |
-
| - score - | -
-
- number
-
- - Relevance score of the search result. - |
-
| - content - | -
-
- string
-
- - Content of the search result. - |
-
| - type + taskId |
- number
+ integer
- Type of the search result. 0=Stubs, 1=Forum, 2=Docs, 3=Examples. + Identifier of the task whose deployments to list. |
+ The
+
+ /agents/deployments/list
+
+ API provides a response in the following format:
+
- The following example demonstates searching content in QuantConnect through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API.
from base64 import b64encode @@ -93373,67 +102881,254 @@-Examples
# -------------------- -### Search Content -# Send a POST request to the /ai/tools/search endpoint to search content -response = post(f'{BASE_URL}/ai/tools/search', headers=get_headers(), json={ - "language": "Python", # Programming language to filter search results - "criteria": [ # Search criteria - { - "input": "option", # Search term (e.g., "option") - "type": "Docs", # Type of content to search (e.g., documentation) - "count": 1 # Number of results to return - } - ] +### List Agents +# Send a POST request to the /agents/list endpoint to check for an existing "My Claude" agent +response = post(f'{BASE_URL}/agents/list', headers=get_headers(), json={ + "organizationId": ORGANIZATION_ID # Organization whose agents to list }) # Parse the JSON response into python managable dict result = response.json() -# Check if the request was successful and print the search results +# Search the returned agents for one already named "My Claude" +my_claude = next((a for a in result.get('agents', []) if a['name'] == 'My Claude'), None) +# Check if the request was successful and print the list if result['success']: - print("Search Results:") - print(result)
- -
- The QuantConnect REST API lets you access your backtest reports from our cloud servers through URL endpoints. -
-- +
- Read out the report of a backtest. + Stop a running agent deployment.
@@ -93451,9 +103146,9 @@
- A JSON object containing info about the backtest to use for the report. The
+ Id of the deployment to stop. The
- /backtests/read/report
+ /agents/deployments/stop
API accepts requests in the following format:
- BacktestReportRequest
+ StopAgentDeploymentRequest
- Model - Request to read out the report of a backtest.
+ Model - Request body for stopping an agent deployment.
- integer
-
-
-
- required
-
-
-
-
-
- example: 23456789
-
-
-
-
@@ -93505,15 +103176,9 @@ Request
required
-
-
-
- example: 26c7bb06b8487cff1c7b3c44652b30f1
-
-
{
- "projectId": 23456789,
- "backtestId": "26c7bb06b8487cff1c7b3c44652b30f1"
+ "deploymentId": "string"
}
The
- /backtests/read/report
+ /agents/deployments/stop
API provides a response in the following format:
- BacktestReportGeneratingResponse
-
- Model - Backtest Report Response wrapper.
-
- boolean
-
-
- boolean
-
-
- string Array
-
-
-{
- "generating": true,
- "success": true,
- "errors": [
- "string"
- ]
-}
-
-
- BacktestReport
+ RestResponse
- Model - Backtest Report Response wrapper.
+ Model - Base API response class for the QuantConnect API.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - report - | -
-
- string
-
- - HTML data of the report with embedded base64 images. - |
- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
success
@@ -93668,7 +103255,6 @@
{
- "report": "string",
"success": true,
"errors": [
"string"
@@ -93712,7 +103298,7 @@
Responses- - - -
- The
+ Id of the deployment to delete. The
- 200 Success -
Responses+ + + +
+ The
+ + 200 Success +
Responses- - - -
- The
- - 200 Success -
Responses+ + + +
+ The
+ + 200 Success +++ 401 Authentication Error +
Examples- The following example demonstates getting a list of Lean versions through the cloud API. + The following example demonstrates listing, creating, reading, and updating an agent; creating, reading, updating, deleting, and listing agent tasks; deploying a task; and reading, prompting, stopping, and deleting a deployment through the cloud API. from base64 import b64encode @@ -94448,14 +104197,243 @@ Examples
- API ReferenceExamples
Data that will be purchased and downloaded: -┌───────────────────────────┬─────────┬────────────────────────┬────────────┬─────────┐ -│ Dataset │ Vendor │ Details │ File count │ Price │ -├───────────────────────────┼─────────┼────────────────────────┼────────────┼─────────┤ -│ Binance Crypto Price Data │ CoinAPI │ Data type: Trade │ 32 │ 800 QCC │ -│ │ │ Ticker: BTCBUSD │ │ │ -│ │ │ Resolution: Second │ │ │ -│ │ │ Start date: 2022-05-05 │ │ │ -│ │ │ End date: 2022-06-05 │ │ │ -└───────────────────────────┴─────────┴────────────────────────┴────────────┴─────────┘ -Total price: 800 QCC -Organization balance: 1,000 QCC +┌─────────────┬──────────┬────────────────────────┬────────────┬────────┐ +│ Dataset │ Vendor │ Details │ File count │ Price │ +├─────────────┼──────────┼────────────────────────┼────────────┼────────┤ +│ US Equities │ AlgoSeek │ Data type: Trade │ 3 │ 15 QCC │ +│ │ │ Ticker: SPY │ │ │ +│ │ │ Resolution: Minute │ │ │ +│ │ │ Start date: 2023-01-01 │ │ │ +│ │ │ End date: 2023-01-05 │ │ │ +└─────────────┴──────────┴────────────────────────┴────────────┴────────┘ +Total price: 15 QCC +Organization balance: 10,000 QCC Data Terms of Use has been signed previously. Find full agreement at: https://www.quantconnect.com/terms/data/?organization=<organizationId> @@ -3124,7 +3124,46 @@ $ lean data download Select a category: @@ -3147,38 +3186,37 @@
- If you add universes to your algorithm, you also need
- - For example, the following algorithm creates a universe of 100 Cryptocurrencies and then subscribes to minute resolution data for each one in the universe: - -
-
- public class CryptoDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2020, 1, 1);
- SetEndDate(2021, 1, 1);
- UniverseSettings.Asynchronous = true;
- AddUniverse(CryptoUniverse.Coinbase(universeDay => universeDay.OrderByDescending(cf => cf.VolumeInUsd).Take(100).Select(x => x.Symbol))
- );
- }
-}
- class CryptoDataAlgorithm(QCAlgorithm): - def initialize(self) -> None: - self.set_start_date(2020, 1, 1) - self.set_end_date(2021, 1, 1) - self.universe_settings.asynchronous = True - self.add_universe(CryptoUniverse.coinbase(self.universe_filter)) - - def universe_filter(self, universe_day: List[CryptoUniverse]) -> List[Symbol]: - sorted_by_dollar_volume = sorted(universe_day, key=lambda cf: (cf.volume_in_usd or 0), reverse=True) - return [cf.symbol for cf in sorted_by_dollar_volume[:100]]- - The following table shows the data cost of the preceding algorithm: - -
- The preceding table assumes you download trade and quote data, but you can run backtests with only trade data. - - - - -Crypto Future- - -- Crypto Future algorithms require data from one of the price datasets and one of the margin rate datasets. - The price datasets are available in several resolutions. - The resolution you need depends on the Crypto Future subscriptions you create in your algorithm and the resolution of data you get in - - history requests - - . - The following table describes the file format and costs of each resolution: - -
- The file format of the margin rate data is one file per Crypto Future and each file costs 100 QCC = $1 USD. - -- For example, the following algorithm subscribes to minute resolution data for one Crypto Future: - -
-
- public class CryptoFutureDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2020, 1, 1);
- SetEndDate(2021, 1, 1);
- SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
- AddCryptoFuture("BTCUSD");
- }
-}
- class CryptoFutureDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2020, 1, 1)
- self.set_end_date(2021, 1, 1)
- self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN)
- self.add_crypto_future('BTCUSD')
- - The following table shows the data cost of the preceding algorithm: - -
- The preceding table assumes you download trade and quote data, but you can run backtests with only trade data. - - - -Forex@@ -4750,7 +4350,7 @@FuturesOne file per ticker per trading day per data format. Trade, quote, and open interest data are separate files.
- 6 QCC = $0.06 USD
+ 150 QCC = $1.50 USD
|
FuturesOne file per ticker per trading day per data format. Trade, quote, and open interest data are separate files.
- 5 QCC = $0.05 USD
+ 100 QCC = $1.00 USD
|
FuturesOne file per ticker per trading day per data format. Trade, quote, and open interest data are separate files.
- 5 QCC = $0.05 USD
+ 50 QCC = $0.50 USD
|
FuturesOne file per ticker per data format. Trade, quote, and open interest data are separate files.
- 300 QCC = $3 USD
+ 1500 QCC = $15 USD
|
FuturesOne file per ticker per data format. Trade, quote, and open interest data are separate files.
- 100 QCC = $1 USD
+ 1500 QCC = $15 USD
|
Futures= 756 files- 756 files @ 5 QCC/file + 756 files @ 50 QCC/file - => 756 * 5 QCC + => 756 * 50 QCC - = 3,780 QCC + = 37,800 QCC - = $37.80 USD + = $378 USD
1 ticker with 3 data formats
@@ -4928,11 +4528,11 @@ |
@@ -37422,7 +37022,7 @@ Futures=> 3 files/day- 3 file/day @ 5 QCC/file + 3 file/day @ 50 QCC/file - => 15 QCC/day + => 150 QCC/day - = $0.15 USD/day + = $1.50 USD/day Options
|
- --bybit-use-testnet <enum: live|paper>
+ --bybit-use-testnet <enum: live|paper|demo>
@@ -46024,7 +45624,7 @@ | Options
|
- --bybit-use-testnet <enum: live|paper>
+ --bybit-use-testnet <enum: live|paper|demo>
diff --git a/single-page/Quantconnect-Local-Platform.html b/single-page/Quantconnect-Local-Platform.html
index 92ba1b958e..5d7f650181 100644
--- a/single-page/Quantconnect-Local-Platform.html
+++ b/single-page/Quantconnect-Local-Platform.html
@@ -5141,7 +5141,11 @@ |
the data providers we support in the cloud
- . Your live algorithms run on our co-located servers that have 10 GB transfer speeds and low latency.
+ . Your live algorithms run on our co-located servers racked in
+
+ Equinix
+
+ that have 10 GB transfer speeds and low latency.
@@ -8530,8 +8534,10 @@ #load "../QuantConnect.csx" -using QuantConnect; +#load "../QuantConnect.csx"+ using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; diff --git a/single-page/Quantconnect-Research-Environment.html b/single-page/Quantconnect-Research-Environment.html index 8d40b9665c..a2f0d1a6c3 100644 --- a/single-page/Quantconnect-Research-Environment.html +++ b/single-page/Quantconnect-Research-Environment.html @@ -105,7 +105,8 @@ Examplebbdf[['price', 'lowerband', 'middleband', 'upperband']].plot();#load "../QuantConnect.csx" -using QuantConnect; +#load "../QuantConnect.csx"+ using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -915,8 +918,8 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - -#load "../QuantConnect.csx" -using QuantConnect; +#load "../Initialize.csx"+ // Load the necessary assembly files. +#load "../QuantConnect.csx"+ using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; using QuantConnect.Data.Consolidators; @@ -6151,13 +6158,17 @@ |
- Mixed, earliest starts May 2002 + July 2017 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - 51 Contracts + 3,320 Currency Pairs | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Tick, Second, Minute, Hour, & Daily + Tick, Second, Minute, Hourly, & Daily | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Mixed, in which the contract is listed* + UTC | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
-
+
Always Open
- , except from Friday 5 PM EST to Sunday 5 PM EST.
- - Index CFDs depends on the underlying market hour* |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -10244,8 +10255,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -10420,7 +10435,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -10463,10 +10478,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -10476,9 +10497,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -10529,7 +10549,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -10608,13 +10628,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -11163,10 +11187,11 @@Plot Data
package.-+#r "../Plotly.NET.dll" -#r "../Plotly.NET.Interactive.dll" - -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++@@ -11256,7 +11281,7 @@using Plotly.NET; using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;Plot Data
plt.show()-HTML(GenericChart.toChartHTML(chart))+display(chart)Line charts display the value of the property you selected in a time series. @@ -11281,18 +11306,23 @@
+// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -using QuantConnect; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Fundamental; using QuantConnect.Algorithm; using QuantConnect.Research; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -11331,7 +11361,7 @@+display(chart)chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Create a QuantBook qb = QuantBook() @@ -11612,13 +11642,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -11881,10 +11915,16 @@
+// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using System; using System.Collections.Generic; using QuantConnect; using QuantConnect.Data; @@ -11893,9 +11933,8 @@+display(chart)using QuantConnect.Algorithm; using QuantConnect.Research; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -11946,7 +11985,7 @@
chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Instantiate a QuantBook instance. qb = QuantBook() # Set the date being studied. @@ -12139,13 +12178,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -12759,10 +12802,13 @@-xaxis_rangeslider_visible=False ) ).show()
#load "../QuantConnect.csx" -#r "../Plotly.NET.dll" - -using QuantConnect; +// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -12770,6 +12816,7 @@+display(chart)using QuantConnect.Data.Market; using QuantConnect.Securities.Option; using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Get the SPY Option chain for January 1, 2024. @@ -12781,10 +12828,10 @@
// Select a contract from the chain. var expiry = chain.Select(contract => contract.Expiry).Min(); var contractSymbol = chain - .Where(contract => - contract.Expiry == expiry && + .Where(contract => + contract.Expiry == expiry && contract.Right == OptionRight.Call && - contract.Greeks.Delta > 0.3m && + contract.Greeks.Delta > 0.3m && contract.Greeks.Delta < 0.7m ) .OrderByDescending(contract => contract.OpenInterest) @@ -12815,7 +12862,7 @@
layout.SetValue("yaxis", yAxis); layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart))
#load "../QuantConnect.csx" -#r "../Plotly.NET.dll" - -using QuantConnect; +// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -12870,6 +12920,7 @@using QuantConnect.Data.Market; using QuantConnect.Securities.Option; using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Get the TSLA Option chain for January 1, 2024. @@ -12909,7 +12960,7 @@
layout.SetValue("yaxis", yAxis); layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart)) +display(chart)
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -13017,8 +13072,8 @@Create Subscriptions
Supported Assets section of the - - CoinAPI dataset listings + + QuantConnect dataset listings . @@ -16236,8 +16291,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -16426,7 +16485,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -16451,10 +16510,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -16464,9 +16529,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -16517,7 +16581,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -16592,13 +16656,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -19877,8 +19945,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -20067,7 +20139,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -20092,10 +20164,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -20105,9 +20183,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -20158,7 +20235,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -20520,13 +20597,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -22235,10 +22316,16 @@
+// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -22248,9 +22335,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -22306,7 +22392,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -22394,13 +22480,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -22981,18 +23071,21 @@
#load "../Initialize.csx"
#r "../Plotly.NET.dll" -using Plotly.NET; -using Plotly.NET.LayoutObjects;+
// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"
#load "../QuantConnect.csx" -using QuantConnect; +using QuantConnect; using QuantConnect.Data; using QuantConnect.Research; using QuantConnect.Securities; using QuantConnect.Data.Market; - +using Plotly.NET; +using Plotly.NET.Interactive; +using Plotly.NET.LayoutObjects; + var qb = new QuantBook(); // Get the front-month ES contract as of December 31, 2021. var future = qb.AddFuture(Futures.Indices.SP500EMini); @@ -23021,7 +23114,7 @@+display(chart)layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart))
#load "../Initialize.csx"
#r "../Plotly.NET.dll" -using Plotly.NET; -using Plotly.NET.LayoutObjects;+
// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"
#load "../QuantConnect.csx" -using QuantConnect; +using QuantConnect; using QuantConnect.Data; using QuantConnect.Research; using QuantConnect.Securities; using QuantConnect.Data.Market; - +using Plotly.NET; +using Plotly.NET.Interactive; +using Plotly.NET.LayoutObjects; + var qb = new QuantBook(); // Get the front-month ES contract as of December 31, 2021. var future = qb.AddFuture(Futures.Indices.SP500EMini); @@ -23100,7 +23196,7 @@+display(chart)layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart))
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -24029,10 +24129,16 @@
+// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using System; using System.Collections.Generic; using QuantConnect; using QuantConnect.Data; @@ -24041,9 +24147,8 @@+display(chart)using QuantConnect.Algorithm; using QuantConnect.Research; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -24098,7 +24203,7 @@
chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Instantiate a QuantBook instance. qb = QuantBook() # Set the date being studied. @@ -24164,13 +24269,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -24771,10 +24880,13 @@-xaxis_rangeslider_visible=False ) ).show()
#load "../QuantConnect.csx" -#r "../Plotly.NET.dll" - -using QuantConnect; +// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -24782,6 +24894,7 @@+display(chart)using QuantConnect.Data.Market; using QuantConnect.Securities; using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Add the underlying Future contract @@ -24829,7 +24942,7 @@
layout.SetValue("yaxis", yAxis); layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart))
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -27761,8 +27878,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -27951,7 +28072,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -27976,10 +28097,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -27989,9 +28116,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -28042,7 +28168,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -28117,13 +28243,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -31011,8 +31141,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -31201,7 +31335,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -31226,10 +31360,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -31239,9 +31379,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -31292,7 +31431,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -31367,13 +31506,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -33633,8 +33776,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the security. @@ -33823,7 +33970,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -33848,10 +33995,16 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using System; using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; @@ -33861,9 +34014,8 @@+display(chart)using QuantConnect.Research; using QuantConnect.Securities; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -33914,7 +34066,7 @@
// Assign the Layout to the chart. chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting. import plotly.graph_objects as go @@ -34198,13 +34350,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -34483,10 +34639,16 @@
+// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -using System; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using System; using System.Collections.Generic; using QuantConnect; using QuantConnect.Data; @@ -34495,9 +34657,8 @@+display(chart)using QuantConnect.Algorithm; using QuantConnect.Research; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -34549,7 +34710,7 @@
chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Instantiate a QuantBook instance. qb = QuantBook() # Set the date being studied. @@ -34744,13 +34905,17 @@Create Subscriptions
#load "../Initialize.csx"
#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -35383,10 +35548,13 @@-xaxis_rangeslider_visible=False ) ).show()
#load "../QuantConnect.csx" -#r "../Plotly.NET.dll" - -using QuantConnect; +// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -35394,6 +35562,7 @@+display(chart)using QuantConnect.Data.Market; using QuantConnect.Securities.Option; using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Get the SPX Option chain for January 1, 2024. @@ -35441,7 +35610,7 @@
layout.SetValue("yaxis", yAxis); layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart))
#load "../QuantConnect.csx" -#r "../Plotly.NET.dll" - -using QuantConnect; +// Load the necessary assembly files. +#load "../QuantConnect.csx" +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -35498,6 +35670,7 @@using QuantConnect.Data.Market; using QuantConnect.Securities.Option; using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Get the VIX weekly Option chain for January 1, 2024. @@ -35539,7 +35712,7 @@
layout.SetValue("yaxis", yAxis); layout.SetValue("title", title); chart.WithLayout(layout); -HTML(GenericChart.toChartHTML(chart)) +display(chart)
#load "../Initialize.csx" -#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#load "../Initialize.csx"+
#load "../QuantConnect.csx" +#r "../Microsoft.Data.Analysis.dll"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -37293,8 +37469,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;
fig.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Candlestick charts display the open, high, low, and close prices of the alternative data. @@ -37483,7 +37663,7 @@
plt.show()-
HTML(GenericChart.toChartHTML(chart))+
display(chart)
Line charts display the value of the property you selected in a time series. @@ -37508,18 +37688,23 @@
// Load the required assembly files and data types in a separate cell. -#load "../Initialize.csx" - +#load "../Initialize.csx"+
// Load the necessary assembly files. #load "../QuantConnect.csx" -using QuantConnect; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+
using QuantConnect; using QuantConnect.Data; using QuantConnect.DataSource; using QuantConnect.Algorithm; using QuantConnect.Research; -// Import Plotly for plotting. -#r "../Plotly.NET.dll" using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; // Create a QuantBook. @@ -37558,7 +37743,7 @@+display(chart)chart.WithLayout(layout); // Display the plot. -HTML(GenericChart.toChartHTML(chart))
# Create a QuantBook qb = QuantBook() @@ -37623,11 +37808,14 @@+display(chart);Define Custom Data
methods.-+#load "../Initialize.csx" -#load "../QuantConnect.csx" -#r "../Microsoft.Data.Analysis.dll" - -using QuantConnect; +#load "../Initialize.csx"+++#load "../QuantConnect.csx" +#r "../Microsoft.Data.Analysis.dll"++using QuantConnect; using QuantConnect.Data; using QuantConnect.Algorithm; using QuantConnect.Research; @@ -38168,8 +38356,12 @@
+import plotly.graph_objects as go-#r "../Plotly.NET.dll" -using Plotly.NET; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++using Plotly.NET; +using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects;@@ -38250,7 +38442,7 @@
fig.show()-HTML(GenericChart.toChartHTML(chart))+display(chart)Candlestick charts display the open, high, low, and close prices of the security. @@ -38344,7 +38536,7 @@
plt.show()-HTML(GenericChart.toChartHTML(chart))+display(chart)Line charts display the value of the property you selected in a time series. @@ -39968,21 +40160,23 @@
+// Load the assembly files and data types in their own cell. -#load "../Initialize.csx" - -// Load the necessary assembly files. +#load "../Initialize.csx"+++// Load the necessary assembly files. #load "../QuantConnect.csx" -#r "../Plotly.NET.dll" -#r "../Plotly.NET.Interactive.dll" - -// Import the QuantConnect, Plotly.NET, and Accord packages for calculation and plotting. +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"++@@ -40054,7 +40248,7 @@// Import the QuantConnect, Plotly.NET, and Accord packages for calculation and plotting. using QuantConnect; using QuantConnect.Research; - + using Plotly.NET; using Plotly.NET.Interactive; using Plotly.NET.LayoutObjects; - + using Accord.Math; using Accord.Statistics;Create Candlestick Chart
chart.WithLayout(layout); // Show the plot. -HTML(GenericChart.toChartHTML(chart)); +display(chart);The Jupyter Notebook displays the candlestick chart. @@ -40103,7 +40297,7 @@
Create Line Chart
chart.WithLayout(layout); // Show the plot. -HTML(GenericChart.toChartHTML(chart));
The Jupyter Notebook displays the line chart. @@ -40152,7 +40346,7 @@
The Jupyter Notebook displays the scatter plot. @@ -40213,7 +40407,7 @@
The Jupyter Notebook displays the heat map. @@ -40268,7 +40462,7 @@
The Jupyter Notebook displays the scatter plot. @@ -40486,8 +40680,8 @@
Fundamental
- in the preceding code snippets with the universe data type.
- The following table shows the datasets that support universe selection and their respective data type.
+ in the preceding code snippets with the universe data type.
+ The following table shows the datasets that support universe selection and their respective data type.
For more information, about universe selection with these datasets and the data points you can use in the filter function, see the dataset's documentation.
| + Binance Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + Binance US Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + Bitfinex Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + Bybit Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + Coinbase Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
International Future Universe
@@ -40529,6 +40798,21 @@ Available Universes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + Kraken Crypto Price Data + | +
+
+ CryptoUniverse
+
+ |
+ + + Learn more + + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
US ETF Constituents
@@ -40640,96 +40924,6 @@ Available Universes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Binance Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Binance US Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Bitfinex Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Bybit Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Coinbase Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Kraken Crypto Price Data - | -
-
- CryptoUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Brain Language Metrics on Company Filings
@@ -40865,21 +41059,6 @@ Available Universes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - WallStreetBets - | -
-
- QuiverWallStreetBetsUniverse
-
- |
- - - Learn more - - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Corporate Buybacks
@@ -40940,10 +41119,16 @@
// Load the required assembly files and data types. -#load "../Initialize.csx" +#load "../Initialize.csx"+ // Load the necessary assembly files. #load "../QuantConnect.csx" - -using QuantConnect; +#r "nuget: Plotly.NET" +#r "nuget: Plotly.NET.Interactive"+ using QuantConnect; using QuantConnect.Data; using QuantConnect.Data.Market; using QuantConnect.Algorithm; @@ -41034,7 +41219,7 @@+display(chart) # Instantiate the QuantBook instance for researching. qb = QuantBook() @@ -41468,14 +41653,16 @@ |
+ Market.CBOE
+
+ Market.CBOE
+
method. For more information about the specific datasets we use for backtests, see the
-
- CoinAPI datasets
+
+ QuantConnect datasets
. To trade Crypto live, you can use the
@@ -27997,8 +28728,8 @@ Create SubscriptionsTo view the supported assets, see the - - CoinAPI datasets + + QuantConnect datasets . @@ -29689,7 +30420,7 @@Create SubscriptionsTo view the supported assets in the Crypto Futures dataset, see - + Supported Assets . @@ -31331,7 +32062,7 @@ Create SubscriptionsTo view the supported Forex pairs, see - + Supported Assets . @@ -92374,6 +93105,395 @@ Time Zone], "earlyCloses": {} }, + "Index-cboe-[*]": { + "exchangeTimeZone": "America/Chicago", + "monday": [ + { + "start": "08:30:00", + "end": "15:15:00", + "state": "market" + } + ], + "tuesday": [ + { + "start": "08:30:00", + "end": "15:15:00", + "state": "market" + } + ], + "wednesday": [ + { + "start": "08:30:00", + "end": "15:15:00", + "state": "market" + } + ], + "thursday": [ + { + "start": "08:30:00", + "end": "15:15:00", + "state": "market" + } + ], + "friday": [ + { + "start": "08:30:00", + "end": "15:15:00", + "state": "market" + } + ], + "holidays": [ + "1/1/1998", + "1/1/1999", + "1/1/2001", + "1/1/2002", + "1/1/2003", + "1/1/2004", + "1/2/2006", + "1/1/2007", + "1/1/2008", + "1/1/2009", + "1/1/2010", + "1/1/2011", + "1/2/2012", + "1/1/2013", + "1/1/2014", + "1/1/2015", + "1/1/2016", + "1/2/2017", + "1/1/2018", + "1/1/2019", + "1/1/2020", + "1/1/2021", + "1/1/2022", + "1/1/2024", + "1/1/2025", + "1/1/2026", + "1/1/2027", + "1/2/2023", + "1/2/2007", + "1/9/2025", + "1/19/1998", + "1/18/1999", + "1/17/2000", + "1/15/2001", + "1/21/2002", + "1/20/2003", + "1/19/2004", + "1/17/2005", + "1/16/2006", + "1/15/2007", + "1/21/2008", + "1/19/2009", + "1/18/2010", + "1/17/2011", + "1/16/2012", + "1/21/2013", + "1/20/2014", + "1/19/2015", + "1/18/2016", + "1/16/2017", + "1/15/2018", + "1/21/2019", + "1/20/2020", + "1/18/2021", + "1/17/2022", + "1/16/2023", + "1/15/2024", + "1/20/2025", + "1/19/2026", + "1/18/2027", + "2/16/1998", + "2/15/1999", + "2/21/2000", + "2/19/2001", + "2/18/2002", + "2/17/2003", + "2/16/2004", + "2/21/2005", + "2/20/2006", + "2/19/2007", + "2/18/2008", + "2/16/2009", + "2/15/2010", + "2/21/2011", + "2/20/2012", + "2/18/2013", + "2/17/2014", + "2/16/2015", + "2/15/2016", + "2/20/2017", + "2/19/2018", + "2/18/2019", + "2/17/2020", + "2/15/2021", + "2/21/2022", + "2/20/2023", + "2/19/2024", + "2/17/2025", + "2/16/2026", + "2/15/2027", + "4/10/1998", + "4/2/1999", + "4/21/2000", + "4/13/2001", + "3/29/2002", + "4/18/2003", + "4/9/2004", + "3/25/2005", + "4/14/2006", + "4/6/2007", + "3/21/2008", + "4/10/2009", + "4/2/2010", + "4/22/2011", + "4/6/2012", + "3/29/2013", + "4/18/2014", + "4/3/2015", + "3/25/2016", + "4/14/2017", + "3/30/2018", + "4/19/2019", + "4/10/2020", + "4/2/2021", + "4/15/2022", + "4/7/2023", + "3/29/2024", + "4/18/2025", + "4/3/2026", + "3/26/2027", + "5/25/1998", + "5/31/1999", + "5/29/2000", + "5/28/2001", + "5/27/2002", + "5/26/2003", + "5/31/2004", + "5/30/2005", + "5/29/2006", + "5/28/2007", + "5/26/2008", + "5/25/2009", + "5/31/2010", + "5/30/2011", + "5/28/2012", + "5/27/2013", + "5/26/2014", + "5/25/2015", + "5/30/2016", + "5/29/2017", + "5/28/2018", + "5/27/2019", + "5/25/2020", + "5/31/2021", + "5/30/2022", + "5/29/2023", + "5/27/2024", + "5/26/2025", + "5/25/2026", + "5/31/2027", + "6/11/2004", + "6/20/2022", + "6/19/2023", + "6/19/2024", + "6/19/2025", + "6/19/2026", + "6/18/2027", + "7/3/1998", + "7/5/1999", + "7/4/2000", + "7/4/2001", + "7/4/2002", + "7/4/2003", + "7/5/2004", + "7/4/2005", + "7/4/2006", + "7/4/2007", + "7/4/2008", + "7/3/2009", + "7/5/2010", + "7/4/2011", + "7/4/2012", + "7/4/2013", + "7/4/2014", + "7/3/2015", + "7/4/2016", + "7/4/2017", + "7/4/2018", + "7/4/2019", + "7/3/2020", + "7/5/2021", + "7/4/2022", + "7/4/2023", + "7/4/2024", + "7/4/2025", + "7/3/2026", + "7/5/2027", + "9/7/1998", + "9/6/1999", + "9/4/2000", + "9/3/2001", + "9/2/2002", + "9/1/2003", + "9/6/2004", + "9/5/2005", + "9/4/2006", + "9/3/2007", + "9/1/2008", + "9/7/2009", + "9/6/2010", + "9/5/2011", + "9/3/2012", + "9/2/2013", + "9/1/2014", + "9/7/2015", + "9/5/2016", + "9/4/2017", + "9/3/2018", + "9/2/2019", + "9/7/2020", + "9/6/2021", + "9/5/2022", + "9/4/2023", + "9/2/2024", + "9/1/2025", + "9/7/2026", + "9/6/2027", + "9/11/2001", + "9/12/2001", + "9/13/2001", + "9/14/2001", + "10/29/2012", + "10/30/2012", + "11/26/1998", + "11/25/1999", + "11/23/2000", + "11/22/2001", + "11/28/2002", + "11/27/2003", + "11/25/2004", + "11/24/2005", + "11/23/2006", + "11/22/2007", + "11/27/2008", + "11/26/2009", + "11/25/2010", + "11/24/2011", + "11/22/2012", + "11/28/2013", + "11/27/2014", + "11/26/2015", + "11/24/2016", + "11/23/2017", + "11/22/2018", + "11/28/2019", + "11/26/2020", + "11/25/2021", + "11/24/2022", + "11/23/2023", + "11/28/2024", + "11/27/2025", + "11/26/2026", + "11/25/2027", + "12/05/2018", + "12/25/1998", + "12/24/1999", + "12/25/2000", + "12/25/2001", + "12/25/2002", + "12/25/2003", + "12/24/2004", + "12/26/2005", + "12/25/2006", + "12/25/2007", + "12/25/2008", + "12/25/2009", + "12/24/2010", + "12/26/2011", + "12/25/2012", + "12/25/2013", + "12/25/2014", + "12/25/2015", + "12/26/2016", + "12/25/2017", + "12/25/2018", + "12/25/2019", + "12/25/2020", + "12/24/2021", + "12/26/2022", + "12/25/2023", + "12/25/2024", + "12/25/2025", + "12/25/2026", + "12/24/2027" + ], + "earlyCloses": { + "7/3/2000": "12:00:00", + "7/3/2001": "12:00:00", + "7/5/2002": "12:00:00", + "7/3/2003": "12:00:00", + "7/3/2006": "12:00:00", + "7/3/2007": "12:00:00", + "7/3/2008": "12:00:00", + "7/3/2012": "12:00:00", + "7/3/2013": "12:00:00", + "7/3/2014": "12:00:00", + "7/3/2017": "12:00:00", + "7/3/2018": "12:00:00", + "7/3/2019": "12:00:00", + "7/3/2023": "12:00:00", + "7/3/2024": "12:00:00", + "7/3/2025": "12:00:00", + "11/26/1999": "12:00:00", + "11/24/2000": "12:00:00", + "11/23/2001": "12:00:00", + "11/29/2002": "12:00:00", + "11/28/2003": "12:00:00", + "11/26/2004": "12:00:00", + "11/25/2005": "12:00:00", + "11/24/2006": "12:00:00", + "11/23/2007": "12:00:00", + "11/28/2008": "12:00:00", + "11/27/2009": "12:00:00", + "11/26/2010": "12:00:00", + "11/25/2011": "12:00:00", + "11/23/2012": "12:00:00", + "11/29/2013": "12:00:00", + "11/28/2014": "12:00:00", + "11/27/2015": "12:00:00", + "11/25/2016": "12:00:00", + "11/24/2017": "12:00:00", + "11/23/2018": "12:00:00", + "11/29/2019": "12:00:00", + "11/27/2020": "12:00:00", + "11/26/2021": "12:00:00", + "11/25/2022": "12:00:00", + "11/24/2023": "12:00:00", + "11/29/2024": "12:00:00", + "11/28/2025": "12:00:00", + "11/27/2026": "12:00:00", + "11/26/2027": "12:00:00", + "12/24/2001": "12:00:00", + "12/24/2002": "12:00:00", + "12/24/2003": "12:00:00", + "12/26/2003": "12:00:00", + "12/24/2007": "12:00:00", + "12/24/2008": "12:00:00", + "12/24/2009": "12:00:00", + "12/24/2012": "12:00:00", + "12/24/2013": "12:00:00", + "12/24/2014": "12:00:00", + "12/24/2015": "12:00:00", + "12/24/2017": "12:00:00", + "12/24/2018": "12:00:00", + "12/24/2019": "12:00:00", + "12/24/2020": "12:00:00", + "12/24/2024": "12:00:00", + "12/24/2025": "12:00:00", + "12/24/2026": "12:00:00" + } + }, "Future-cme-MES": { "exchangeTimeZone": "America/New_York", "sunday": [ @@ -113685,7 +114805,7 @@Create SubscriptionsTo view the supported assets in the US Cash Indices dataset, see the - + Supported Indices . @@ -129078,7 +130198,7 @@ OANDA SubscriptionsTo view the supported CFD contracts, see - + Supported Assets . For more information about the specific dataset we use for backtests, see the @@ -148814,6 +149934,58 @@ ScheduleTrigger an event on the last tradable date of each week for a specific symbol minus an offset. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_start(days_offset: int = 0)
+
+
+ DateRules.QuarterStart(int daysOffset = 0)
+
+ |
+ + Trigger an event on the first day of each quarter plus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterStart(Symbol symbol, int daysOffset = 0)
+
+ |
+ + Trigger an event on the first tradable date of each quarter for a specific symbol plus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_end(days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(int daysOffset = 0)
+
+ |
+ + Trigger an event on the last day of each quarter minus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(Symbol symbol, int daysOffset = 0)
+
+ |
+ + Trigger an event on the last tradable date of each quarter for a specific symbol minus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -150008,6 +151180,166 @@
|
- + Example | @@ -159345,7 +161047,7 @@- + Example | @@ -159374,7 +161076,7 @@- + Example | @@ -159403,7 +161105,7 @@- + Example | @@ -159432,7 +161134,7 @@- + Example | @@ -159461,7 +161163,7 @@- + Example | @@ -159920,6 +161622,134 @@||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_start(days_offset: int = 0)
+
+
+ DateRules.QuarterStart(int daysOffset = 0)
+
+ |
+ + Trigger an event on the first day of each quarter plus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterStart(Symbol symbol, int daysOffset = 0)
+
+ |
+ + Trigger an event on the first tradable date of each quarter for a specific symbol plus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_end(days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(int daysOffset = 0)
+
+ |
+ + Trigger an event on the last day of each quarter minus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+ self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(Symbol symbol, int daysOffset = 0)
+
+ |
+ + Trigger an event on the last tradable date of each quarter for a specific symbol minus an offset. + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -161904,8 +163786,52 @@ |
- 631 Crypto Futures Pairs + 718 Crypto Futures Pairs | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Regular + Dense | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Daily + Tick, Second, Minute, Hourly, & Daily | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Pairs Available (631) + Pairs Available (718) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - 1CATUSDT + 0GUSDT + | ++ 1000000BOBUSDT + | ++ 1000000MOGUSDT + | ++ 1000BONKUSDC + | ++ 1000BONKUSDT + | ++ 1000CATUSDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + 1000CHEEMSUSDT + | ++ 1000FLOKIUSDT + | ++ 1000LUNCBUSD + | ++ 1000LUNCUSDT + | ++ 1000PEPEUSDC + | ++ 1000PEPEUSDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + 1000RATSUSDT + | ++ 1000SATSUSDT + | ++ 1000SHIBBUSD + | ++ 1000SHIBUSDC + | ++ 1000SHIBUSDT + | ++ 1000WHYUSDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + 1000XECUSDT + | ++ 1000XUSDT | 1INCHUSDT | - A8USDT + 1MBABYDOGEUSDT + | ++ 2ZUSDT + | ++ 4USDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + A2ZUSDT | AAVEUSD | ++ AAVEUSDC + | AAVEUSDT | ACEUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ACHUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ACTUSDT | ACXUSDT | ++ ADABUSD + | ADAUSD | - ADAUSDT + ADAUSDC | - AERGOUSDT + ADAUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + AERGOUSDT + | AEROUSDT | @@ -165580,7 +167697,7 @@- AGIUSDT + AGIXBUSD |
AGIXUSDT
@@ -165588,17 +167705,28 @@ Supported Assets | AGLDUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + AGTUSDT + | AI16ZUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - AIDOGEUSDT + AIAUSDT | - AIOZUSDT + AINUSDT + | ++ AIOTUSDT + | ++ AIOUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AIUSDT | @@ -165606,62 +167734,79 @@- AKROUSDT + AKEUSDT | AKTUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ALCHUSDT | - ALEOUSDT + ALGOUSD | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ALGOUSDT | ALICEUSDT | ++ ALLUSDT + | ALPACAUSDT | ALPHAUSDT | ++ ALPINEUSDT + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ALTUSDT | - ALUUSDT + AMBBUSD | AMBUSDT | ++ ANCBUSD + | ANIMEUSDT | ANKRUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ANTUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - APEUSDT + APEBUSD | - APEXUSDT + APEUSD + | ++ APEUSDT | API3USDT | ++ APTBUSD + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| APTUSD | @@ -165669,16 +167814,19 @@- APUUSDT + ARBUSDC | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ARBUSDT | ARCUSDT | ++ ARIAUSDT + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ARKMUSDT | @@ -165691,6 +167839,12 @@ARUSDT | ++ ASRUSDT + | ++ ASTERUSDT + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -165702,48 +167856,68 @@ Supported Assets | ATHUSDT | ++ ATOMUSD + | ATOMUSDT | ++ AUCTIONBUSD + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AUCTIONUSDT | AUDIOUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - AVAAIUSDT + AUSDT | - AVAILUSDT + AVAAIUSDT | AVAUSDT | ++ AVAXBUSD + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AVAXUSD | ++ AVAXUSDC + | AVAXUSDT | - AVLUSDT + AVNTUSDT + | ++ AWEUSDT + | ++ AXLUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - AXLUSDT + AXSUSD | AXSUSDT | - B3USDT + B2USDT | - BABYDOGEUSDT + B3USDT |
BABYUSDT
@@ -165776,6 +167950,12 @@ Supported Assets | BANUSDT | ++ BARDUSDT + | ++ BASUSDT + | BATUSDT | @@ -165785,45 +167965,53 @@BCHUSD | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - BCHUSDT + BCHUSDC | - BEAMUSDT + BCHUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - BEERUSDT + BDXNUSDT | - BELUSDT + BEAMXUSDT | - BENDOGUSDT + BELUSDT | BERAUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BICOUSDT | ++ BIDUSDT + | BIGTIMEUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - BILLYUSDT + BIOUSDC | BIOUSDT | - BLASTUSDT + BLESSUSDT + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + BLUAIUSDT | - BLUEUSDT + BLUEBIRDUSDT |
BLURUSDT
@@ -165831,10 +168019,19 @@ Supported Assets | BLZUSDT | ++ BMTUSDT + | ++ BNBBUSD + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - BMTUSDT + BNBUSD + | ++ BNBUSDC |
BNBUSDT
@@ -165846,50 +168043,67 @@ Supported AssetsBNXUSDT |
- BOBAUSDT + BOMEUSDC | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BOMEUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BONDUSDT | - BONKUSDT + BRETTUSDT | - BRETTUSDT + BROCCOLI714USDT | - BROCCOLIUSDT + BROCCOLIF3BUSDT | BRUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BSVUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BSWUSDT | ++ BTCBUSD + | ++ BTCDOMUSDT + | ++ BTCSTUSDT + | BTCUSD | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + BTCUSDC + | BTCUSDT | - BTTUSDT + BTRUSDT | - BUSDUSDT + BTSUSDT | - BUZZUSDT + BULLAUSDT + | ++ BUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CATSUSDT + CELOUSDT | - CATUSDT + CELRUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CEEKUSDT + CETUSUSDT | - CELOUSDT + CFXUSDT | - CELRUSDT + CGPTUSDT | - CETUSUSDT + CHESSUSDT | - CFXUSDT + CHILLGUYUSDT | - CGPTUSDT + CHRUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CHEEMSUSDT + CHZUSD | - CHESSUSDT + CHZUSDT | - CHILLGUYUSDT + CKBUSDT | - CHRUSDT + CLOUSDT | - CHZUSDT + COAIUSDT | - CKBUSDT + COCOSUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CLANKERUSDT + COMBOUSDT | - CLOUDUSDT + COMPUSDT | - COMBOUSDT + COOKIEUSDT | - COMPUSDT + COSUSDT | - COOKIEUSDT + COTIUSDT | - COOKUSDT + COWUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - COQUSDT + CROSSUSDT | - COREUSDT + CRVUSDC | - COSUSDT + CRVUSDT | - COTIUSDT + CTKUSDT | - COVALUSDT + CTSIUSDT | - COWUSDT + CUDISUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CPOOLUSDT + CUSDT | - CROUSDT + CVCUSDT | - CRVUSDT + CVXBUSD | - CTCUSDT + CVXUSDT | - CTKUSDT + CYBERUSDT | - CTSIUSDT + DAMUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - CVCUSDT + DARUSDT | - CVXUSDT + DASHUSDT | - CYBERUSDT + DEEPUSDT | - DAOUSDT + DEFIUSDT | - DARKUSDT + DEGENUSDT | - DARUSDT + DEGOUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - DASHUSDT + DENTUSDT | - DATAUSDT + DEXEUSDT | - DBRUSDT + DFUSDT | - DEEPUSDT + DGBUSDT | - DEGENUSDT + DIAUSDT | - DENTUSDT + DMCUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - DEXEUSDT + DODOBUSD | - DGBUSDT + DODOXUSDT | - DODOUSDT + DOGEBUSD | DOGEUSD | - DOGEUSDT + DOGEUSDC | - DOGSUSDT + DOGEUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - DOGUSDT + DOGSUSD + | ++ DOGSUSDT + | ++ DOLOUSDT | DOODUSDT | - DOP1USDT + DOTBUSD | DOTUSD | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DOTUSDT | DRIFTUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - DUCKUSDT + DUSDT |
DUSKUSDT
@@ -166105,37 +168325,48 @@ Supported Assets | DYMUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + EDENUSDT + | EDUUSDT | - EGLDUSDT + EGLDUSD | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - EIGENUSDT + EGLDUSDT | - ELONUSDT + EIGENUSDT | - ELXUSDT + ENAUSDC | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENAUSDT | ENJUSDT | ++ ENSOUSDT + | ++ ENSUSD + | ENSUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EOSUSD | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EOSUSDT | @@ -166146,22 +168377,42 @@- ETCUSD + ERAUSDT | - ETCUSDT + ESPORTSUSDT + | ++ ETCBUSD | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - ETHBTCUSDT + ETCUSD + | ++ ETCUSDT + | ++ ETHBTC + | ++ ETHBUSD + | ++ ETHFIUSDC | ETHFIUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ETHUSD | ++ ETHUSDC + | ETHUSDT | @@ -166169,18 +168420,21 @@- FARTCOINUSDT + EULUSDT + | ++ EVAAUSDT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - FBUSDT + FARTCOINUSDT | - FDUSDUSDT + FETUSDT | - FETUSDT + FFUSDT |
FHEUSDT
@@ -166189,139 +168443,136 @@ Supported AssetsFIDAUSDT |
- FILUSD + FILBUSD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - FILUSDT + FILUSD | - FIOUSDT + FILUSDC | - FIREUSDT + FILUSDT | - FITFIUSDT + FIOUSDT | - FLMUSDT + FISUSDT | - FLOCKUSDT + FLMUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - FLOKIUSDT + FLOCKUSDT | FLOWUSDT | - FLRUSDT + FLUIDUSDT | FLUXUSDT | - FORMUSDT + FOOTBALLUSDT | - FORTHUSDT + FORMUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - FOXYUSDT + FORTHUSDT | FRONTUSDT | - FTMUSDT + FTMBUSD | - FTNUSDT + FTMUSD | - FUELUSDT + FTMUSDT | - FUNUSDT + FTTBUSD | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - FUSDT + FTTUSDT | - FWOGUSDT + FUNUSDT | - FXSUSDT + FUSDT | - GALAUSDT + FXSUSDT | - GALUSDT + GALABUSD | - GASUSDT + GALAUSD | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - GEMSUSDT + GALAUSDT | - GFTUSDT + GALBUSD | - GIGAUSDT + GALUSDT | - GLMRUSDT + GASUSDT | - GLMUSDT + GHSTUSDT | - GMEUSDT + GIGGLEUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - GMTUSDT + GLMRUSDT | - GMXUSDT + GLMUSDT | - GNOUSDT + GMTBUSD | - GOATUSDT + GMTUSD | - GODSUSDT + GMTUSDT | - GOMININGUSDT + GMXUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - GORKUSDT + GOATUSDT | GPSUSDT | -- GPTUSDT - | GRASSUSDT | @@ -166331,11 +168582,11 @@GRTUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GTCUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GUNUSDT | @@ -166346,13 +168597,22 @@- HBARUSDT + HANAUSDT | - HEIUSDT + HBARUSDC + | ++ HBARUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + HEIUSDT + | ++ HEMIUSDT + | HFTUSDT | @@ -166365,25 +168625,36 @@HIPPOUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HIVEUSDT | HMSTRUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HNTUSDT | ++ HOLOUSDT + | ++ HOMEUSDT + | HOOKUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HOTUSDT | - HPOS10IUSDT + HUMAUSDT + | ++ HUSDT |
HYPERUSDT
@@ -166391,17 +168662,31 @@ Supported Assets | HYPEUSDT | ++ ICNTUSDT + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + ICPBUSD + | ICPUSDT | ++ ICXUSD + | ICXUSDT | IDEXUSDT | ++ IDOLUSDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IDUSDT | @@ -166411,14 +168696,17 @@IMXUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| INITUSDT | INJUSDT | ++ INUSDT + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IOSTUSDT | @@ -166431,14 +168719,14 @@IOUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - IPUSDT + IPUSDC | - IQ50USDT + IPUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JASMYUSDT | @@ -166451,19 +168739,19 @@JSTUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JTOUSDT | JUPUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - JUSDT + KAIAUSDT | - KAIAUSDT + KAITOUSDC |
KAITOUSDT
@@ -166471,26 +168759,32 @@ Supported Assets | KASUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| KAVAUSDT | KDAUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| KERNELUSDT | KEYUSDT | ++ KGENUSDT + | KLAYUSDT | KMNOUSDT | ++ KNCUSD + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -166503,28 +168797,48 @@ Supported AssetsKSMUSDT |
- L3USDT + LABUSDT | - LADYSUSDT + LAUSDT | - LAIUSDT + LAYERUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + LDOBUSD + | LDOUSDT | ++ LEVERBUSD + | LEVERUSDT | ++ LIGHTUSDT + | LINAUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + LINEAUSDT + | ++ LINKBUSD + | LINKUSD | ++ LINKUSDC + | LINKUSDT | @@ -166537,7 +168851,7 @@- LOOKSUSDT + LOKAUSDT |
LOOMUSDT
@@ -166557,16 +168871,16 @@ Supported AssetsLSKUSDT |
- LTCUSD + LTCBUSD | - LTCUSDT + LTCUSD | - LTOUSDT + LTCUSDC | - LUCEUSDT + LTCUSDT |
LUMIAUSDT
@@ -166574,16 +168888,16 @@ Supported Assets | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - LUNA2USDT + LUNA2BUSD | - LUNCUSDT + LUNA2USDT | - MAGICUSDT + LYNUSDT | - MAJORUSDT + MAGICUSDT |
MANAUSD
@@ -166594,19 +168908,19 @@ Supported Assets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MANEKIUSDT + MANTAUSDT | - MANTAUSDT + MASKUSDT | - MAPOUSDT + MATICBUSD | - MASAUSDT + MATICUSD | - MASKUSDT + MATICUSDC |
MATICUSDT
@@ -166619,26 +168933,20 @@ Supported Assets | MAVUSDT | -- MAXUSDT - | MBLUSDT | MBOXUSDT | -- MCUSDT - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDTUSDT | MELANIAUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MEMEFIUSDT | @@ -166651,16 +168959,16 @@METISUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MEUSDT + METUSDT | - MEWUSDT + MEUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MICHIUSDT + MEWUSDT |
MILKUSDT
@@ -166669,30 +168977,22 @@ Supported AssetsMINAUSDT |
- MKRUSDT - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MLNUSDT + MIRAUSDT | - MNTUSD + MITOUSDT | - MNTUSDT + MKRUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MOBILEUSDT + MLNUSDT | MOCAUSDT | -- MOGUSDT - | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MONUSDT | @@ -166703,19 +169003,10 @@- MOTHER1USDT - | -- MOTHER2USDT - | -- MOTHERUSDT + MOVEUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MOVEUSDT - | MOVRUSDT | @@ -166726,47 +169017,50 @@- MULTIUSDT + MUSDT | - MUMUUSDT + MYROUSDT + | ++ MYXUSDT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - MVLUSDT + NAORISUSDT | - MYRIAUSDT + NEARBUSD | - MYROUSDT + NEARUSD | - NCUSDT + NEARUSDC | - NEARUSD + NEARUSDT | - NEARUSDT + NEIROETHUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - NEIROCTOUSDT + NEIROUSDT | - NEIROETHUSDT + NEOUSDC | NEOUSDT | - NFPUSDT + NEWTUSDT | - NFTUSDT + NFPUSDT |
NILUSDT
@@ -166780,10 +169074,10 @@ Supported AssetsNMRUSDT |
- NOTUSDT + NOMUSDT | - NSUSDT + NOTUSDT |
NTRNUSDT
@@ -166794,14 +169088,11 @@ Supported Assets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - NYANUSDT + NXPCUSDT | OBOLUSDT | -- OBTUSDT - | OCEANUSDT | @@ -166811,14 +169102,11 @@OGUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - OKBUSDT - | OLUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OMGUSDT | @@ -166831,17 +169119,20 @@ONDOUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ONEUSDT | ONGUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ONTUSDT | ++ OPENUSDT + | OPUSD | @@ -166851,88 +169142,77 @@ORBSUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ORCAUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ORDERUSDT | - ORDIUSDT - | -- ORNUSDT + ORDIUSDC | - OSMOUSDT + ORDIUSDT | OXTUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PARTIUSDT | PAXGUSDT | -- PEAQUSDT - | -- PEIPEIUSDT - | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PENDLEUSDT | - PENGUSDT + PENGUUSDC | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PENGUUSDT | PEOPLEUSDT | -- PEPEUSDT - | PERPUSDT | PHAUSDT | -- PHBUSDT - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - PIPPINUSDT + PHBBUSD | - PIRATEUSDT + PHBUSDT + | ++ PIPPINUSDT | PIXELUSDT | - PIXFIUSDT + PLAYUSDT | PLUMEUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + PNUTUSDC + | PNUTUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| POLUSDT | @@ -166945,25 +169225,16 @@POPCATUSDT | -- PORTALUSDT - | -- POWRUSDT - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - PRCLUSDT - | -- PRE05EOSUSDT + PORT3USDT | - PRE08EOSUSDT + PORTALUSDT | - PRIMEUSDT + POWRUSDT |
PROMPTUSDT
@@ -166971,34 +169242,31 @@ Supported Assets | PROMUSDT | ++ PROVEUSDT + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - PROSUSDT + PTBUSDT | PUFFERUSDT | - PUMPUSDT + PUMPBTCUSDT | - PUNDIXUSDT + PUMPUSDT | - PUNDUUSDT + PUNDIXUSDT | - PYRUSDT + PYTHUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - PYTHUSDT - | -- QIUSDT - | QNTUSDT | @@ -167006,24 +169274,21 @@- QUBICUSDT + QUICKUSDT | - QUICKUSDT + QUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RADUSDT | RAREUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - RATSUSDT - | -- RAYDIUMUSDT + RAYSOLUSDT |
RAYUSDT
@@ -167031,14 +169296,20 @@ Supported Assets | RDNTUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + RECALLUSDT + | REDUSDT | REEFUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + REIUSDT + | RENDERUSDT | @@ -167046,67 +169317,70 @@- REQUSDT + RESOLVUSDT | - REXUSDT + REZUSDT + | ++ RIFUSDT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - REZUSDT + RIVERUSDT | - RFCUSDT + RLCUSDT | - RIFSOLUSDT + RNDRUSDT | - RIFUSDT + RONINUSDT | - RLCUSDT + ROSEUSD | - RNDRUSDT + ROSEUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - ROAMUSDT + RPLUSDT | - RONINUSDT + RSRUSDT | - RONUSDT + RUNEUSD | - ROSEUSDT + RUNEUSDT | - RPLUSDT + RVNUSDT | - RSRUSDT + RVVUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - RSS3USDT + SAFEUSDT | - RUNEUSDT + SAGAUSDT | - RVNUSDT + SAHARAUSDT | - SAFEUSDT + SANDBUSD | - SAGAUSDT + SANDUSD |
SANDUSDT
@@ -167114,10 +169388,10 @@ Supported Assets | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SATSUSDT + SANTOSUSDT | - SCAUSDT + SAPIENUSDT |
SCRTUSDT
@@ -167129,95 +169403,101 @@ Supported AssetsSCUSDT |
- SDUSDT + SEIUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SEIUSDT + SFPUSDT | - SENDUSDT + SHELLUSDT | - SERAPHUSDT + SIGNUSDT | - SFPUSDT + SIRENUSDT | - SHELLUSDT + SKATEUSDT | - SHIB1000USDT + SKLUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SIGNUSDT + SKYAIUSDT | - SILLYUSDT + SKYUSDT | - SIRENUSDT + SLERFUSDT | - SKLUSDT + SLPUSDT | - SLERFUSDT + SNTUSDT | - SLFUSDT + SNXUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SLPUSDT + SOLBUSD | - SNTUSDT + SOLUSD | - SNXUSDT + SOLUSDC | - SOLAYERUSDT + SOLUSDT | - SOLOUSDT + SOLVUSDT | - SOLUSD + SOMIUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SOLUSDT + SONICUSDT | - SOLVUSDT + SOONUSDT | - SONICUSDT + SOPHUSDT | - SPECUSDT + SPELLUSDT | - SPELLUSDT + SPKUSDT | SPXUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + SQDUSDT + | ++ SRMUSDT + | SSVUSDT | - STARLUSDT + STBLUSDT |
STEEMUSDT
@@ -167225,14 +169505,14 @@ Supported Assets | STGUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STMXUSDT | STORJUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STOUSDT | @@ -167245,19 +169525,19 @@STRKUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| STXUSDT | SUIUSD | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - SUIUSDT + SUIUSDC | - SUNDOGUSDT + SUIUSDT |
SUNUSDT
@@ -167265,20 +169545,17 @@ Supported Assets | SUPERUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SUSDT | SUSHIUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SWARMSUSDT | -- SWEATUSDT - | SWELLUSDT | @@ -167288,25 +169565,42 @@SXTUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYNUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + SYRUPUSDT + | SYSUSDT | ++ TACUSDT + | ++ TAGUSDT + | TAIKOUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - TAIUSDT + TAKEUSDT + | ++ TANSSIUSDT | TAOUSDT | - TEST01SWELLUSDT + TAUSDT + | ++ THETAUSD |
THETAUSDT
@@ -167317,27 +169611,27 @@ Supported AssetsTHEUSDT |
- TIAUSDT + TIAUSDC | - TLMUSDT + TIAUSDT | - TNSRUSDT + TLMBUSD | - TOKENUSDT + TLMUSDT | - TOMIUSDT + TNSRUSDT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - TOMOUSDT + TOKENUSDT | - TONUSD + TOMOUSDT |
TONUSDT
@@ -167346,62 +169640,93 @@ Supported AssetsTOSHIUSDT |
- TRBUSDT + TOWNSUSDT | - TROYUSDT + TRADOORUSDT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + TRBUSDT + | ++ TREEUSDT + | ++ TROYUSDT + | ++ TRUMPUSDC + | TRUMPUSDT | ++ TRUTHUSDT + | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TRUUSDT | ++ TRXBUSD + | ++ TRXUSD + | TRXUSDT | - TSTBSCUSDT + TSTUSDT | TURBOUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TUSDT | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TUTUSDT | TWTUSDT | ++ UBUSDT + | UMAUSDT | UNFIUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + UNIBUSD + | UNIUSD | - UNIUSDT + UNIUSDC | -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - UROUSDT + UNIUSDT | USDCUSDT | - USDEUSDT + USELESSUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| USTCUSDT | @@ -167411,8 +169736,6 @@UXLINKUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VANAUSDT | @@ -167422,43 +169745,37 @@VELODROMEUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - VELOUSDT + VELVETUSDT + | ++ VETUSD | VETUSDT | - VGXUSDT + VFYUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VICUSDT | VIDTUSDT | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VINEUSDT | -- VINUUSDT - | VIRTUALUSDT | VOXELUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - VRAUSDT - | -- VRUSDT - | VTHOUSDT | @@ -167468,68 +169785,65 @@WALUSDT | -- WAVESUSDT - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - WAXPUSDT + WAVESBUSD | - WCTUSDT + WAVESUSDT | - WENUSDT + WAXPUSDT | - WHYUSDT + WCTUSDT | WIFUSD | - WIFUSDT + WIFUSDC | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - WLDUSDT + WIFUSDT | - WOOUSDT + WLDUSD | - WSMUSDT + WLDUSDC | - WUSDT + WLDUSDT | - XAIUSDT + WLFIUSDC | - XAUTUSDT + WLFIUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - XCHUSDT + WOOUSDT | - XCNUSDT + WUSDT | - XDCUSDT + XAIUSDT | - XECUSDT + XANUSDT | - XEMUSDT + XCNUSDT | - XIONUSDT + XEMUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - XMRUSDT + XMRUSD | - XNOUSDT + XMRUSDT | - XRDUSDT + XNYUSDT | - XRPUSD + XPINUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - XRPUSDT + XPLUSDT | - XTERUSDT + XRPBUSD | - XTZUSDT + XRPUSD | - XUSDT + XRPUSDC | - XVGUSDT + XRPUSDT | - XVSUSDT + XTZUSD | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - YFIIUSDT + XTZUSDT | - YFIUSDT + XVGUSDT | - YGGUSDT + XVSUSDT | - ZBCNUSDT + YALAUSDT | - ZCXUSDT + YBUSDT | - ZECUSDT + YFIUSDT | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - ZENTUSDT + YGGUSDT + | ++ ZBTUSDT + | ++ ZECUSDT |
ZENUSDT
@@ -167605,16 +169925,16 @@ Supported Assets | ZETAUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - ZEUSUSDT + ZILUSD | ZILUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - ZKFUSDT + ZKCUSDT |
ZKJUSDT
@@ -167625,17 +169945,20 @@ Supported Assets | ZORAUSDT | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ZRCUSDT | ZROUSDT | -|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ZRXUSDT | ++ 币安人生USDT + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- The Binance Crypto Future Margin Rate dataset enables correct margin cost so you can accurately design strategies for Cryptocurrencies with term structure. Examples include the following strategies: + The Binance Crypto Future Price dataset enables you to accurately design strategies for Cryptocurrencies with term structure. Examples include the following strategies:
- The following example algorithm holds a long position in the BTCUSDT perpetual Future contract on the Bybit exchange. When the margin interest rate is relatively low, it flips to a short position. + The following example algorithm buys BTCUSDT perpetual future contract if the last day's close price was close to ask close price than bid close price, sells short of that in opposite, through the Binance exchange:
from AlgorithmImports import * - +-from AlgorithmImports import * -class BybitCryptoFutureDataAlgorithm(QCAlgorithm): - # Add an indicator to track the low of trailing margin interest rates. - _low_interest_rate = Minimum(10) +class BinanceCryptoFutureDataAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 9, 1) self.set_end_date(2024, 12, 31) - # Set Account Currency to USDT, since USD cannot be used to trade. - self.set_cash("USDT", 100_000) - # Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling. - self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN) - # Seed the price of each asset with its last known price to avoid trading errors. - self.settings.seed_initial_prices = True - # Requesting data, we only trade on BTCUSDT Future in Bybit exchange + # Set the account currency to USDT, since you can't trade with + # USD and the algorithm doesn't automatically convert USD & USDT + # holdings. + self.set_account_currency("USDT", 100000) + # Binance Futures Exchange accepts both Cash and Margin account + # types. Select the one you need for the best reality modeling. + self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) + # Add BTCUSDT data from the Binance Future exchange. # Perpetual futures does not have a filter function. - self._future = self.add_crypto_future("BTCUSDT", Resolution.DAILY) + self._btc = self.add_crypto_future("BTCUSDT", Resolution.DAILY) # Historical data - history = self.history[MarginInterestRate](self._future.symbol, 10, Resolution.DAILY) - for data_point in history: - self._low_interest_rate.update(data_point.end_time, data_point.interest_rate) + history = self.history(self._btc, 10, Resolution.DAILY) def on_data(self, slice: Slice) -> None: - # Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL - # Or you can calculate the trade size on keeping the quote currency constant - if self._future.symbol not in slice.margin_interest_rates: + # Trade only based on updated price data. + if self._btc.symbol not in slice.bars or self._btc.symbol not in slice.quote_bars: return - interest_rate = slice.margin_interest_rates[self._future.symbol].interest_rate - self.plot('Margin Interest Rate', str(self._future.symbol), interest_rate) - # Short when margin interest rates are relatively low. Otherwise, long. - if interest_rate <= self._low_interest_rate.current.value: - if not self._future.holdings.is_short: - self.set_holdings(self._future.symbol, -0.5) - elif not self._future.holdings.is_long: - self.set_holdings(self._future.symbol, 1) - # Update the indicator. - self._low_interest_rate.update(self.time, interest_rate)public class BybitCryptoFutureDataAlgorithm : QCAlgorithm + # Scalp-trade the bid-ask spread based on the supply-demand strength + if self._btc.price - self._btc.bid_price > self._btc.ask_price - self._btc.price: + self.set_holdings(self._btc, -0.5) + else: + self.set_holdings(self._btc, 1)++}public class BinanceCryptoFutureDataAlgorithm : QCAlgorithm { - private CryptoFuture _future; - // Add an indicator to track the low of trailing margin interest rates. - private Minimum _lowInterestRate = new(10); + public CryptoFuture _btc; public override void Initialize() { SetStartDate(2024, 9, 1); SetEndDate(2024, 12, 31); - // Set Account Currency to USDT, since USD cannot be used to trade. - SetCash("USDT", 100000); - // Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling. - SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin); - // Seed the price of each asset with its last known price to avoid trading errors. - Settings.SeedInitialPrices = true; - // Requesting data, we only trade on BTCUSDT Future in Bybit exchange + // Set the account currency to USDT, since you can't trade with + // USD and the algorithm doesn't automatically convert USD & USDT + // holdings. + SetAccountCurrency("USDT", 100000); + // Binance Futures Exchange accepts both Cash and Margin account + // types. Select the one you need for the best reality modeling. + SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); + // Add BTCUSDT data from the Binance Future exchange. // Perpetual futures does not have a filter function. - _future = AddCryptoFuture("BTCUSDT", Resolution.Daily); + _btc = AddCryptoFuture("BTCUSDT", Resolution.Daily); // Historical data - var history = History<MarginInterestRate>(_future.Symbol, 10, Resolution.Daily); - foreach (var dataPoint in history) - { - _lowInterestRate.Update(dataPoint.EndTime, dataPoint.InterestRate); - } + var history = History(_btc, 10, Resolution.Daily); } public override void OnData(Slice slice) { - // Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL - // Or you can calculate the trade size on keeping the quote currency constant - if (!slice.MarginInterestRates.TryGetValue(_future.Symbol, out var dataPoint)) + // Trade only based on updated price data. + if (!slice.Bars.ContainsKey(_btc) || !slice.QuoteBars.ContainsKey(_btc)) { return; } - var interestRate = dataPoint.InterestRate; - Plot("Margin Interest Rate", _future.Symbol.ToString(), interestRate); - // Short when margin interest rates are relatively low. Otherwise, long. - if (interestRate <= _lowInterestRate) + // Scalp-trade the bid-ask spread based on the supply-demand strength + if (_btc.Price - _btc.BidPrice > _btc.AskPrice - _btc.Price) { - if (!_future.Holdings.IsShort) - { - SetHoldings(_future.Symbol, -0.5); - } + SetHoldings(_btc, -0.5m); } - else if (!_future.Holdings.IsLong) + else { - SetHoldings(_future.Symbol, 1); + SetHoldings(_btc, 1m); } - // Update the indicator. - _lowInterestRate.Update(Time, interestRate); } -}
- The following example algorithm holds a long position in the BTCUSDT perpetual Future contract on the Bybit exchange. When the margin interest rate is relatively low, it flips to a short position. + The following example algorithm hold a long BTCUSDT Future portfolio if the last day's close price was close to ask close price than bid close price, while hold short of that in opposite, through the Binance exchange using the + + algorithm framework + + implementation:
from AlgorithmImports import * +-from AlgorithmImports import * -class BybitCryptoFutureDataAlgorithm(QCAlgorithm): +class BinanceCryptoFutureDataAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2024, 9, 1) self.set_end_date(2024, 12, 31) - self.settings.free_portfolio_value_percentage = 0.1 - # Set Account Currency to USDT, since USD cannot be used to trade. - self.set_cash("USDT", 100000) - # Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling. - self.set_brokerage_model(BrokerageName.BYBIT, AccountType.MARGIN) - # Seed the price of each asset with its last known price to avoid trading errors. - self.settings.seed_initial_prices = True + # Set the account currency to USDT, since you can't trade with + # USD and the algorithm doesn't automatically convert USD & USDT + # holdings. + self.set_account_currency("USDT", 100000) + # Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. + self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN) self.universe_settings.resolution = Resolution.DAILY self.universe_settings.leverage = 2 - # We only trade on BTCUSDT Future in Bybit exchange - symbols = Symbol.create("BTCUSDT", SecurityType.CRYPTO_FUTURE, Market.BYBIT) + # We only trade on BTCUSDT Future in Binance Future exchange + symbols = Symbol.create("BTCUSDT", SecurityType.CRYPTO_FUTURE, Market.BINANCE) self.add_universe_selection(ManualUniverseSelectionModel(symbols)) # Custom alpha model to emit insights based on the Crypto Future price data self.add_alpha(CryptoFutureAlphaModel()) @@ -167794,59 +170097,63 @@self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel()) self.set_execution(ImmediateExecutionModel()) - class CryptoFutureAlphaModel(AlphaModel): - _min_by_symbol = {} + def __init__(self) -> None: + self.symbols = [] def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]: insights = [] - for symbol, low_interest_rate in self._min_by_symbol.items(): - # Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL - # Or you can calculate the trade size on keeping the quote currency constant - if symbol not in slice.margin_interest_rates: + + for symbol in self.symbols: + # Trade only based on updated price data + if not slice.bars.contains_key(symbol) or not slice.quote_bars.contains_key(symbol): continue - interest_rate = slice.margin_interest_rates[symbol].interest_rate - algorithm.plot('Margin Interest Rate', str(symbol), interest_rate) - # Short when margin interest rates are relatively low. Otherwise, long. - if interest_rate <= low_interest_rate.current.value: + + quote = slice.quote_bars[symbol] + price = slice.bars[symbol].price + + # Scalp-trade the bid-ask spread based on the supply-demand strength + if price - quote.bid.close > quote.ask.close - price: direction = InsightDirection.DOWN else: direction = InsightDirection.UP insights.append(Insight.price(symbol, timedelta(1), direction)) - # Update the indicator. - low_interest_rate.update(slice.time, interest_rate) + return insights def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None: for security in changes.added_securities: symbol = security.symbol - # Add an indicator to track the low of trailing margin interest rates. - self._min_by_symbol[symbol] = Minimum(10) + self.symbols.append(symbol) + # Historical data - history = algorithm.history[MarginInterestRate](symbol, 10, Resolution.DAILY) - for data_point in history: - self._min_by_symbol[symbol].update(data_point.end_time, data_point.interest_rate) + history = algorithm.history(symbol, 10, Resolution.DAILY) + for security in changes.removed_securities: - self._min_by_symbol.pop(security.symbol, None)
public class BybitCryptoFutureDataAlgorithm : QCAlgorithm + symbol = security.symbol + if symbol in self.symbols: + self.symbols.remove(symbol) +++}public class BinanceCryptoFutureDataAlgorithm : QCAlgorithm { + public Symbol _symbol; + public override void Initialize() { SetStartDate(2024, 9, 1); SetEndDate(2024, 12, 31); - Settings.FreePortfolioValuePercentage = 0.1m; - // Set Account Currency to USDT, since USD cannot be used to trade. - SetCash("USDT", 100000); - // Bybit accepts both Cash and Margin account types, select the one you need for the best reality modeling. - SetBrokerageModel(BrokerageName.Bybit, AccountType.Margin); - // Seed the price of each asset with its last known price to avoid trading errors. - Settings.SeedInitialPrices = true; + // Set the account currency to USDT, since you can't trade with + // USD and the algorithm doesn't automatically convert USD & USDT + // holdings. + SetAccountCurrency("USDT", 100000); + // Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling. + SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin); UniverseSettings.Resolution = Resolution.Daily; UniverseSettings.Leverage = 2; - // We only trade on BTCUSDT Future in Bybit exchange - var symbols = new List<Symbol>{ - QuantConnect.Symbol.Create("BTCUSDT", SecurityType.CryptoFuture, Market.Bybit) + // We only trade on BTCUSDT Future in Binance Future exchange + var symbols = new List<Symbol> { + QuantConnect.Symbol.Create("BTCUSDT", SecurityType.CryptoFuture, Market.Binance) }; AddUniverseSelection(new ManualUniverseSelectionModel(symbols)); // Custom alpha model to emit insights based on the Crypto Future price data @@ -167859,28 +170166,32 @@public class CryptoFutureAlphaModel : AlphaModel { - private Dictionary<Symbol, Minimum> _minBySymbol = new(); + private List<Symbol> _symbols = new(); public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice) { var insights = new List<Insight>(); - foreach (var kvp in _minBySymbol) + + foreach (var symbol in _symbols) { - var symbol = kvp.Key; - var lowInterestRate = kvp.Value; - // Note that you may want to access the margin interest of the crypto future to calculate if it would impact a trade's PnL - // Or you can calculate the trade size on keeping the quote currency constant - if (!slice.MarginInterestRates.TryGetValue(symbol, out var dataPoint)) + // Trade only based on updated price data + if (!slice.Bars.ContainsKey(symbol) || !slice.QuoteBars.TryGetValue(symbol, out var quote)) + { continue; - var interestRate = dataPoint.InterestRate; - algorithm.Plot("Margin Interest Rate", symbol.ToString(), interestRate); - // Short when margin interest rates are relatively low. Otherwise, long. - var direction = interestRate <= lowInterestRate.Current.Value - ? InsightDirection.Down - : InsightDirection.Up; + } + var price = slice.Bars[symbol].Price; + + // Scalp-trade the bid-ask spread based on the supply-demand strength + InsightDirection direction; + if (price - quote.Bid.Close > quote.Ask.Close - price) + { + direction = InsightDirection.Down; + } + else + { + direction = InsightDirection.Up; + } insights.Add(Insight.Price(symbol, TimeSpan.FromDays(1), direction)); - // Update the indicator. - lowInterestRate.Update(slice.Time, interestRate); } return insights; } @@ -167890,22 +170201,18 @@
foreach (var security in changes.AddedSecurities) { var symbol = security.Symbol; - // Add an indicator to track the low of trailing margin interest rates. - var min = new Minimum(10); - _minBySymbol[symbol] = min; + _symbols.Add(symbol); + // Historical data - var history = algorithm.History<MarginInterestRate>(symbol, 10, Resolution.Daily); - foreach (var dataPoint in history) - { - min.Update(dataPoint.EndTime, dataPoint.InterestRate); - } + var history = algorithm.History(symbol, 10, Resolution.Daily); } + foreach (var security in changes.RemovedSecurities) { - _minBySymbol.Remove(security.Symbol); + _symbols.Remove(security.Symbol); } } -}
- The Binance Crypto Future Margin Rate dataset provides
+ The Binance Crypto Future Price dataset provides
- MarginInterestRate
+ TradeBar
- objects, which have the following attributes:
+ ,
+
+ QuoteBar
+
+ , and
+
+ Tick
+
+ objects.
+
+ TradeBar
+
+ objects have the following attributes:
+
+
+ QuoteBar
+
+ objects have the following attributes:
+
+
+ Tick
+
+ objects have the following attributes:
+
- +
- The CFD Data by QuantConnect serves 51 - - contracts for differences - - (CFD). The data starts as early as May 2002 and is delivered on any frequency from tick to daily. This dataset is created by QuantConnect processing raw tick data from OANDA. -
-- CFD data does not include ask and bid sizes. + The Binance Crypto Price Data is for Cryptocurrency price and volume data points. The data covers 3,320 Cryptocurrency pairs, starts in July 2017, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on Binance.
- For more information about the CFD Data dataset, including CLI commands and pricing, see the - + For more information about the Binance Crypto Price Data dataset, including CLI commands and pricing, see the + dataset listing . @@ -167962,7 +170301,7 @@
- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. + Binance was founded by Changpeng Zhao in 2017 with the goal to "increase the freedom of money globally". Binance provides access to trading Crypto through spot markets and perpetual Futures. They serve clients with no minimum deposit when depositing Crypto. Binance also provides an NFT marketplace, a mining pool, and services to deposit Crypto coins in liquidity pools to earn rewards.
@@ -167971,11 +170310,24 @@- The following snippet demonstrates how to request data from the CFD dataset: + The following snippet demonstrates how to request data from the Binance Crypto Price dataset:
self.xauusd = self.add_cfd("XAUUSD", Resolution.DAILY).symbol
- _symbol = AddCfd("XAUUSD", Resolution.Daily).Symbol;
+ # Binance accepts both Cash and Margin account types only.
+self.set_brokerage_model(BrokerageName.BINANCE, AccountType.CASH)
+#self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
+
+self.btcbusd = self.add_crypto("BTCBUSD", Resolution.MINUTE, Market.BINANCE).symbol
+
+self._universe = self.add_universe(CryptoUniverse.binance(self.universe_selection_filter))
+
+ // Binance accepts both Cash and Margin account types only.
+SetBrokerageModel(BrokerageName.Binance, AccountType.Cash);
+//SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
+
+_symbol = AddCrypto("BTCBUSD", Resolution.Minute, Market.Binance).Symbol;
+
+_universe = AddUniverse(CryptoUniverse.Binance(UniverseSelectionFilter));
| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 1998 - | -
| - Coverage - | -- 125 US Indices and 3 International indices (HSI, SX5E and N225) - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Minute, Hour, & Daily - | -
| - Timezone - | -
- New York for US Indices, refer to
-
- Supported Assets
-
- below for International indices
- |
-
| - Market Hours - | -- - Regular Only - - | -
- To add Cash Indices data to your algorithm, call the
-
- AddIndex
-
-
- add_index
-
- method. Save a reference to the Index
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class CashIndexAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2020, 6, 1)
- self.set_end_date(2021, 6, 1)
- self.set_cash(100000)
-
- self.vix = self.add_index("VIX").symbol
-
- public class CashIndexAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
-
- _symbol = AddIndex("VIX").Symbol;
- }
-}
- - For more information about creating Index subscriptions, see - - Requesting Data - - . -
- - - -
- To get the current Cash Indices data, index the
-
- Bars
-
-
- bars
-
- property of the current
-
-
- Slice
-
-
- with the Index
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if self.vix in slice.bars:
- trade_bar = slice.bars[self.vix]
- self.log(f"{self.vix} close at {slice.time}: {trade_bar.close}")
- public override void OnData(Slice slice)
-{
- if (slice.Bars.ContainsKey(_symbol))
- {
- var tradeBar = slice.Bars[_symbol];
- Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- for symbol, trade_bar in slice.bars.items():
- self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.Bars)
- {
- var symbol = kvp.Key;
- var tradeBar = kvp.Value;
- Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-}
-
- - For more information about accessing Index data, see - - Handling Data - - . -
- - - -
- To get historical Cash Indices data, call the
-
- History
-
-
- history
-
- method with the Index
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.vix, 100, Resolution.DAILY) - -# TradeBar objects -history_bars = self.history[TradeBar](self.vix, 100, Resolution.DAILY)-
// TradeBar objects -var historyBars = History(_symbol, 100, Resolution.Daily);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To remove an Index subscription, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.vix)-
RemoveSecurity(_symbol);-
- The following table shows the US Cash indices with Index Option support: -
-| - Ticker - | -- Index - | -- Expiry - | -- Start Date - | -
|---|---|---|---|
| - VIX - | -- S&P500 - | -- 30 Days - | -- Jul 2003 - | -
| - SPX - | -- S&P500 - | -- - - | -- Jan 1998 - | -
| - NDX - | -- NASDAQ-100 - | -- - - | -- Jan 1998 - | -
| - RUT - | -- Russell 2000 - | -- - - | -- Jan 2008 - | -
- The Cboe Volatility Index (VIX) is a real-time index that represents the market's expectations for the relative strength of near-term price changes of the S&P 500 Index (SPX). Because it's derived from the prices of SPX index Options with near-term expiration dates, it generates a 30-day forward projection of volatility. Volatility, or how fast prices change, is often seen as a way to gauge market sentiment, and in particular, the degree of fear among market participants. -
-- The S&P 500 Index, or the Standard & Poor's 500 Index, is a market-capitalization-weighted index of the 500 largest publicly-traded companies in the U.S. It is not an exact list of the top 500 U.S. companies by market capitalization because there are other criteria included in the index. The index is widely regarded as the best gauge of large-cap U.S. Equities. -
-- The Nasdaq-100 Index is a modified market-capitalization-weighted index composed of securities issued by 100 of the largest non-financial companies listed on the Nasdaq Stock Market (Nasdaq). The index includes companies from various industries except for the financial industry, like commercial and investment banks. These non-financial sectors include retail, biotechnology, industrial, technology, health care, and others. -
-- The Russell 2000 Index is a small-cap U.S. stock market index that makes up the smallest 2,000 stocks in the Russell Index. It was started by the Frank Russell Company in 1984. The index is maintained by FTSE Russell, a subsidiary of the London Stock Exchange Group (LSEG). -
-- The following table shows the International Cash indices: -
-| - Ticker - | -- Index - | -- Start Date - | -- Time Zone - | -- Currency - | -- HSI - | -- Hang Seng Index - | -- Dec 2006 - | -- Asia/Hong Kong - | -- HKD - | -
|---|---|---|---|---|
| - SX5E - | -- EUREX EU STOXX - | -- Jul 2003 - | -- Europe/Berlin - | -- EUR - | -
| - N225 - | -- Nikkei 225 - | -- Jul 2003 - | -- Asia/Tokyo - | -- JPY - | -
- The Cash Indices enable you to incorporate popular indices into your trading algorithms. Examples include the following use cases: -
-- The following example algorithm tracks the 80-day EMA and 200-day EMA of SPX. When the short EMA crosses above the long EMA, the algorithm buys SPY. Otherwise, it holds cash. -
-from AlgorithmImports import *
-
-
-class IndexDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- # Request SPY data as a trading vehicle for SPX
- self.spy = self.add_equity("SPY").symbol
-
- # Request SPX data for trade signal generation
- spx = self.add_index("SPX").symbol
-
- # Create short and long-term EMA indicators for trend estimation to trade
- self.ema_fast = self.EMA(spx, 80, Resolution.DAILY)
- self.ema_slow = self.EMA(spx, 200, Resolution.DAILY)
- self.set_warm_up(200, Resolution.DAILY)
-
- # Historical data
- history = self.history(spx, 60, Resolution.DAILY)
- self.debug(f'We got {len(history.index)} items from our history request')
-
- def on_data(self, slice: Slice) -> None:
- # Trade signals required indicators to be ready
- if self.is_warming_up or not self.ema_slow.is_ready:
- return
-
- # If short-term EMA is above long-term, it indicates an up trend, so we buy SPY
- if not self.portfolio.invested and self.ema_fast > self.ema_slow:
- self.set_holdings(self.spy, 1)
- # If it is the reverse, it indicates a downtrend, and we liquidate any position
- elif self.ema_fast < self.ema_slow:
- self.liquidate()
-
- public class IndexDataAlgorithm : QCAlgorithm
-{
- private Symbol _spy;
- private ExponentialMovingAverage _emaSlow, _emaFast;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
-
- // Request SPY data as trading vehicle for SPX
- _spy = AddEquity("SPY").Symbol;
-
- // Request SPX data for trade signal generation
- var spx = AddIndex("SPX").Symbol;
-
- // Create short and long-term EMA indicators for trend estimation to trade
- _emaFast = EMA(spx, 80, Resolution.Daily);
- _emaSlow = EMA(spx, 200, Resolution.Daily);
- SetWarmUp(200, Resolution.Daily);
-
- // Historical data
- var history = History(spx, 60, Resolution.Daily);
- Debug($"We got {history.Count()} items from our history request");
- }
-
- public override void OnData(Slice slice)
- {
- // Trade signals required indicators to be ready
- if (IsWarmingUp || !_emaSlow.IsReady)
- {
- return;
- }
-
- // If short-term EMA is above long-term, it indicates an up trend, so we buy SPY
- if (!Portfolio.Invested && _emaFast > _emaSlow)
- {
- SetHoldings(_spy, 1);
- }
- // If it is the reverse, it indicates a downtrend, and we liquidate any position
- else if (_emaFast < _emaSlow)
- {
- Liquidate();
- }
- }
-}
- - The following example algorithm tracks the 80-day EMA and 200-day EMA of SPX. When the short EMA crosses above the long EMA, the algorithm buys SPY. Otherwise, it holds cash. -
-from AlgorithmImports import *
-
-
-class IndexDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- # Universe contains only SPY as a trading vehicle for SPX
- self.set_universe_selection(ManualUniverseSelectionModel
- (
- Symbol.create("SPY", SecurityType.EQUITY, Market.USA)
- ))
- # Custom alpha model that emits insights based on SPX index data
- self.set_alpha(SpxEmaCrossAlphaModel(self))
- # Equally investing can dissipate non-systematic risky event's capital concentration risk evenly
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(Expiry.END_OF_MONTH))
-
-
-class SpxEmaCrossAlphaModel(AlphaModel):
-
- def __init__(self, algorithm: QCAlgorithm) -> None:
- # Request SPX data for trade signal generation
- spx = algorithm.add_index("SPX").symbol
-
- # Create short and long-term EMA indicators for trend estimation to trade
- self.ema_fast = algorithm.EMA(spx, 80, Resolution.DAILY)
- self.ema_slow = algorithm.EMA(spx, 200, Resolution.DAILY)
- algorithm.set_warm_up(200, Resolution.DAILY)
-
- # Historical data
- history = algorithm.history(spx, 60, Resolution.DAILY)
- algorithm.debug(f'We got {len(history.index)} items from our history request')
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- # Trade signals required indicators to be ready
- if algorithm.is_warming_up or not self.ema_slow.is_ready:
- return []
-
- # If short-term EMA is above long-term, it indicates an up trend, so we buy SPY
- if not algorithm.portfolio.invested and self.ema_fast > self.ema_slow:
- return [Insight.price(kvp.key, Expiry.END_OF_MONTH, InsightDirection.UP)
- for kvp in algorithm.active_securities if kvp.value.is_tradable]
- # If it is the reverse, it indicates downtrend, and we liquidate any position
- elif self.ema_fast < self.ema_slow:
- return [Insight.price(kvp.key, Expiry.END_OF_MONTH, InsightDirection.FLAT)
- for kvp in algorithm.active_securities if kvp.value.is_tradable]
-
- return []
-
- public class IndexDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
-
- // Universe contains only SPY as a trading vehicle for SPX
- SetUniverseSelection(new ManualUniverseSelectionModel
- (
- QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA)
- ));
- // Custom alpha model that emits insights based on SPX index data
- SetAlpha(new SpxEmaCrossAlphaModel(this));
- // Equally invests can dissipate non-systematic risky event's capital concentration risk evenly
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(Expiry.EndOfMonth));
- }
-}
-
-public class SpxEmaCrossAlphaModel : AlphaModel
-{
- private ExponentialMovingAverage _emaSlow, _emaFast;
-
- public SpxEmaCrossAlphaModel(QCAlgorithm algorithm)
- {
- // Request SPX data for trade signal generation
- var spx = algorithm.AddIndex("SPX").Symbol;
-
- // Create short and long-term EMA indicators for trend estimation to trade
- _emaFast = algorithm.EMA(spx, 80, Resolution.Daily);
- _emaSlow = algorithm.EMA(spx, 200, Resolution.Daily);
- algorithm.SetWarmUp(200, Resolution.Daily);
-
- // Historical data
- var history = algorithm.History(spx, 60, Resolution.Daily);
- algorithm.Debug($"We got {history.Count()} items from our history request");
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- // Trade signals required indicators to be ready
- if (algorithm.IsWarmingUp || !_emaSlow.IsReady)
- {
- return Enumerable.Empty<Insight>();
- }
-
- // If short-term EMA is above long-term, it indicates an up trend, so we buy SPY
- if (!algorithm.Portfolio.Invested && _emaFast > _emaSlow)
- {
- return algorithm.ActiveSecurities
- .Where(kvp => kvp.Value.IsTradable)
- .Select(kvp => Insight.Price(kvp.Key, Expiry.EndOfMonth, InsightDirection.Up));
- }
- // If it is the reverse, it indicates downtrend, and we liquidate any position
- else if (_emaFast < _emaSlow)
- {
- return algorithm.ActiveSecurities
- .Where(kvp => kvp.Value.IsTradable)
- .Select(kvp => Insight.Price(kvp.Key, Expiry.EndOfMonth, InsightDirection.Flat));
- }
-
- return Enumerable.Empty<Insight>();
- }
-}
-
- The Cash Indices dataset provides
-
- TradeBar
-
- object.
-
-
- TradeBar
-
- objects have the following attributes:
-
- -
- The FOREX Data by QuantConnect serves 71 - - foreign exchange - - (FOREX) pairs, starts on various dates from January 2007, and is delivered on any frequency from tick to daily. This dataset is created by QuantConnect processing raw tick data from OANDA. -
-- FOREX data does not include ask and bid sizes. -
-- For more information about the FOREX Data dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the FOREX dataset: -
-self.eurusd = self.add_forex("EURUSD", Resolution.DAILY).symbol
- _symbol = AddForex("EURUSD", Resolution.Daily).Symbol;
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2007 - | -
| - Asset Coverage - | -- 71 Currency pairs - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Tick, Second, Minute, Hour, & Daily - | -
| - Timezone - | -- UTC - | -
| - Market Hours - | -- - Always Open - - , except from Friday 5 PM EST to Sunday 5 PM EST - | -
- To add FOREX data to your algorithm, call the
-
- AddForex
-
-
- add_forex
-
- method. Save a reference to the Forex
-
- Symbol
-
- so you can access the data later in your algorithm.
-
-class ForexAlgorithm (QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2019, 2, 20)
- self.set_end_date(2019, 2, 21)
- self.set_cash(100000)
-
- self.eurusd = self.add_forex('EURUSD', Resolution.MINUTE).symbol
-
- self.set_benchmark(self.eurusd)
-
- public class ForexAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2019, 2, 20);
- SetEndDate(2019, 2, 21);
- SetCash(100000);
-
- _symbol = AddForex("EURUSD", Resolution.Minute).Symbol;
-
- SetBenchmark(_symbol);
- }
-}
- - For more information about creating Forex subscriptions, see - - Requesting Data - - . -
- - - -
- To get the current Forex data, index the
-
- QuoteBars
-
-
- quote_bars
-
- , or
-
- Ticks
-
-
- ticks
-
- properties of the current
-
-
- Slice
-
-
- with the Forex
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if self.eurusd in slice.quote_bars:
- quote_bar = slice.quote_bars[self.eurusd]
- self.log(f"{self.eurusd} bid at {slice.time}: {quote_bar.bid.close}")
-
- if self.eurusd in slice.ticks:
- ticks = slice.ticks[self.eurusd]
- for tick in ticks:
- self.log(f"{self.eurusd} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- if (slice.QuoteBars.ContainsKey(_symbol))
- {
- var quoteBar = slice.QuoteBars[_symbol];
- Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- if (slice.Ticks.ContainsKey(_symbol))
- {
- var ticks = slice.Ticks[_symbol];
- foreach (var tick in ticks)
- {
- Log($"{_symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- for symbol, quote_bar in slice.quote_bars.items():
- self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- for symbol, ticks in slice.ticks.items():
- for tick in ticks:
- self.log(f"{symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.QuoteBars)
- {
- var symbol = kvp.Key;
- var quoteBar = kvp.Value;
- Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- foreach (var kvp in slice.Ticks)
- {
- var symbol = kvp.Key;
- var ticks = kvp.Value;
- foreach (var tick in ticks)
- {
- Log($"{symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
- - For more information about accessing Forex data, see - - Handling Data - - . -
- - - -
- To get historical Forex data, call the
-
- History
-
-
- history
-
- method with the Forex
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.eurusd, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](self.eurusd, 100, Resolution.MINUTE) - -# Tick objects -history_ticks = self.history[Tick](self.eurusd, timedelta(seconds=10), Resolution.TICK)-
// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); - -// Tick objects -var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To remove a Forex pair subscription, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.eurusd)-
RemoveSecurity(_symbol);-
- The
-
- RemoveSecurity
-
-
- remove_security
-
- method cancels your open orders for the security and liquidates your holdings.
-
- The following table shows the available Forex pairs: -
-- The FOREX price data enables you to trade currency pairs in the global market. Examples include the following strategies: -
-- The following example algorithm implements a FOREX carry trade. It buys the FOREX pair of the country with the lowest interest rate and sells the FOREX pair of the country with the highest interest rate. -
-from AlgorithmImports import *
-
-
-class ForexCarryTradeAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(25000)
-
- # We will use hard-coded interest rates for each base currency
- self.rates = {
- "USDAUD": 1.5, # Australia
- "USDCAD": 0.5, # Canada
- "USDCNY": 4.35, # China
- "USDEUR": 0.0, # Euro Area
- "USDINR": 6.5, # India
- "USDJPY": -0.1, # Japan
- "USDMXN": 4.25, # Mexico
- "USDTRY": 7.5, # Turkey
- "USDZAR": 7.0 # South Africa
- }
-
- # Subscribe to forex data for trading
- for ticker in self.rates:
- self.add_forex(ticker, Resolution.DAILY)
-
- # Use a month counter as variable to control rebalancing
- self.month = -1
-
- def on_data(self, slice: Slice) -> None:
- # Monthly rebalance checker
- if self.month == self.time.month:
- return
- self.month = self.time.month
-
- # Long the pair with highest interest rate and sell the pair with the lowest to earn the max monetary inflation difference between the two
- sorted_rates = sorted(self.rates.items(), key = lambda x: x[1])
- self.set_holdings(sorted_rates[0][0], -0.5)
- self.set_holdings(sorted_rates[-1][0], 0.5)
-
- public class ForexCarryTradeAlgorithm : QCAlgorithm
-{
- // Use a month counter as variable to control rebalancing
- private int _month = -1;
- private Dictionary<string, decimal> _rates;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(25000);
-
- // We will use hard-coded interest rates for each base currency
- _rates = new Dictionary<string, decimal>()
- {
- {"USDAUD", 1.5m}, // Australia
- {"USDCAD", 0.5m}, // Canada
- {"USDCNY", 4.35m}, // China
- {"USDEUR", 0.0m}, // Euro Area
- {"USDINR", 6.5m}, // India
- {"USDJPY", -0.1m}, // Japan
- {"USDMXN", 4.25m}, // Mexico
- {"USDTRY", 7.5m}, // Turkey
- {"USDZAR", 7.0m} // South Africa
- };
-
- // Subscribe to forex data for trading
- foreach (var ticker in _rates.Keys)
- {
- AddForex(ticker, Resolution.Daily);
- }
- }
-
- public override void OnData(Slice slice)
- {
- // Monthly rebalance checker
- if (_month == Time.Month) return;
- _month = Time.Month;
-
- // Long the pair with highest interest rate and sell the pair with the lowest to earn the max monetary inflation difference between the two
- var sortedRates = (from kvp in _rates orderby kvp.Value ascending select kvp.Key).ToArray();
- SetHoldings(sortedRates[0], -0.5);
- SetHoldings(sortedRates[sortedRates.Length-1], 0.5);
- }
-}
- - The following example algorithm implements a FOREX carry trade. It buys the FOREX pair of the country with the lowest interest rate and sells the FOREX pair of the country with the highest interest rate. -
-from AlgorithmImports import *
-
-
-class ForexCarryTradeAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(25000)
-
- def to_symbol(ticker: str) -> Symbol:
- return Symbol.create(ticker, SecurityType.FOREX, Market.OANDA)
-
- # We will use hard-coded interest rates for each base currency
- rates = {
- to_symbol("USDAUD"): 1.5, # Australia
- to_symbol("USDCAD"): 0.5, # Canada
- to_symbol("USDCNY"): 4.35, # China
- to_symbol("USDEUR"): 0.0, # Euro Area
- to_symbol("USDINR"): 6.5, # India
- to_symbol("USDJPY"): -0.1, # Japan
- to_symbol("USDMXN"): 4.25, # Mexico
- to_symbol("USDTRY"): 7.5, # Turkey
- to_symbol("USDZAR"): 7.0 # South Africa
- }
-
- self.set_universe_selection(ManualUniverseSelectionModel(list(rates.keys())))
- # A custom alpha model to emit insight according to interest rate
- self.set_alpha(IntestRatesAlphaModel(rates))
- # Equal size to capitalize the monetary value of quote currency only based on interest rate difference
- # For dollar-neutral to save margin cost
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(Expiry.END_OF_MONTH))
-
-class IntestRatesAlphaModel(AlphaModel):
- def __init__(self, rates: float) -> None:
- self.rates = rates
- # Variable to control the rebalancing time
- self.month = -1
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- # Monthly rebalance
- if self.month == algorithm.time.month:
- return []
- self.month = algorithm.time.month
-
- # # Long the pair with highest interest rate and sell the pair with the lowest to earn the max monetary inflation difference between the two
- sorted_rates = sorted(self.rates.items(), key = lambda x: x[1])
- return Insight.group(
- Insight.price(sorted_rates[0][0], Expiry.END_OF_MONTH, InsightDirection.UP),
- Insight.price(sorted_rates[-1][0], Expiry.END_OF_MONTH, InsightDirection.DOWN)
- )
-
- public class ForexCarryTradeAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(25000);
-
- Symbol toSymbol(string ticker)
- {
- return QuantConnect.Symbol.Create(ticker, SecurityType.Forex, Market.Oanda);
- }
-
- // We will use hard-coded interest rates for each base currency
- var rates = new Dictionary<Symbol, decimal>()
- {
- {toSymbol("USDAUD"), 1.5m}, // Australia
- {toSymbol("USDCAD"), 0.5m}, // Canada
- {toSymbol("USDCNY"), 4.35m}, // China
- {toSymbol("USDEUR"), 0.0m}, // Euro Area
- {toSymbol("USDINR"), 6.5m}, // India
- {toSymbol("USDJPY"), -0.1m}, // Japan
- {toSymbol("USDMXN"), 4.25m}, // Mexico
- {toSymbol("USDTRY"), 7.5m}, // Turkey
- {toSymbol("USDZAR"), 7.0m} // South Africa
- };
-
- SetUniverseSelection(new ManualUniverseSelectionModel(rates.Keys));
- // A custom alpha model to emit insight according to interest rate
- SetAlpha(new IntestRatesAlphaModel(rates));
- // Equal size to capitalize the monetary value of quote currency only based on interest rate difference
- // For dollar-neutral to save margin cost
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(Expiry.EndOfMonth));
- }
-}
-
-public class IntestRatesAlphaModel : AlphaModel
-{
- // Variable to control the rebalancing time
- private int _month = -1;
- private Dictionary<Symbol, decimal> _rates;
-
- public IntestRatesAlphaModel(Dictionary<Symbol, decimal> rates)
- {
- _rates = rates;
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- // Monthly rebalance
- if (_month == algorithm.Time.Month)
- {
- return Enumerable.Empty<Insight>();
- }
- _month = algorithm.Time.Month;
-
- // Long the pair with highest interest rate and sell the pair with the lowest to earn the max monetary inflation difference between the two
- var sortedRates = (from kvp in _rates orderby kvp.Value ascending select kvp.Key).ToArray();
-
- return Insight.Group(
- Insight.Price(sortedRates[0], Expiry.EndOfMonth, InsightDirection.Up),
- Insight.Price(sortedRates[sortedRates.Length-1], Expiry.EndOfMonth, InsightDirection.Down)
- );
- }
-}
-
- The FOREX dataset provides
-
- QuoteBar
-
- and
-
- Tick
-
- objects.
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- Tick
-
- objects have the following attributes:
-
- -
- The Fear and Greed dataset by QuantConnect provides data points to quantify the degree of fear and greed in the US Equity market. The data starts in 2014 and is delivered on a daily frequency, delayed by two days. This dataset is created by aggregating seven indicators, including market volatility, stock market breadth, and put-call ratios. -
-- For more information about the Fear and Greed dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the Fear and Greed dataset: -
-self._dataset_symbol = self.add_data(FearGreedIndex, 'FG').symbol-
_datasetSymbol = AddData<FearGreedIndex>("FG").Symbol;
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- July 2014 - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- The latest daily data points are about two days since the VIX and SPX prices are inputs into the index and their latest daily prices are also two days old. New data is available at 9 AM EST. -
- - - -
- To add Fear and Greed data to your algorithm, call the
-
- AddData<FearGreedIndex>
-
-
- add_data
-
- method. Save a reference to the dataset
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class FearAndGreedDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2019, 1, 1)
- self.set_end_date(2020, 6, 1)
- self.set_cash(100000)
-
- self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
- self._dataset_symbol = self.add_data(FearGreedIndex, "FG").symbol
- public class FearAndGreedDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol, _datasetSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2019, 1, 1);
- SetEndDate(2020, 6, 1);
- SetCash(100000);
- _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
- _datasetSymbol = AddData<FearGreedIndex>("FG").Symbol;
- }
-}
-
- To get the current Fear and Greed data, index the current
-
-
- Slice
-
-
- with the dataset
-
- Symbol
-
- .
-
- Slice
-
- objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your dataset at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if slice.contains_key(self._dataset_symbol):
- data_point = slice[self._dataset_symbol]
- self.log(f"{self._dataset_symbol} value at {slice.time}: {data_point.value}")
- public override void OnData(Slice slice)
-{
- if (slice.ContainsKey(_datasetSymbol))
- {
- var dataPoint = slice[_datasetSymbol];
- Log($"{_datasetSymbol} value at {slice.Time}: {dataPoint.Value}");
- }
-}
-
-
- To get historical Fear and Greed data, call the
-
- History
-
-
- history
-
- method with the dataset
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self._dataset_symbol, 100, Resolution.DAILY) - -# Dataset objects -history = self.history[FearGreedIndex](self._dataset_symbol, 100, Resolution.DAILY)-
var history = History<FearGreedIndex>(_datasetSymbol, 100, Resolution.Daily);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To remove a subscription to the Fear and Greed dataset, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self._dataset_symbol)-
RemoveSecurity(_datasetSymbol);-
- The Fear and Greed dataset quantifies the degree of fear and greed in the US Equity market. Example use cases include the following strategies: -
-- The following example algorithm buys SPY when the Fear and Greed index is less than 25 (extreme fear) and sells when it's above 75 (extreme greed). -
-from AlgorithmImports import *
-
-
-class FearAndGreedExampleAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- # Add the market index to trade.
- self._equity = self.add_equity('SPY', Resolution.DAILY)
- # Add the Fear and Greed dataset.
- self._dataset_symbol = self.add_data(FearGreedIndex, 'FG').symbol
-
- def on_data(self, data: Slice) -> None:
- # Wait until the Fear and Greed dataset has new data.
- if self._dataset_symbol not in data:
- return
- value = data[self._dataset_symbol].value
- # Buy when the market is fearful.
- if not self._equity.invested and value < 25:
- self.set_holdings(self._equity.symbol, 1)
- # Sell when the market is greedy.
- elif self._equity.invested and value > 75:
- self.liquidate()
- public class FearAndGreedExampleAlgorithm : QCAlgorithm
-{
- private Equity _equity;
- private Symbol _datasetSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Add the market index to trade.
- _equity = AddEquity("SPY", Resolution.Daily);
- // Add the Fear and Greed dataset.
- _datasetSymbol = AddData<FearGreedIndex>("FG").Symbol;
- }
-
- public override void OnData(Slice data)
- {
- // Wait until the Fear and Greed dataset has new data
- if (!data.ContainsKey(_datasetSymbol))
- {
- return;
- }
- var value = data[_datasetSymbol].Value;
- // Buy when the market is fearful.
- if (!_equity.Invested && value < 25)
- {
- SetHoldings(_equity.Symbol, 1);
- }
- // Sell when the market is greedy.
- else if (_equity.Invested && value > 75)
- {
- Liquidate();
- }
- }
-}
- - The following example algorithm buys SPY when the Fear and Greed index is less than 25 (extreme fear) and sells when it's above 75 (extreme greed). -
-from AlgorithmImports import *
-
-
-class FearAndGreedExampleAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- # Trade SPY on a daily basis.
- self.universe_settings.resolution = Resolution.DAILY
- symbols = [Symbol.create('SPY', SecurityType.EQUITY, Market.USA)]
- self.add_universe_selection(ManualUniverseSelectionModel(symbols))
- # Add a custom Alpha model that emits insights based on the Fear and Greed dataset.
- self.add_alpha(FearAndGreedAlphaModel(self))
- # Set the equal weighted PCM so the algorithm places trades.
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
-
-
-# Define the custom alpha model.
-class FearAndGreedAlphaModel(AlphaModel):
-
- def __init__(self, algorithm):
- # Create a list to track the current universe.
- self._securities = []
- # Add the Fear and Greed dataset.
- self._dataset_symbol = algorithm.add_data(FearGreedIndex, 'FG').symbol
-
- def update(self, algorithm: QCAlgorithm, data: Slice) -> List[Insight]:
- # Wait until the Fear and Greed dataset has new data.
- if self._dataset_symbol not in data:
- return []
- # Wait until the Fear and Greed index is extreme.
- value = data[self._dataset_symbol].value
- if 25 <= value <= 75:
- return []
- insights = []
- for security in self._securities:
- # Buy when the market is fearful.
- if not security.invested and value < 25:
- direction = InsightDirection.UP
- # Sell when the market is greedy.
- elif security.invested and value > 75:
- direction = InsightDirection.FLAT
- else:
- continue
- insights.append(Insight.price(security.symbol, timedelta(2*365), direction))
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- # When assets enter the universe, save them.
- for security in changes.added_securities:
- self._securities.append(security)
- # When assets leave the universe, remove them.
- for security in changes.removed_securities:
- if security in self._securities:
- self._securities.remove(security)
- public class FearAndGreedExampleAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Trade SPY on a daily basis.
- UniverseSettings.Resolution = Resolution.Daily;
- var symbols = new[] { QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA) };
- AddUniverseSelection(new ManualUniverseSelectionModel(symbols));
- // Add a custom Alpha model that emits insights based on the Fear and Greed dataset.
- AddAlpha(new FearAndGreedAlphaModel(this));
- // Set the equal weighted PCM so the algorithm places trades.
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- }
-}
-
-// Define the custom Alpha model.
-public class FearAndGreedAlphaModel : AlphaModel
-{
- // Create a list to track the current universe.
- private List<Security> _securities = new List<Security>();
- private Symbol _datasetSymbol;
-
- public FearAndGreedAlphaModel(QCAlgorithm algorithm)
- {
- // Add the Fear and Greed dataset.
- _datasetSymbol = algorithm.AddData<FearGreedIndex>("FG").Symbol;
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
- {
- // Wait until the Fear and Greed dataset has new data.
- if (!data.ContainsKey(_datasetSymbol))
- {
- return Enumerable.Empty<Insight>();
- }
- // Wait until the Fear and Greed index is extreme.
- var value = data[_datasetSymbol].Value;
- if (value >= 25 && value <= 75)
- {
- return Enumerable.Empty<Insight>();
- }
-
- var insights = new List<Insight>();
- foreach (var security in _securities)
- {
- InsightDirection direction;
- // Buy when the market is fearful.
- if (!security.Invested && value < 25)
- {
- direction = InsightDirection.Up;
- }
- // Sell when the market is greedy.
- else if (security.Invested && value > 75)
- {
- direction = InsightDirection.Flat;
- }
- else
- {
- continue;
- }
- insights.Add(Insight.Price(security.Symbol, TimeSpan.FromDays(2 * 365), direction));
- }
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- // When assets enter the universe, save them.
- foreach (var security in changes.AddedSecurities)
- {
- _securities.Add(security);
- }
- // When assets leave the universe, remove them.
- foreach (var security in changes.RemovedSecurities)
- {
- _securities.Remove(security);
- }
- }
-}
-
- The Fear and Greed dataset provides
-
- FearGreedIndex
-
- objects, which have the following attributes:
-
- -
- The International Future Universe dataset by QuantConnect lists the available International Future contracts, their daily trading volume, and Open Interest. The data covers 4 contracts (DAX, FESX, HSI, and NKD), starts in July 1998, and is delivered on daily frequency. This dataset is created by monitoring the trading activity on the EUREX, HKFE, and CME. -
-- This dataset depends on the - - US Futures Security Master - - dataset because the US Futures Security Master dataset contains information on symbol changes of the contracts. -
-
- This dataset
-
- does not
-
- contain market data. For market data, see
-
- International Futures by TickData
-
- and
-
- US Futures by AlgoSeek
-
- for NKD.
-
- For more information about the International Future Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The International Futures Universe dataset provides data for contract filtering/selection: -
-hsi = self.add_future(Futures.Indices.HANG_SENG, Resolution.MINUTE) # "HSI" -hsi.set_filter(0, 90) -dax = self.add_future(Futures.Indices.DAX, Resolution.MINUTE) # "DAX" -dax.set_filter(0, 90) -fesx = self.add_future(Futures.Indices.EURO_STOXX_50, Resolution.MINUTE) # "FESX" -fesx.set_filter(0, 90) -nkd = self.add_future(Futures.Indices.NIKKEI_225_DOLLAR, Resolution.MINUTE) # "NKD" -nkd.set_filter(0, 90)-
var hsi= AddFuture(Futures.Indices.HangSeng, Resolution.Minute) // "HSI"; -hsi.SetFilter(0, 90); -var dax = AddFuture(Futures.Indices.Dax, Resolution.Minute) // "DAX"; -dax.SetFilter(0, 90); -var fesx = AddFuture(Futures.Indices.EuroStoxx50, Resolution.Minute) // "FESX"; -fesx.SetFilter(0, 90); -var nkd = AddFuture(Futures.Indices.Nikkei225Dollar, Resolution.Minute) // "NKD"; -nkd.SetFilter(0, 90);-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -
- July 1998 (for details, see
-
- Supported Assets
-
- )
- |
-
| - Coverage - | -- 4 Contracts - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -
- Various (for details, see
-
- Supported Assets
-
- )
- |
-
| - Market Hours - | -- - Regular and Extended - - | -
- To add International Future Universe data to your algorithm, call the
-
- AddFuture
-
-
- add_future
-
- method. Save a reference to the Future object so you can access the data later in your algorithm. To define which contracts should be in your universe, specify the filter when requesting the Future data.
-
- The
-
- AddFuture
-
-
- add_future
-
- method provides a daily stream of Future chain data. To get the most recent daily chain, call the
-
- FuturesChain
-
-
- futures_chain
-
- method with the underlying Future Symbol. The
-
- FuturesChain
-
-
- futures_chain
-
- method returns data on all the tradable contracts, not just the contracts that pass your universe filter.
-
class InternationalFuturesDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2013, 12, 20) - self.set_end_date(2014, 2, 20) - self.set_cash(1000000) - self.universe_settings.asynchronous = True - self._future = self.add_future(Futures.Indices.HANG_SENG) - # Set our contract filter for this Future chain. - self._future.set_filter(lambda universe: universe.standards_only().front_month()) - # Get the entire Futures chain for the current day. - chain = self.futures_chain(self._future.symbol, flatten=True).data_frame-
public class InternationalFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _future;
-
- public override void Initialize()
- {
- SetStartDate(2013, 12, 20);
- SetEndDate(2014, 2, 20);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
- var future = AddFuture(Futures.Indices.HangSeng);
- // Set our contract filter for this Future chain.
- _future.SetFilter((universe) => universe.StandardsOnly().FrontMonth());
- // Get the entire Futures chain for the current day.
- var chain = FuturesChain(_future.Symbol);
- }
-}
- - For more information about creating Future Universes, see - - Futures - - . -
- - - -- For information about accessing International Future Universe data, see - - Futures - - . -
- - - -- You can get historical International Future Universe data in an algorithm and the Research Environment. -
-
- To get historical International Future Universe data in an algorithm, call the
-
- History<FutureUniverse>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a lookback period. This method returns the all the available contracts for each trading day, not the subset of contracts that pass your universe filter. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and save a reference to it. -future = self.add_future(Futures.Indices.HANG_SENG) - -# DataFrame example where the columns are the FutureUniverse attributes: -history_df = self.history(FutureUniverse, future.symbol, 5, flatten=True) - -# Series example where the values are lists of FutureUniverse objects: -history_series = self.history(FutureUniverse, future.symbol, 5, flatten=False) - -# FutureUniverse objects example: -history = self.history[FutureUniverse](future.symbol, 5)-
// Add the Future and save a reference to it. -var future = AddFuture(Futures.Indices.HangSeng); - -// Get historical data. -var history = History<FutureUniverse>(future.Symbol, 5);-
- For more information about historical International Future Universe data in algorithms, see - - Contracts - - . -
-
- To get historical International Future Universe data in the Research Environment, call the
-
- History<FutureUniverse>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a time period. This method returns the all the available contracts for each trading day, not the subset of contracts that pass your universe filter. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and save a reference to it. -future = qb.add_future(Futures.Indices.HANG_SENG) - -# DataFrame example where the columns are the FutureUniverse attributes: -history_df = qb.history(FutureUniverse, future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1), flatten=True) - -# Series example where the values are lists of FutureUniverse objects: -history_series = qb.history(FutureUniverse, future.symbol, 5, flatten=False) - -# FutureUniverse objects example: -history = qb.history[FutureUniverse](future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1))-
// Add the Future and save a reference to it. -var future = qb.AddFuture(Futures.Indices.HangSeng); - -// Get historical data. -var history = qb.History<FutureUniverse>(future.Symbol, new DateTime(2025, 1, 1), new DateTime(2025, 4, 1));-
- For more information about historical International Future Universe data in the Research Environment, see - - Daily Prices History - - . -
- - - -- The following table shows the available Futures: -
-| - Ticker - | -- Future - | -- Start Date - | -- Time Zone - | -- Currency - | -
|---|---|---|---|---|
| - HSI - | -- Hang Seng Index Futures - | -- Jan 2010 - | -- Asia/Hong Kong - | -- HKD - | -
| - DAX - | -- German Index Futures - | -- Jan 2010 - | -- Europe/Berlin - | -- EUR - | -
| - FESX - | -- EURO STOXX 50 Index Futures - | -- Jul 1998 - | -- Europe/Berlin - | -- EUR - | -
| - NKD - | -- Nikkei 225 Index Futures - | -- Jan 2007 - | -- America/Chicago - | -- USD - | -
- The International Futures Universe dataset enables you to design Futures strategies accurately. Examples include the following strategies: -
-- The following example algorithm uses the - - ZigZag indicator - - to determine the trend of Hang Seng Index. It then trades the Index with HSI Futures. -
-from AlgorithmImports import *
-
-
-class InternationalFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Set the time zone to HKT to make it more comparable with the exchange.
- self.set_time_zone(TimeZones.HONG_KONG)
- # Set the account currency as HKD to trade HSI Futures.
- self.set_account_currency("HKD", 1000000)
- # Seed the last price of the contracts for filling.
- self.settings.seed_initial_prices = True
-
- # Request HSI Futures to trade.
- # Note that we will trade the contract with the highest open interest for liquidity.
- self.hsi_future = self.add_future(
- Futures.Indices.HANG_SENG,
- extended_market_hours=True,
- data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
- contract_depth_offset=0
- )
- # Adds contracts that expiry within 90 days. We will trade the farthest contract
- self.hsi_future.set_filter(0,90)
- # Request the corresponding underlying Index for feeding indicator for trade signal generation.
- hsi_index = self.add_index("HSI").symbol
-
- # Create a ZigZag indicator to trade Hang Seng Index price pivot points.
- self._zz = self.zz(hsi_index, 0.15, 5, Resolution.DAILY)
- # Warm up indicator for immediate readiness to trade.
- self.warm_up_indicator(hsi_index, self._zz, Resolution.DAILY)
-
- def on_data(self, slice: Slice) -> None:
- # Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if self.is_market_open(self.hsi_future.symbol) and self._zz.is_ready:
- pivot = self._zz.pivot_type
- # If the last pivot point is a low point, the current trend is increasing after this low point.
- if pivot == PivotPointType.LOW:
- contracts = sorted([x.symbol for x in slice.future_chains.get(self.hsi_future.symbol)],
- key=lambda x: x.id.date)
- self.set_holdings(contracts[-1], 0.2)
- # If the last pivot point is a high point, the current trend is decreasing after this high point.
- if pivot == PivotPointType.HIGH:
- contracts = sorted([x.symbol for x in slice.future_chains.get(self.hsi_future.symbol)],
- key=lambda x: x.id.date)
- self.set_holdings(contracts[-1], -0.2)
- public class InternationalFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _hsiFuture;
- private ZigZag _zz;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Set the time zone to HKT to make it more comparable with the exchange.
- SetTimeZone(TimeZones.HongKong);
- // Set the account currency as HKD to trade HSI Futures.
- SetAccountCurrency("HKD", 1000000);
-
- // Seed the last price of the contracts for filling.
- Settings.SeedInitialPrices = true;
-
- // Request HSI Futures to trade.
- // Note that we will trade the contract with the highest open interest for liquidity.
- _hsiFuture = AddFuture(
- Futures.Indices.HangSeng,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.LastTradingDay,
- contractDepthOffset: 0
- );
- // Adds contracts that expiry within 90 days. We will trade the farthest contract
- _hsiFuture.SetFilter(0,90);
- // Request the corresponding underlying index for feeding indicators for trade signal generation.
- var hsiIndex = AddIndex("HSI").Symbol;
-
- // Create a ZigZag indicator to trade Hang Seng Index price pivot points.
- _zz = ZZ(hsiIndex, 0.15m, 5, Resolution.Daily);
- // Warm up indicator for immediate readiness to trade.
- WarmUpIndicator(hsiIndex, _zz, Resolution.Daily);
- }
-
- public override void OnData(Slice slice)
- {
- // Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if (IsMarketOpen(_hsiFuture.Symbol) && _zz.IsReady)
- {
- var pivot = _zz.PivotType;
- FuturesChain chain;
- // If the last pivot point is low, the current trend is increasing after this low point.
- if (pivot == PivotPointType.Low && slice.FutureChains.TryGetValue(_hsiFuture.Symbol, out chain))
- {
- var contract = chain.OrderBy(x => x.Expiry).LastOrDefault()?.Symbol;
- SetHoldings(contract, 0.2m);
- }
- // If the last pivot point is high, the current trend decreases after this high point.
- if (pivot == PivotPointType.High && slice.FutureChains.TryGetValue(_hsiFuture.Symbol, out chain))
- {
- var contract = chain.OrderBy(x => x.Expiry).LastOrDefault()?.Symbol;
- SetHoldings(contract, -0.2m);
- }
- }
- }
-}
-
- The International Future Universe dataset provides
-
- FutureFilterUniverse
-
- and
-
- FutureUniverse
-
- objects.
-
-
- FutureFilterUniverse
-
- objects have the following attributes:
-
-
- FutureUniverse
-
- objects have the following attributes:
-
- -
- The US ETF Constituents dataset by QuantConnect tracks the constituents and weighting of US Equities in 2,650 ETF listings. The data starts in June 2009 and is delivered on a daily basis (monthly basis before January 2015). This dataset is created by tracking the host ETF websites and can be delayed by up to 1 week. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- For more information about the US ETF Constituents dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 160,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US ETF Constituents dataset: -
-def initialize(self) -> None:
- self.universe_settings.asynchronous = True
- # Use the following method for a Classic Algorithm
- self._universe = self.add_universe(self.universe.etf("SPY", Market.USA, self.universe_settings, self.etf_constituents_filter))
-
- symbol = Symbol.create("SPY", SecurityType.EQUITY, Market.USA)
- # Use the following method for a Framework Algorithm
- self.add_universe_selection(ETFConstituentsUniverseSelectionModel(symbol, self.universe_settings, self.etf_constituents_filter))
-
- def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
- # Add all Symbols of the ETFConstituentUniverse
- return [x.symbol for x in constituents]
- public override void Initialize()
-{
- UniverseSettings.Asynchronous = true;
- // Use the following method for a Classic Algorithm
- _universe = AddUniverse(Universe.ETF("SPY", Market.USA, UniverseSettings, ETFConstituentsFilter));
-
- var symbol = QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA);
- // Use the following method for a Framework Algorithm
- AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(symbol, UniverseSettings, ETFConstituentsFilter));
-}
-private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable <ETFConstituentUniverse> constituents)
-{
- // Add all Symbols of the ETFConstituentUniverse
- return constituents.Select(x => x.Symbol);
-}
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- June 2009 - | -
| - Asset Coverage - | -- 2,650 US ETF Listings - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily (Monthly before Jan 2015) - | -
| - Timezone - | -- New York - | -
- To add US ETF Constituents data to your algorithm, call the
-
- AddUniverse
-
-
- add_universe
-
- and
-
- Universe.ETF
-
-
- universe.etf
-
- methods. To select which constituents occupy the universe, provide the ETF
-
- Symbol
-
- and a selection function.
-
class ETFConstituentUniverseAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2018, 1, 1)
- self.set_end_date(2020, 8, 25)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- self._universe = self.add_universe(self.universe.etf("SPY", self.universe_settings, self.etf_constituents_filter))
- public class ETFConstituentUniverseAlgorithm : QCAlgorithm
-{
- private Universe _universe;
-
- public override void Initialize()
- {
- SetStartDate(2018, 1, 1);
- SetEndDate(2020, 8, 25);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- _universe = AddUniverse(Universe.ETF("SPY", UniverseSettings, ETFConstituentsFilter));
- }
-}
-
- - For more information about universe settings, see - - Settings - - . -
- - - -
- To access the US ETF Constituent data, use the
-
- ETFConstituentUniverse
-
- objects in your selection function. The data is available in daily resolution. The
-
- Symbol
-
- objects you return from your selection function defines the universe constituents.
-
def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
- for c in constituents:
- self.debug(f'{c.end_time} :: {c.last_update} :: {c.weight} :: {c.shares_held} :: {c.market_value}')
- return [x.symbol for x in constituents]
-
-public IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents)
-{
- foreach (var c in constituents)
- {
- Debug($"{c.EndTime} :: {c.LastUpdate} :: {c.Weight} :: {c.SharesHeld} :: {c.MarketValue}");
- }
-
- return constituents.Select(c => c.Symbol);
-}
-
- - You can get historical universe data in an algorithm and in the Research Environment. -
-
- To get historical universe data in an algorithm, call the
-
- History
-
-
- history
-
- method with the
-
- Universe
-
- object and the lookback period. If there is no data in the period you request, the history result is empty.
-
var history = History(_universe, 30, Resolution.Daily);
-foreach (var constituents in history)
-{
- foreach (ETFConstituentUniverse constituent in constituents)
- {
- Log($"{constituent.Symbol} weight at {constituent.EndTime}: {constituent.Weight}");
- }
-}
- # DataFrame example where the columns are the ETFConstituentUniverse attributes:
-df_history = self.history(self.universe, 30, Resolution.DAILY, flatten=True)
-
-# Series example where the values are lists of ETFConstituentUniverse objects:
-series_history = self.history(self.universe, 30, Resolution.DAILY)
-for (universe_symbol, time), constituents in series_history.items():
- for constituent in constituents:
- self.log(f'{constituent.symbol} weight at {constituent.end_time}: {constituent.weight}')
-
- To get historical universe data in research, call the
-
- UniverseHistory
-
-
- universe_history
-
- method with the
-
- Universe
-
- object and the lookback period. The
-
- UniverseHistory
-
-
- universe_history
-
- returns the filtered universe. If there is no data in the period you request, the history result is empty.
-
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var constituents in universeHistory )
-{
- foreach (ETFConstituentUniverse constituent in constituents)
- {
- Console.WriteLine($"{constituent.Symbol} weight at {constituent.EndTime}: {constituent.Weight}");
- }
-}
- # DataFrame example where the columns are the ETFConstituentUniverse attributes:
-df_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
-
-# Series example where the values are lists of ETFConstituentUniverse objects:
-series_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), constituents in series_history.items():
- for constituent in constituents:
- print(f"{constituent.symbol} weight at {constituent.end_time}: {constituent.weight}")
-
- You can call the
-
- History
-
-
- history
-
- method in Research.
-
- The following table shows the available ETFs: -
- - - - -- The ETF Constituents dataset provides an excellent source of tradable universes for strategies without selection bias. When you use an ETF universe, the original ETF can serve as an excellent benchmark for your strategy performance. Other use cases include the following: -
-- The following example algorithm creates a dynamic universe of the 10 largest US Equities in the SPY ETF. Each day, the algorithm forms a dollar-neutral and market-neutral portfolio by buying the 10 ETF constituents and shorting the SPY ETF. -
-from AlgorithmImports import *
-
-
-class ETFConstituentUniverseAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- # Add the SPY to trade.
- self._spy = self.add_equity("SPY").symbol
- # Add an ETF constituents universe that selects the large caps
- # in SPY. Save the universe object so you can get history
- # for the universe.
- universe = self.add_universe(
- self.universe.etf(
- self._spy,
- universe_filter_func=self._select_assets
- )
- )
- # Get historical universe data.
- history = self.history(universe, 30, Resolution.DAILY, flatten=True)
- # Show an example of wrangling the historical data.
- etf_weights = history.weight.unstack(1)
- # Create a dictionary to store the ETF weights each day.
- self._weight_by_symbol = {}
- # Add a Scheduled Event to rebalance the portfolio each day.
- self.schedule.on(
- self.date_rules.every_day(self._spy),
- self.time_rules.after_market_open(self._spy, 1),
- self._rebalance
- )
-
- def _select_assets(
- self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
- # Select the 10 largest stocks in the SPY.
- selected = sorted(
- [c for c in constituents if c.weight],
- key=lambda c: c.weight
- )[-10:]
- # Save the weights for position sizing.
- self._weight_by_symbol = {c.symbol: c.weight for c in selected}
- # Return the selected assets.
- return list(self._weight_by_symbol.keys())
-
- def _rebalance(self) -> None:
- # Create a long-short portfolio to earn the excess return of the
- # top 10 weighted stocks from SPY.
- spy_weight = sum(self._weight_by_symbol.values())
- targets = [PortfolioTarget(self._spy, -0.5)]
- for symbol, weight in self._weight_by_symbol.items():
- targets.append(PortfolioTarget(symbol, 0.5*weight/spy_weight))
- # Liquidate the stocks that aren't in top 10.
- self.set_holdings(targets, True)
-
- public class ETFConstituentUniverseAlgorithm : QCAlgorithm
-{
- private Symbol _spy;
- // Create a dictionary to store the ETF weights each day.
- private Dictionary<Symbol, decimal> _weightBySymbol = new();
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Add the SPY to trade.
- _spy = AddEquity("SPY").Symbol;
- // Add an ETF constituents universe that selects the large caps
- // in SPY. Save the universe object so you can get history
- // for the universe.
- var universe = AddUniverse(Universe.ETF(_spy, universeFilterFunc: SelectAssets));
- // Get historical universe data.
- var history = History(universe, 30, Resolution.Daily);
- // Show an example of iterating through the historical data.
- foreach (var constituents in history)
- {
- var t = constituents.EndTime;
- foreach (ETFConstituentUniverse constituent in constituents)
- {
- var symbol = constituent.Symbol;
- var weight = constituent.Weight;
- }
- }
- // Add a Scheduled Event to rebalance the portfolio each day.
- Schedule.On(DateRules.EveryDay(_spy), TimeRules.AfterMarketOpen(_spy, 1), Rebalance);
- }
-
- private IEnumerable<Symbol> SelectAssets(IEnumerable<ETFConstituentUniverse> constituents)
- {
- // Select the 10 largest stocks in the SPY.
- _weightBySymbol = constituents.OrderByDescending(c => c.Weight).Take(10)
- // Save the weights for position sizing.
- .ToDictionary(c => c.Symbol, c => c.Weight ?? 0m);
- // Return the selected assets.
- return _weightBySymbol.Keys;
- }
-
- private void Rebalance()
- {
- // Create a long-short portfolio to earn the excess return of the
- // top 10 weighted stocks from SPY.
- var spyWeight = _weightBySymbol.Values.Sum();
- var targets = new List<PortfolioTarget>() { new PortfolioTarget(_spy, -0.5m) };
- foreach (var kvp in _weightBySymbol)
- {
- targets.Add(new PortfolioTarget(kvp.Key, 0.5m * kvp.Value / spyWeight));
- }
- // Liquidate the stocks that aren't in top 10.
- SetHoldings(targets, true);
- }
-}
- - The following example algorithm creates a dynamic universe of the 10 largest US Equities in the SPY ETF. Each day, the algorithm forms a dollar-neutral and market-neutral portfolio by buying the 10 ETF constituents and shorting the SPY ETF. -
-class ETFConstituentUniverseFrameworkAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- self.universe_settings.asynchronous = False
- self.universe_settings.resolution = Resolution.MINUTE
- self.weight_by_symbol = {}
-
- # Add universe selection on SPY's constituents to select only from large cap stocks
- # Save the universe to access its members for historical data call
- spy = self.add_equity("SPY").symbol
- self.add_universe_selection(ETFConstituentsUniverseSelectionModel(spy, self.universe_settings, self.etf_constituents_filter))
-
- # Add alpha model that set normalized weight as investment insight
- self.add_alpha(ETFConstituentsAlphaModel(self, spy))
-
- # Set up portfolio construction model that invest by the insight weights
- pcm = InsightWeightingPortfolioConstructionModel()
- # Avoid excessive rebalance on insight changes
- pcm.rebalance_on_insight_changes = False
- self.set_portfolio_construction(pcm)
-
- self.add_risk_management(NullRiskManagementModel())
-
- self.set_execution(ImmediateExecutionModel())
-
- def etf_constituents_filter(self, constituents: List[ETFConstituentUniverse]) -> List[Symbol]:
- # The top 10 weighted securities are considered better active selections
- # Save the weights for position sizing
- selected = sorted([c for c in constituents if c.weight],
- key=lambda c: c.weight, reverse=True)[:10]
- self.weight_by_symbol = {c.symbol: c.weight for c in selected}
-
- return list(self.weight_by_symbol.keys())
-
-class ETFConstituentsAlphaModel(AlphaModel):
-
- def __init__(self, algorithm: QCAlgorithm, etf: Symbol) -> None:
- self.algorithm = algorithm
- self.etf = etf
- self.day = -1
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- # Rebalance daily since selection is on daily basis
- if self.day == algorithm.time.day:
- return []
-
- self.day = algorithm.time.day
-
- insights = []
-
- # Create a long-short portfolio to earn excess return of the top 10 weighted stocks from SPY
- etf_weight = sum(self.algorithm.weight_by_symbol.values())
- if etf_weight> 0:
- # Invest half the portfolio by normalized weights of the top 10 constituents
- for symbol, weight in self.algorithm.weight_by_symbol.items():
- if algorithm.securities.contains_key(symbol):
- insights.append(Insight.price(symbol, Expiry.END_OF_DAY, InsightDirection.UP, weight=0.5*weight/etf_weight))
-
- # Short the other half with SPY, looking to profit from the active selection
- insights.append(Insight.price(self.etf, Expiry.END_OF_DAY, InsightDirection.DOWN, weight=0.5))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- # Liquidate the ones not in top 10 weights
- symbols = [x.symbol for x in changes.removed_securities if x.invested]
- algorithm.liquidate(symbols, tag='Removed From Universe')
- public class ETFConstituentUniverseFrameworkAlgorithm : QCAlgorithm
-{
- public Dictionary<Symbol, decimal> WeightBySymbol = [];
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- UniverseSettings.Asynchronous = false;
- UniverseSettings.Resolution = Resolution.Minute;
-
- // Add universe selection on SPY's constituents to select only from large cap stocks
- // Save the universe to access its members for historical data call
- var spy = AddEquity("SPY").Symbol;
- AddUniverseSelection(new ETFConstituentsUniverseSelectionModel(spy, UniverseSettings, ETFConstituentsFilter));
-
- // Add alpha model that set normalized weight as investment insight
- AddAlpha(new ETFConstituentsAlphaModel(this, spy));
-
- // Set up portfolio construction model that invest by the insight weights
- SetPortfolioConstruction(new InsightWeightingPortfolioConstructionModel
- {
- // Avoid excessive rebalance on insight changes
- RebalanceOnInsightChanges = false
- });
-
- AddRiskManagement(new NullRiskManagementModel());
-
- SetExecution(new ImmediateExecutionModel());
- }
-
- private IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents)
- {
- // The top 10 weighted securities are considered better active selections
- // Save the weights for position sizing
- WeightBySymbol = constituents.Where(c=> c.Weight.HasValue).OrderByDescending(c => c.Weight).Take(10)
- .ToDictionary(c => c.Symbol, c => c.Weight.Value);
-
- return WeightBySymbol.Keys;
- }
-}
-
-public class ETFConstituentsAlphaModel : AlphaModel
-{
- private int _day = -1;
- private Symbol _etf;
- private ETFConstituentUniverseFrameworkAlgorithm _algorithm;
-
- public ETFConstituentsAlphaModel(ETFConstituentUniverseFrameworkAlgorithm algorithm, Symbol etf)
- {
- _etf = etf;
- _algorithm = algorithm;
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- // Rebalance daily since selection is on daily basis
- if (_day == algorithm.Time.Day)
- {
- return [];
- }
-
- _day = algorithm.Time.Day;
-
- var insights = new List<Insight>();
-
- // Create a long-short portfolio to earn excess return of the top 10 weighted stocks from SPY
- var etfWeight = (double)_algorithm.WeightBySymbol.Values.Sum();
- if (etfWeight > 0)
- {
- // Invest half the portfolio by normalized weights of the top 10 constituents
- foreach(var kvp in _algorithm.WeightBySymbol)
- {
- insights.Add(Insight.Price(kvp.Key, Expiry.EndOfDay, InsightDirection.Up, weight: (double)kvp.Value/etfWeight * 0.5));
- }
-
- // Short the other half with SPY, looking to profit from the active selection
- insights.Add(Insight.Price(_etf, Expiry.EndOfDay, InsightDirection.Down, weight: 0.5));
- }
-
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- // Liquidate the ones not in top 10 weights
- var symbols = changes.RemovedSecurities.Where(x => x.Invested).Select(x => x.Symbol);
- algorithm.Liquidate(symbols, tag: "Removed From Universe");
- }
-}
- - The following example lists ETF constituents with the greatest weight in the SPY: -
-var qb = new QuantBook();
-
-// Add the ETF
-var symbol = qb.AddEquity("SPY").Symbol;
-
-// Add ETF Universe Selection
-IEnumerable<Symbol> ETFConstituentsFilter(IEnumerable<ETFConstituentUniverse> constituents)
-{
- // Take the top 10 weighted constituents
- return constituents
- .OrderByDescending(c => c.Weight)
- .Take(10)
- .Select(c => c.Symbol);
-}
-
-var universe = qb.AddUniverse(qb.Universe.ETF(spy, qb.UniverseSettings, ETFConstituentsFilter));
-
-// Historical Universe data
-var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var constituents in universeHistory )
-{
- foreach (ETFConstituentUniverse constituent in constituents)
- {
- Console.WriteLine($"{constituent.Symbol} weight at {constituent.EndTime}: {constituent.Weight}");
- }
-}
- qb = QuantBook()
-
-# Add the ETF
-qb.spy = qb.add_equity("SPY").symbol
-
-# Add ETF Universe Selection
-def etf_constituents_filter(constituents):
- # Take the top 10 weighted constituents
- selected = sorted([c for c in constituents if c.weight],
- key=lambda c: c.weight, reverse=True)[:10]
- return [c.symbol for c in selected]
-
-universe = qb.add_universe(qb.universe.etf(qb.spy, qb.universe_settings, etf_constituents_filter))
-
-# Historical Universe data
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), constituents in universe_history.items():
- for constituent in constituents:
- print(f"{constituent.symbol} weight at {constituent.end_time}: {constituent.weight}")
-
- The ETF Constituents dataset provides
-
- ETFConstituentUniverse
-
- objects, which have the following attributes:
-
- -
- The US Equity Short Availability dataset provides the available shares for open short positions and their borrowing cost in the US Equity market. The data covers 10,500 US Equities, starts in January 2018, and is delivered on a daily frequency. This dataset is created using information from the exchanges. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- For more information about the US Equities Short Availability dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippets demonstrate how to request data from the US Equities Short Availability dataset. -
-security.set_shortable_provider(InteractiveBrokersShortableProvider())-
security.SetShortableProvider(new InteractiveBrokersShortableProvider());-
security.set_shortable_provider(LocalDiskShortableProvider("axos"))
- security.SetShortableProvider(new LocalDiskShortableProvider("axos"));
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2018 - | -
| - Asset Coverage - | -- 10,500 US Equities - | -
| - Data Density - | -- Sparse - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- To add US Equities Short Availability data to your algorithm, set the - - shortable provider - - of each US Equity in your algorithm. -
-class ShortAvailabilityDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2019, 1, 1)
- security = self.add_equity("AAPL")
- # Set shortable provider as IB
- security.set_shortable_provider(InteractiveBrokersShortableProvider())
- self._symbol = security.symbol
- public class ShortAvailabilityDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2019, 1, 1);
- var security = AddEquity("AAPL");
- // Set shortable provider as IB
- security.SetShortableProvider(new InteractiveBrokersShortableProvider());
- _symbol = security.Symbol;
- }
-}
-
- To check how many shares are available for a security to short, call the
-
- ShortableQuantity
-
-
- shortable_quantity
-
- method of the
-
- ShortableProvider
-
-
- shortable_provider
-
-
var shortableProvider = Securities[_symbol].ShortableProvider; -// Get the shortable quantity of the selected symbol at the selected time -var shortableQuantity = shortableProvider.ShortableQuantity(_symbol, Time); - -// Check if there are a certain quantity of shares available -var quantity = 100; -var isShortableQuantity = Shortable(_symbol, quantity);-
shortable_provider = self.securities[self._symbol].shortable_provider -# Get the shortable quantity of the selected symbol at the selected time -shortable_quantity = shortable_provider.shortable_quantity(self._symbol, self.time) - -# Check if there are a certain quantity of shares available -quantity = 100; -is_shortable_quantity = self.shortable(self._symbol, quantity)-
- To check borrowing cost, call the
-
- FeeRate
-
-
- fee_rate
-
- or
-
- RebateRate
-
-
- rebate_rate
-
- method of the
-
- ShortableProvider
-
-
- shortable_provider
-
-
var feeRate = shortableProvider.FeeRate(_symbol, Time); -var rebateRate = shortableProvider.RebateRate(_symbol, Time);-
fee_rate = shortable_provider.fee_rate(self._symbol, self.time); -rebate_rate = shortable_provider.rebate_rate(self._symbol, self.time);-
- The US Equities Short Availability dataset enables you to accurately design strategies harnessing information about short availability. Examples include the following use cases: -
-- The following example algorithm shorts GameStop every day there are shares available to short. If the algorithm receives a margin call, it liquidates the position and start again on the next day. -
-from AlgorithmImports import *
-
-class ShortAvailabilityDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000)
- # Seed the security price as the last known price, such that the price data is immediately available at initial rebalance
- self.settings.seed_initial_prices = True
- self.add_security_initializer(self._custom_security_initializer)
-
- self.equity = self.add_equity("GME")
-
- # Set up daily rebalance scheduled event, since shortable quantity is updated daily
- self.schedule.on(
- self.date_rules.every_day(self.equity.symbol),
- self.time_rules.after_market_open(self.equity.symbol, 10),
- self.rebalance)
-
- def rebalance(self) -> None:
- symbol = self.equity.symbol
-
- # You can obtain the shortable quantity to decide the submission of a short order
- shortable_quantity = self.equity.shortable_provider.shortable_quantity(symbol, self.time)
- if not shortable_quantity:
- shortable_quantity = 0
- # Fee and rebate rate is also available, such that you can calculate the expected return and decide if the margin is worthwhile
- self.plot('Total Shortable Quantity', symbol, shortable_quantity)
- self.plot('Borrowing Cost', "Fee Rate", self.equity.shortable_provider.fee_rate(symbol, self.time))
- self.plot('Borrowing Cost', "Rebate Rate", self.equity.shortable_provider.rebate_rate(symbol, self.time))
-
- # Test whether we can short the desired quantity
- quantity = self.calculate_order_quantity(symbol, -1)
- if quantity and self.shortable(symbol, quantity):
- self.market_order(symbol, quantity)
-
- def on_margin_call_warning(self) -> None:
- self.liquidate()
-
- def _custom_security_initializer(self, security: Security) -> None:
- # Set the shortable provider as your broker for accurate short reality modeling
- security.set_shortable_provider(InteractiveBrokersShortableProvider())
- public class ShortAvailabilityDataAlgorithm : QCAlgorithm
-{
- private Equity _equity;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000);
- // Seed the security price as the last known price, such that the price data is immediately available at initial rebalance
- Settings.SeedInitialPrices = true;
- AddSecurityInitializer(security =>
- {
- // Set the shortable provider as your broker for accurate short reality modeling
- security.SetShortableProvider(new InteractiveBrokersShortableProvider());
- });
-
- _equity = AddEquity("GME");
-
- // Set up daily rebalance scheduled event, since shortable quantity is updated daily
- Schedule.On(
- DateRules.EveryDay(_equity.Symbol),
- TimeRules.AfterMarketOpen(_equity.Symbol, 10),
- Rebalance);
- }
-
- public void Rebalance()
- {
- var symbol = _equity.Symbol;
-
- // You can obtain the shortable quantity to decide the submission of a short order
- // Fee and rebate rate is also available, such that you can calculate the expected return and decide if the margin is worthwhile
- Plot("Total Shortable Quantity", symbol, _equity.ShortableProvider.ShortableQuantity(symbol, Time) ?? 0m);
- Plot("Borrowing Cost", "Fee Rate", _equity.ShortableProvider.FeeRate(symbol, Time));
- Plot("Borrowing Cost", "Rebate Rate", _equity.ShortableProvider.RebateRate(symbol, Time));
-
- // Test whether we can short the desired quantity
- var quantity = CalculateOrderQuantity(symbol, -1m);
- if (quantity != 0 && Shortable(symbol, quantity))
- {
- MarketOrder(symbol, quantity);
- }
- }
-
- public override void OnMarginCallWarning()
- {
- Liquidate();
- }
-}
- - The following example algorithm shorts GameStop every day there are shares available to short. If the algorithm receives a margin call, it liquidates the position and start again on the next day. -
-from AlgorithmImports import *
-
-
-class ShortAvailabilityDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
-
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000)
- # Seed the security price as the last known price, such that the price data is immediately available at initial rebalance
- self.settings.seed_initial_prices = True
- self.add_security_initializer(self._custom_security_initializer)
-
- self.set_universe_selection(ManualUniverseSelectionModel(
- [Symbol.create("GME", SecurityType.EQUITY, Market.USA)]))
-
- # Emit down-direction insights to short all securities in the universe
- self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.DOWN, timedelta(1)))
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
- self.set_execution(ShortableExecutionModel())
-
- # On Margin Call, emit flat-direction insights to liquidate the positions
- def on_margin_call_warning(self) -> None:
- self.emit_insights([Insight.price(kvp.Key, timedelta(1), InsightDirection.FLAT)
- for kvp in self.securities if kvp.Value.invested])
-
- def _custom_security_initializer(self, security: Security) -> None:
- # Set the shortable provider as IB
- security.set_shortable_provider(InteractiveBrokersShortableProvider())
-
-class ShortableExecutionModel(ExecutionModel):
- def __init__(self) -> None:
- self.targets_collection = PortfolioTargetCollection()
-
- def execute(self, algorithm: QCAlgorithm, targets: List[PortfolioTarget]) -> None:
- '''Immediately submits orders for the specified portfolio targets.
- Args:
- algorithm: The algorithm instance
- targets: The portfolio targets to be ordered'''
-
- # for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
- self.targets_collection.add_range(targets)
- if self.targets_collection.count > 0:
- for target in self.targets_collection.order_by_margin_impact(algorithm):
- # calculate remaining quantity to be ordered
- quantity = OrderSizing.get_unordered_quantity(algorithm, target)
- # If the quantity is negative, ensure that the security is shortable
- if quantity > 0 or algorithm.shortable(target.symbol, quantity):
- algorithm.market_order(target.symbol, quantity)
-
- self.targets_collection.clear_fulfilled(algorithm)
- public class ShortAvailabilityDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000);
- // Seed the security price as the last known price, such that the price data is immediately available at initial rebalance
- Settings.SeedInitialPrices = true;
- AddSecurityInitializer(security =>
- {
- // Set the shortable provider as your broker for accurate short reality modeling
- security.SetShortableProvider(new InteractiveBrokersShortableProvider());
- });
-
- SetUniverseSelection(new ManualUniverseSelectionModel(
- QuantConnect.Symbol.Create("GME", SecurityType.Equity, Market.USA)));
-
- // Emit down-direction insights to short all securities in the universe
- SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Down, TimeSpan.FromDays(1)));
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- SetExecution(new ShortableExecutionModel());
- }
-
- // On Margin Call, emit flat-direction insights to liquidate the positions
- public override void OnMarginCallWarning()
- {
- EmitInsights(Securities
- .Where(kvp => kvp.Value.Invested)
- .Select(kvp => Insight.Price(kvp.Key, TimeSpan.FromDays(1), InsightDirection.Flat))
- .ToArray());
- }
-
- public class ShortableExecutionModel : ImmediateExecutionModel
- {
- private readonly PortfolioTargetCollection _targetsCollection = new PortfolioTargetCollection();
-
- public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets)
- {
- _targetsCollection.AddRange(targets);
- // for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
- if (_targetsCollection.Count > 0)
- {
- foreach (var target in _targetsCollection.OrderByMarginImpact(algorithm))
- {
- // calculate remaining quantity to be ordered
- var quantity = OrderSizing.GetUnorderedQuantity(algorithm, target);
- // If the quantity is negative, ensure that the security is shortable
- if (quantity > 0 || algorithm.Shortable(target.Symbol, quantity))
- {
- algorithm.MarketOrder(target.Symbol, quantity);
- }
- }
-
- _targetsCollection.ClearFulfilled(algorithm);
- }
- }
- }
-}
-
- The US Equities Short Availability data is a
-
- Symbol
-
- /decimal pair for
-
- ShortQuantity
-
- ,
-
- FeeRate
-
- ,
- and
-
- RebateRate
-
- .
-
- -
- The US Equity Coarse Universe dataset by QuantConnect is a daily universe of all trading stocks in the US for a given day with the end of day price and volume. The data covers 30,000 US Equities in total, with approximately 8,000 Equities per day. The data starts in January 1998 and is delivered each trading day. This dataset is created by taking the closing auction price tick from the daily L1 trade and quote exchange dumps. -
-- This dataset depends on the - - US Equities by AlgoSeek - - dataset because - - universe selection - - adds and removes market data subscriptions and on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- QuantConnect/LEAN combines the data of this dataset with - - MorningStar Fundamental data - - in runtime. You can use this dataset in local development without the Morningstar counterpart. -
-- For more information about the US Equity Coarse Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US Equity Coarse Universe dataset: -
-equity = self.add_equity("IBM")
-ibm_fundamental = equity.fundamentals
- var equity = AddEquity("IBM");
-var ibmFundamental = equity.Fundamentals;
- ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-ibm_fundamental = self.fundamentals
- var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-var ibmFundamental = Fundamentals(ibm);
- def initialize(self) -> None: - # Universe selection - self._universe = self.add_universe(self.fundamental_filter_function) - -def fundamental_filter_function(self, fundamental: List[Fundamental]): - # Sort all equities with price above $10 by dollar volume - sorted_by_dollar_volume = sorted([f for f in fundamental if f.price > 10], - key=lambda f: f.dollar_volume, reverse=True) - # Take the top 10 - return [f.symbol for f in sorted_by_dollar_volume[:10]]-
public override void Initialize()
-{
- // Universe selection
- _universe = AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
-}
-
-public override List<Symbol> FundamentalFilterFunction(List<Fundamental> fundamental)
-{
- // Sort all equities with price above $10 by dollar volume, take the top 10
- return (from f in fundamental
- where f.Price > 10
- orderby f.DollarVolume descending
- select f.Symbol).Take(10);
-}
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 1998 - | -
| - Asset Coverage - | -- 30,000 US Equities - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- This dataset doesn't include Over-the-Counter (OTC) stocks. -
- - - -- You don't need any special code to request US Coarse Fundamental Data. You can access the current and historical fundamental data for any of the US Equities that this dataset includes. -
-class CoarseFundamentalDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2021, 1, 1)
- self.set_end_date(2021, 7, 1)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
-
- # Option 1: Subscribe to individual US Equity assets
- self.add_equity("IBM")
-
- # Option 2A: Create a fundamental universe (classic version)
- self._universe = self.add_universe(self.fundamental_function)
-
- # Option 2B: Create a fundamental universe (framework version)
- self.add_universe_selection(FundamentalUniverseSelectionModel(self.fundamental_function))
- public class CoarseFundamentalDataAlgorithm : QCAlgorithm
-{
- private Universe _universe;
- public override void Initialize()
- {
- SetStartDate(2021, 1, 1);
- SetEndDate(2021, 7, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
-
- // Option 1: Subscribe to individual US Equity assets
- AddEquity("IBM");
-
- // Option 2A: Create a fundamental universe (classic version)
- _universe = AddUniverse(FundamentalFilterFunction);
-
- // Option 2B: Create a fundamental universe (framework version)
- AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
- }
-}
- - For more information about universe settings, see - - Settings - - . -
- - - -- If you add a - - fundamental universe - - to your algorithm, you can access fundamental data in the universe selection function. -
-def fundamental_function(self, fundamental: List[Fundamental]) -> List[Symbol]:
- sorted_by_dollar_volume = sorted(fundamental, key=lambda x: x.dollar_volume, reverse=True)[:3]
- for cf in sorted_by_dollar_volume:
- self.debug(f"{cf.end_time} :: {cf.symbol} : {cf.adjusted_price} :: {cf.dollar_volume}")
-
- return [ x.symbol for x in sorted_by_dollar_volume]
- public IEnumerable<Symbol> FundamentalFunction(IEnumerable<Fundamental> fundamental)
-{
- var sortedByDollarVolume = fundamental
- .OrderByDescending(x => x.DollarVolume)
- .Take(3).ToList();
-
- foreach (var cf in sortedByDollarVolume)
- {
- Debug($"{cf.EndTime} :: {cf.Symbol} : {cf.AdjustedPrice} :: {cf.DollarVolume}");
- }
-
- return sortedByDollarVolume.Select(x => x.Symbol);
-}
-
- To get fundamental data for Equities in your algorithm, use the
-
- Fundamentals
-
-
- fundamentals
-
- property of the
-
- Equity
-
- objects. The fundamental data represent the corporate fundamentals for the current algorithm time.
-
fundamentals = self.securities[symbol].fundamentals-
var fundamentals = Securities[symbol].Fundamentals;-
- To get fundamental data for Equities, regardless of whether or not you have subscribed to them in your algorithm, call the
-
- Fundamentals
-
-
- fundamentals
-
- method. If you pass one
-
- Symbol
-
- , the method returns a
-
- Fundamental
-
- object. If you pass a list of
-
- Symbol
-
- objects, the method returns a list of
-
- Fundamental
-
- objects.
-
// Single asset
-var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-var ibmFundamental = Fundamentals(ibm);
-
-// Multiple assets
-var nb = QuantConnect.Symbol.Create("NB", SecurityType.Equity, Market.USA);
-var fundamentals = Fundamentals(new List<Symbol>{ nb, ibm }).ToList();
- # Single asset
-ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-ibm_fundamental = self.fundamentals(ibm)
-
-# Multiple assets
-nb = Symbol.create("NB", SecurityType.EQUITY, Market.USA)
-fundamentals = self.fundamentals([ nb, ibm ])
- - You can get historical fundamental data in an algorithm and in the Research Environment. -
-
- To get historical fundamental data in an algorithm, call the
-
- History
-
-
- history
-
- method with
-
- Fundamental
-
- type and the Equity
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-
-// Fundamental objects
-var fundamentalHistory = History<Fundamental>(ibm, TimeSpan.FromDays(30));
-
-// Fundamentals objects for all US Equities (including delisted companies)
-var fundamentalsHistory = History<Fundamentals>(TimeSpan.FromDays(30));
-
-// Collection of Fundamental objects for all US Equities (including delisted companies)
-var collectionHistory = History(_universe, 30, Resolution.Daily);
-foreach (var fundamental in collectionHistory)
-{
- // Cast to Fundamental is required
- var mostLiquid = fundamental.OfType<Fundamental>().OrderByDescending(x => x.DollarVolume).Take(5);
-}
- ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-
-# DataFrame of fundamental data for a given asset
-df_history = self.history(Fundamental, ibm, timedelta(30), flatten=True)
-
-# Fundamental objects
-fundamental_history = self.history[Fundamental](ibm, timedelta(30))
-
-# Fundamentals objects for all US Equities (including delisted companies)
-fundamentals_history = self.history[Fundamentals](timedelta(30))
-
-# DataFrame of fundamental data for universe constituents
-df_history = self.history(self._universe, 30, Resolution.DAILY, flatten=True)
-
-# Series of fundamental data for universe constituents
-series_history = self.history(self._universe, 30, Resolution.DAILY)
-for (universe_symbol, time), fundamental in series_history.items():
- most_liquid = sorted(fundamental, key=lambda x: x.dollar_volume)[-5:]
-
- To get historical universe data in the Research Environment, call the
-
- UniverseHistory
-
-
- universe_history
-
- method with the
-
- Universe
-
- object and the lookback period. This method returns the filtered universe. If there is no data in the period you request, the history result is empty.
-
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var fundamentals in universeHistory)
-{
- foreach (Fundamental fundamental in fundamentals)
- {
- Console.WriteLine($"{fundamental.Symbol} dollar volume at {fundamental.EndTime}: {fundamental.DollarVolume}");
- }
-}
- # DataFrame of fundamental data for universe constituents
-df_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
-
-# Series of fundamental data for universe constituents
-series_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), fundamentals in series_history.items():
- for fundamental in fundamentals:
- print(f"{fundamental.symbol} dollar volume at {fundamental.end_time}: {fundamental.dollar_volume}")
- - For more information about historical US Equity fundamental data, see - - Equity Fundamental Data - - . -
- - - -- The US Equity Coarse Universe dataset enables you to accurately design a universe of US Equities. Examples include the following strategies: -
-
- Fundamental
-
- objects)
- - The following example algorithm creates a dynamic universe of the three most liquid US Equities. Each time the universe changes, the algorithm forms an equal-weighted portfolio of the three companies. -
-from AlgorithmImports import * - - -class USEquityCoarseUniverseConstituentsDataAlgorithm(QCAlgorithm): - - _number_of_symbols = 3 - _changes = None - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - self.set_cash(100000) - # Set Asynchronous to True to improve speed performance. - self.universe_settings.asynchronous = True - # Add a universe of US Equities. - universe = self.add_universe(self._select_assets) - # Get historical data for the universe. - history = self.history(universe, 30, Resolution.DAILY, flatten=True) - - def _select_assets(self, fundamental: List[Fundamental]) -> List[Symbol]: - # Select the top traded stocks, since they are the most popular - # with high capital flow. - return [ - x.symbol for x in sorted( - fundamental, key=lambda x: x.dollar_volume - )[-self._number_of_symbols:] - ] - - def on_data(self, slice: Slice) -> None: - # If we have no changes, do nothing. - if not slice.bars or self._changes is None: - return - # Liquidate removed securities, since they are not the most - # popular stocks. - for security in self._changes.removed_securities: - if security.invested: - self.liquidate(security.symbol) - # We want 1/N allocation for each security in our universe to - # evenly dissipate risk. - for security in self._changes.added_securities: - self.set_holdings(security.symbol, 1 / self._number_of_symbols) - self._changes = None - - def on_securities_changed(self, changes: SecurityChanges) -> None: - self._changes = changes --
public class USEquityCoarseUniverseConstituentsDataAlgorithm : QCAlgorithm
-{
- private int _numberOfSymbols = 3;
- private SecurityChanges _changes = SecurityChanges.None;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Set Asynchronous to true to improve speed performance
- UniverseSettings.Asynchronous = true;
- // Requesting data
- var universe = AddUniverse(SelectAssets);
- // Get historical data for the universe.
- var history = History(universe, 30, Resolution.Daily);
- foreach (var fundamentals in history)
- {
- // Iterate through each asset in the universe on this day
- // and access its data point attributes.
- foreach (Fundamental f in fundamentals)
- {
- var symbol = f.Symbol;
- var t = f.EndTime;
- var dollarVolume = f.DollarVolume;
- }
- }
- }
-
- public IEnumerable<Symbol> SelectAssets(IEnumerable<Fundamental> fundamental)
- {
- // Select the top traded stocks, since they are the most popular
- // with high capital flow.
- return fundamental.OrderByDescending(x => x.DollarVolume)
- .Take(_numberOfSymbols).Select(x => x.Symbol);
- }
-
- public override void OnData(Slice slice)
- {
- // If we have no changes, do nothing.
- if (slice.Bars.Count == 0 || _changes == SecurityChanges.None) return;
- // Liquidate removed securities, since they are not the most
- // popular stocks.
- foreach (var security in _changes.RemovedSecurities)
- {
- if (security.Invested)
- {
- Liquidate(security.Symbol);
- }
- }
- // We want 1/N allocation for each security in our universe to
- // evenly dissipate risk.
- foreach (var security in _changes.AddedSecurities)
- {
- SetHoldings(security.Symbol, 1m / _numberOfSymbols);
- }
- _changes = SecurityChanges.None;
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- _changes = changes;
- }
-}
- - The following example algorithm creates a dynamic universe of the three most liquid US Equities and forms an equal-weighted portfolio with them. -
-from AlgorithmImports import * - - -class USEquityCoarseUniverseConstituentsDataAlgorithm(QCAlgorithm): - - _number_of_symbols = 3 - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - self.set_cash(100000) - - # Set Asynchronous to True to improve speed performance - self.universe_settings.asynchronous = True - - # Requesting data - self.set_universe_selection( - FundamentalUniverseSelectionModel(self.fundamental_selection_function)) - - # we want 1/N allocation in each security in our universe to evenly dissipate risk - self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1))) - self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel()) - - self.add_risk_management(NullRiskManagementModel()) - - self.set_execution(ImmediateExecutionModel()) - - def fundamental_selection_function(self, fundamental: List[Fundamental]) -> List[Symbol]: - # Select the top traded stocks, since they are the most popular with high capital flow - sorted_by_dollar_volume = sorted(fundamental, key=lambda x: x.dollar_volume, reverse=True) - return [ x.symbol for x in sorted_by_dollar_volume[:self._number_of_symbols] ]-
public class USEquityCoarseUniverseConstituentsDataAlgorithm : QCAlgorithm
-{
- private int _numberOfSymbols = 3;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Set Asynchronous to true to improve speed performance
- UniverseSettings.Asynchronous = true;
-
- // Requesting data
- SetUniverseSelection(
- new FundamentalUniverseSelectionModel(FundamentalSelectionFunction));
-
- // we want 1/N allocation in each security in our universe to evenly dissipate risk
- SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(1)));
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
-
- AddRiskManagement(new NullRiskManagementModel());
-
- SetExecution(new ImmediateExecutionModel());
- }
-
- public IEnumerable<Symbol> FundamentalSelectionFunction(IEnumerable<Fundamental> fundamental)
- {
- // Select the top traded stocks, since they are the most popular with high capital flow
- return fundamental.OrderByDescending(x => x.DollarVolume)
- .Take(_numberOfSymbols).Select(x => x.Symbol);
- }
-}
- - The following example lists the three most liquid US Equities: -
-var qb = new QuantBook();
-
-// Add Fundamental Universe Selection
-IEnumerable<Symbol> FundamentalSelectionFunction(IEnumerable<Fundamental> fundamentals)
-{
- return fundamentals.OrderByDescending(x => c.DollarVolume).Take(10).Select(x => c.Symbol);
-}
-
-var universe = qb.AddUniverse(FundamentalSelectionFunction);
-
-// Historical Universe data
-var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var fundamentals in universeHistory)
-{
- foreach (Fundamental fundamental in fundamentals)
- {
- Console.WriteLine($"{fundamental.Symbol} dollar volume at {fundamental.EndTime}: {fundamental.DollarVolume}");
- }
-}
- qb = QuantBook()
-
-# Add Fundamental Universe Selection
-def fundamental_selection_function(fundamentals):
- selected = sorted(fundamentals, key=lambda x: x.dollar_volume, reverse=True)[:10]
- return [x.symbol for x in selected]
-
-universe = qb.add_universe(fundamental_selection_function)
-
-# Historical Universe data
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), fundamentals in universe_history.items():
- for fundamental in fundamentals:
- print(f"{fundamental.symbol} dollar volume at {fundamental.end_time}: {fundamental.dollar_volume}")
-
- The US Equity Coarse Universe dataset provides its data within
-
- Fundamental
-
- objects, which have the following . The attributes from
-
- market_cap
-
-
- MarketCap
-
- to
-
- asset_classification
-
-
- AssetClassification
-
- listed in the following widget are NaN until this dataset is combined with the
-
- MorningStar Fundamental
-
- dataset.
-
- -
- The US Equity Option Universe dataset by QuantConnect lists the available US Equity Options contracts and the current Implied Volatility and Greeks. The data covers 4,000 Symbols, starts in January 2012, and is delivered on a daily update frequency. To create this dataset, we use - - our implementation - - of the forward tree pricing model, which accounts for the interest rate, dividend payments, and daily closing prices. The values in this dataset are the same values you can get from daily - - indicators - - with mirror Options. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes of the underlying security. -
-
- This dataset
-
- does not
-
- contain market data. For market data, see
-
- US Equity Options by AlgoSeek
-
- .
-
- For more information about the US Equity Option Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US Equity Options Universe dataset: -
-option = self.add_option("GOOG")
-self.option_symbol = option.symbol
-option.set_filter(lambda universe: universe.delta(0.4, 0.6))
- var option = AddOption("GOOG");
-_optionSymbol = option.Symbol;
-option.SetFilter(universe => universe.delta(0.4m, 0.6m));
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012 - | -
| - Asset Coverage - | -- 4,000 Symbols - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- To add US Equity Options Universe data to your algorithm, call the
-
- AddOption
-
-
- add_option
-
- method. Save a reference to the Equity Option
-
- Symbol
-
- so you can access the data later in your algorithm. To define which contracts should be in your universe, call the
-
- SetFilter
-
-
- set_filter
-
- method of the Option object.
-
- The
-
- AddOption
-
-
- add_option
-
- method provides a daily stream of Option chain data. To get the most recent daily chain, call the
-
- OptionChain
-
-
- option_chain
-
- method with the underlying Equity Symbol. The
-
- OptionChain
-
-
- option_chain
-
- method returns data on all the tradable contracts, not just the contracts that pass your universe filter.
-
class USEquityOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2020, 6, 1)
- self.set_end_date(2021, 6, 1)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- option = self.add_option("GOOG")
- self.option_symbol = option.symbol
- # Set our strike/expiry filter for this option chain
- option.set_filter(self._option_filter)
- # Get the entire Option chain for the current day.
- chain = self.option_chain(option.symbol.underlying, flatten=True).data_frame
-
- def _option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Contracts can be filtered by greeks, implied volatility, open interest:
- return universe \
- .delta(0.5, 1.5) \
- .gamma(0.0001, 0.0006) \
- .vega(0.01, 1.5) \
- .theta(-2.0, -0.5) \
- .rho(0.5, 3.0) \
- .implied_volatility(1, 3) \
- .open_interest(100,500)
-
- public class USEquityOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _optionSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- // Requesting data
- var option = AddOption("GOOG");
- _optionSymbol = option.Symbol;
- // Set our strike/expiry filter for this option chain
- option.SetFilter(OptionFilter);
- // Get the entire Option chain for the current day.
- var chain = OptionChain(option.Symbol.Underlying);
- }
-
- private OptionFilterUniverse OptionFilter(OptionFilterUniverse universe)
- {
- // Contracts can be filtered by greeks, implied volatility, open interest:
- return universe
- .Delta(0.5m, 1.5m)
- .Gamma(0.0001m, 0.0006m)
- .Vega(0.01m, 1.5m)
- .Theta(-2.0m, -0.5m)
- .Rho(0.5m, 3.0m)
- .ImpliedVolatility(1.0m, 3.0m)
- .OpenInterest(100, 500);
- }
-}
- - The Equity resolution must be less than or equal to the Equity Option resolution. For example, if you set the Equity resolution to minute, then you must set the Equity Option resolution to minute, hour, or daily. -
-- For more information about creating US Equity Option Universes, see - - Equity Options - - . -
- - - -- For information about accessing US Equity Options Universe data, see - - Equity Options - - . -
- - - -- You can get historical US Equity Options Universe data in an algorithm and the Research Environment. -
-
- To get historical US Equity Options Universe data in an algorithm, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical Equity Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter. If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.option_symbol, timedelta(3), flatten=True) - -# OptionUniverse objects -history = self.history[OptionUniverse](self.option_symbol, timedelta(3))-
// OptionUniverse objects -var history = History<OptionUniverse>(_optionSymbol, TimeSpan.FromDays(3)).ToList();-
- For more information about historical Equity Options Universe data in algorithms, see - - Historical Data - - . -
-
- To get historical US Equity Options Universe data in the Research Environment, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter.
-
qb = QuantBook()
-option = qb.add_option("GOOG")
-history = qb.history(option.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5), flatten=True)
- var qb = new QuantBook();
-var option = qb.AddOption("GOOG");
-var history = qb.History<OptionUniverse>(option.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 6));
-foreach (var chain in history)
-{
- var endTime = chain.EndTime;
- var filteredContracts = chain.Data
- .Select(contract => contract as OptionUniverse)
- .Where(contract => contract.Greeks.Delta > 0.3m);
- foreach (var contract in filteredContracts)
- {
- var price = contract.Price;
- var iv = contract.ImpliedVolatility;
- }
-}
- - For more information about historical Equity Options Universe data in the Research Environment, see - - Universes - - . -
- - - -- To view the supported assets in the US Equity Options Universe dataset, see the - - Data Explorer - - . -
- - - -- The US Equity Options Universe dataset enables you to accurately design Option strategies. Examples include the following strategies: -
-- The following example algorithm subscribes to Google put options that fall within delta range between -1 and -0.95, open interest range between 10 and 1000, and expire within seven days. Within this Option chain, the algorithm holds the put Option contract that has the minimum delta (closest to -1) during market hour to hedge the underlying intra-day movement completely. It avoid volatility from sentiment and only earns from inter-day movement from longer-term factors. When the contract expires, the algorithm rolls over to the next contract that meets this criteria. -
-from AlgorithmImports import *
-
-class USEquityOptionsUniverseAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(10000000)
-
- # Asynchronous can use computational resources efficiently
- self.universe_settings.asynchronous = True
- # Subscribe to the underlying for the underlying position
- # Set the data normalization mode to raw for strike price comparability
- self.equity = self.add_equity("GOOG", data_normalization_mode=DataNormalizationMode.RAW).symbol
- # Requesting option data and filter for the hedge candidates
- option = self.add_option(self.equity)
- option.set_filter(self.option_filter)
- self.option_symbol = option.symbol
-
- # Set scheduled event to buy a hedge option contract at market open to eliminate the intra-day movement
- self.schedule.on(
- self.date_rules.every_day(self.equity),
- self.time_rules.after_market_open(self.equity, 1),
- self.buy_hedge_contract
- )
-
- # Set a scheduled event to sell the hedge contract before market close, since we want to earn from inter-day movement
- # Leave 2 minutes contingency to fill
- self.schedule.on(
- self.date_rules.every_day(self.equity),
- self.time_rules.before_market_close(self.equity, 2),
- self.sell_hedge_contract
- )
-
- self.hedge = None
-
- def option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Select the contracts with delta very close to -1 and high open interest
- # This can effectively hedge most of the price change of the underlying and ensure the liquidity
- # Make sure the contract is expiring close for its tradbility
- return universe.puts_only().expiration(2, 7).delta(-1, -0.95).open_interest(10, 1000)
-
- def buy_hedge_contract(self) -> None:
- chain = self.current_slice.option_chains.get(self.option_symbol)
- if chain:
- # Order the underlying if not hold, the order size should match the option contract
- # Order only if option chain data ready for hedging
- if not self.portfolio[self.equity].invested:
- self.market_order(self.equity, self.securities[self.option_symbol].symbol_properties.contract_multiplier)
-
- # Get the contract with delta closest to -1 (lowest possible delta)
- contract = sorted(chain, key=lambda x: x.greeks.delta)[0]
- self.hedge = contract.symbol
- # Buy 1 deep ITM put with delta close to -1 to eliminate the intraday movement
- self.market_order(self.hedge, 1)
-
- def sell_hedge_contract(self) -> None:
- # Check if any hedge contract position, if so, liquidate before market close to expose to underlying overnight movement
- if self.hedge:
- self.liquidate(self.hedge)
- self.hedge = None
- public class USEquityOptionsUniverseAlgorithm : QCAlgorithm
-{
- private Symbol _equity, _optionSymbol, _hedge;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(10000000);
- // Asynchronous can use computational resources efficiently
- UniverseSettings.Asynchronous = true;
-
- // Subscribe to the underlying for the underlying position
- // Set the data normalization mode to raw for strike price comparability
- _equity = AddEquity("GOOG", dataNormalizationMode: DataNormalizationMode.Raw).Symbol;
- // Requesting option data and filter for the hedge candidates
- var option = AddOption(_equity);
- _optionSymbol = option.Symbol;
- option.SetFilter(OptionFilter);
-
- // Set scheduled event to buy a hedge option contract at market open to eliminate the intra-day movement
- Schedule.On(
- DateRules.EveryDay(_equity),
- TimeRules.AfterMarketOpen(_equity, 1),
- BuyHedgeContract
- );
-
- // Set a scheduled event to sell the hedge contract before market close, since we want to earn from inter-day movement
- // Leave 2 minutes contingency to fill
- Schedule.On(
- DateRules.EveryDay(_equity),
- TimeRules.BeforeMarketClose(_equity, 2),
- SellHedgeContract
- );
- }
-
- private OptionFilterUniverse OptionFilter(OptionFilterUniverse universe)
- {
- // Select the contracts with delta very close to -1 and high open interest
- // This can effectively hedge most of the price change of the underlying and ensure the liquidity
- // Make sure the contract is expiring close for its tradbility
- return universe
- .PutsOnly()
- .Expiration(2, 7)
- .Delta(-1m, -0.95m)
- .OpenInterest(10, 1000);
- }
-
- private void BuyHedgeContract()
- {
- if (CurrentSlice.OptionChains.TryGetValue(_optionSymbol, out var chain))
- {
- // Order the underlying if not hold, the order size should match the option contract
- // Order only if option chain data ready for hedging
- if (!Portfolio[_equity].Invested)
- {
- MarketOrder(_equity, Securities[_optionSymbol].SymbolProperties.ContractMultiplier);
- }
-
- // Get the contract with delta closest to -1 (lowest possible delta)
- var contract = chain.MinBy(x => x.Greeks.Delta);
- _hedge = contract.Symbol;
- // Buy 1 deep ITM put with delta close to -1 to eliminate the intraday movement
- MarketOrder(_hedge, 1);
- }
- }
-
- private void SellHedgeContract()
- {
- // Check if any hedge contract position, if so, liquidate before market close to expose to underlying overnight movement
- if (_hedge != null)
- {
- Liquidate(_hedge);
- _hedge = null;
- }
- }
-}
- - The following example algorithm demonstrating a Gamma Scalping strategy through framework algorithm. It filters NVDA options with expiration between 30 to 90 days and open interest between 50 and 1000, due to liquidity concern and lower Gamma fluctuation. Assuming a significant upward trend is expecting, it orders a long straddle strategy from the strike price with Delta-neutral and the highest Gamma to earn the highest profit from upward underlying movement. -
-from AlgorithmImports import *
-
-class USEquityOptionsUniverseFrameworkAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- # Asynchronous can use computational resources efficiently
- self.universe_settings.asynchronous = True
-
- # Universe selection that select based on liquidity of the option contracts (by open interest)
- self.add_universe_selection(EquityOptionsUniverseSelectionModel())
- # Custom alpha model that use Delta and Gamma to signal insights
- self.add_alpha(OptionDeltaGammaAlphaModel())
- # To maintain long-short size equal, use a PCM that order a single contract
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-class EquityOptionsUniverseSelectionModel(OptionUniverseSelectionModel):
- def __init__(self) -> None:
- # Daily update with the select_option_chain_symbols function
- super().__init__(timedelta(1), self.select_option_chain_symbols)
-
- def select_option_chain_symbols(self, dt: datetime) -> List[Symbol]:
- # Select only NVDA options as our focus, which is a highly traded volatile equity with great upward momentum
- return [Symbol.create("NVDA", SecurityType.OPTION, Market.USA)]
-
- def filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # To ensure the liquidity and tradability, make sure the option is not 0-DTE and have a fair open interest
- # A longer TTM will have lower Gamma thus more stable in the local delta-neutral position
- return universe.expiration(30, 90).open_interest(50, 1000)
-
-class OptionDeltaGammaAlphaModel(AlphaModel):
- def __init__(self) -> None:
- # A day count variable to control the alpha model only trade once a day
- self._day = -1
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
-
- if self._day != slice.time.day:
- # We open position for each option underlying as separate bet
- for _, chain in slice.option_chains.items():
- # For theta-neutral, select the same expiry for both call and put
- expiry = min(x.expiry for x in chain)
- contracts = [x for x in chain if x.expiry == expiry]
-
- # Calculate delta and gamma per strike price group for later filtering, ensure both call and put available for option strategy
- delta_gamma_symbols = []
- strikes = set(x.strike for x in contracts if len([y for y in contracts if y.strike == x.strike]) == 2)
- for strike in strikes:
- # Get both call and put for their aggregated delta and gamma
- call = next(filter(lambda x: x.right == OptionRight.CALL and x.strike == strike, contracts))
- put = next(filter(lambda x: x.right == OptionRight.PUT and x.strike == strike, contracts))
- delta_gamma_symbols.append((call.greeks.delta + put.greeks.delta, call.greeks.gamma + put.greeks.gamma, call.symbol, put.symbol))
-
- if len(delta_gamma_symbols) == 0:
- continue
-
- # We want a delta-neutral position, so it is likely to be ATM (like a long straddle)
- # Less than 2d.p. difference is non-significant, which we can risk for better reward
- # Assuming the market direction is up in most scenario, we try to get the strike providing max overall Gamma
- # Make sure the aggregated gamma to be positive to bet on large uptrend
- # So it will earn more when the price really go up higher and higher, but locally immune for small noise
- filtered = [item for item in delta_gamma_symbols if round(item[0], 2) <= 0.01 and item[1] > 0]
- if len(filtered) == 0:
- continue
- selected = sorted(filtered, key=lambda x: x[1], reverse=True)[0]
-
- # Provide trade signal and roll the day count to let the position stay for the whole day
- selected_call = selected[2]
- selected_put = selected[3]
- insights.extend([
- Insight.price(selected_call, Expiry.END_OF_DAY, InsightDirection.UP),
- Insight.price(selected_put, Expiry.END_OF_DAY, InsightDirection.UP)
- ])
- self._day = slice.time.day
-
- return insights
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- # Use a whole number target to order the exact number of share for size-matching
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class USEquityOptionsUniverseFrameworkAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Asynchronous can use computational resources efficiently
- UniverseSettings.Asynchronous = true;
-
- // Universe selection that select based on liquidity of the option contracts (by open interest)
- AddUniverseSelection(new EquityOptionsUniverseSelectionModel());
- // Custom alpha model that use Delta and Gamma to signal insights
- AddAlpha(new OptionDeltaGammaAlphaModel());
- // To maintain long-short size equal, use a PCM that order a single contract
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-class EquityOptionsUniverseSelectionModel : OptionUniverseSelectionModel
-{
- // Daily update with the SelectOptionChainSymbols function
- public EquityOptionsUniverseSelectionModel()
- : base(TimeSpan.FromDays(1), SelectOptionChainSymbols) {}
-
- private static IEnumerable<Symbol> SelectOptionChainSymbols(DateTime utcTime)
- {
- // Select only NVDA options as our focus, which is a highly traded volatile equity with great upward momentum
- return new[] {QuantConnect.Symbol.Create("NVDA", SecurityType.Option, Market.USA)};
- }
-
- protected override OptionFilterUniverse Filter(OptionFilterUniverse filter)
- {
- // To ensure the liquidity and tradability, make sure the option is not 0-DTE and have a fair open interest
- // A longer TTM will have lower Gamma thus more stable in the local delta-neutral position
- return filter
- .Expiration(30, 90)
- .OpenInterest(50, 1000);
- }
-}
-
-class OptionDeltaGammaAlphaModel : AlphaModel
-{
- // A day count variable to control the alpha model only trade once a day
- private int _day = -1;
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- if (_day != slice.Time.Day)
- {
- // We open position for each option underlying as separate bet
- foreach (var kvp in slice.OptionChains)
- {
- var chain = kvp.Value;
-
- // For theta-neutral, select the same expiry for both call and put
- var expiry = chain.Min(x => x.Expiry);
- var contracts = chain.Where(x => x.Expiry == expiry).ToList();
-
- // Calculate delta and gamma per strike price group for later filtering, ensure both call and put available for option strategy
- var deltaGammaSymbols = new List<(decimal, decimal, Symbol, Symbol)>();
- var strikes = contracts.Select(x => x.Strike)
- .Where(x => contracts.Count(y => y.Strike == x) == 2)
- .Distinct();
- foreach (var strike in strikes)
- {
- // Get both call and put for their aggregated delta and gamma
- var call = contracts.Single(x => x.Right == OptionRight.Call && x.Strike == strike);
- var put = contracts.Single(x => x.Right == OptionRight.Put && x.Strike == strike);
- deltaGammaSymbols.Add((call.Greeks.Delta + put.Greeks.Delta, call.Greeks.Gamma + put.Greeks.Gamma, call.Symbol, put.Symbol));
- }
-
- if (deltaGammaSymbols.Count == 0)
- {
- continue;
- }
-
- // We want a delta-neutral position, so it is likely to be ATM (like a long straddle)
- // Less than 2d.p. difference is non-significant, which we can risk for better reward
- // Assuming the market direction is up in most scenario, we try to get the strike providing max overall Gamma
- // Make sure the aggregated gamma to be positive to bet on large uptrend
- // So it will earn more when the price really go up higher and higher, but locally immune for small noise
- var filtered = deltaGammaSymbols.Where(item => Math.Round(item.Item1, 2) <= 0.01m && item.Item2 > 0).ToList();
- if (filtered.Count == 0)
- {
- continue;
- }
- var selected = filtered.OrderByDescending(item => item.Item2).First();
-
- // Provide trade signal and roll the day count to let the position stay for the whole day
- var selectedCall = selected.Item3;
- var selectedPut = selected.Item4;
- insights.AddRange(new[] {
- Insight.Price(selectedCall, Expiry.EndOfDay, InsightDirection.Up),
- Insight.Price(selectedPut, Expiry.EndOfDay, InsightDirection.Up)
- });
- _day = slice.Time.Day;
- }
- }
-
- return insights;
- }
-}
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- // Use a whole number target to order the exact number of share for size-matching
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Equity Options Universe dataset provides
-
- OptionFilterUniverse
-
- ,
-
- OptionUniverse
-
- , and
-
- OptionChain
-
- objects.
-
-
- OptionFilterUniverse
-
- objects have the following attributes:
-
-
- OptionUniverse
-
- objects have the following attributes:
-
-
- OptionChain
-
- objects have the following attributes:
-
- -
- The US Equity Security Master dataset by QuantConnect tracks US Equity corporate actions, including splits, dividends, delistings, mergers, and ticker changes through history. The data covers approximately 27,500 US Equities, starts in January 1998, and is delivered on a daily update frequency. You can easily download and install the dataset with the LEAN CLI so it's ready to use by LEAN. LEAN automatically handles all corporate actions and passes them into your algorithm as - - events - - . -
-
- This is
-
- NOT
-
- the underlying Equity data (
-
- US Equities
-
- dataset), which you need to purchase separately with a license from AlgoSeek. This security master dataset is required to purchase the US Equities or US Equities Options datasets.
-
- For more information about the US Equity Security Master dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- Data is delivered as a daily updated zip archive of map and factor files. The data is designed to be used in the LEAN Engine and cannot be consumed another way. The following table shows the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 1998 - | -
| - Data Points - | -- Splits, Dividends, Mergers, IPO, & Delistings - | -
| - Asset Coverage - | -- 27,500 US Equities - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- This is
-
- not
-
- the underlying Equity data (
-
- US Equities
-
- dataset), which you need to purchase separately with a license from AlgoSeek. This security master dataset is required to purchase the US Equities or US Equities Options datasets.
-
- You don't need any special code to utilize the US Equity Security Master. It automatically loads when you - - request US Equities data - - . -
- - - -
- To get the current split data, index the
-
- Splits
-
-
- splits
-
- property of the current
-
-
- Slice
-
-
- with the Equity
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Check if any splits for the symbol
- if slice.splits.contains_key(self._symbol):
- # If so, get the mapped split object
- split = slice.splits[self._symbol]
- split_type = {0: "Warning", 1: "SplitOccurred"}.get(split.type)
- self.log(f"Split: {split.symbol}\t{split.split_factor}\t{split.reference_price}\t{split_type}")
- public override void OnData(Slice slice)
-{
- // Check if any splits for the symbol
- if (slice.Splits.ContainsKey(_symbol))
- {
- // If so, get the mapped split object
- var split = slice.Splits[_symbol];
- Log($"Split: {split.Symbol}\t{split.SplitFactor}\t{split.ReferencePrice}\t{split.Type}");
- }
-}
- - For more information about accessing splits, see - - Splits - - . -
- - - -
- To get the current dividend data, index the
-
- Dividends
-
-
- dividends
-
- property of the current
-
- Slice
-
- with the Equity
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Check if any dividend for the symbol
- if slice.dividends.contains_key(self._symbol):
- # If so, get the mapped dividend object
- dividend = slice.dividends[self._symbol]
- self.log(f'Dividend: {dividend.symbol}\t{dividend.distribution}\t{dividend.reference_price}')
- public override void OnData(Slice slice)
-{
- // Check if any dividend for the symbol
- if (slice.Dividends.ContainsKey(_symbol))
- {
- // If so, get the mapped dividend object
- var dividend = slice.Dividends[_symbol];
- Log($"Dividend: {dividend.Symbol}\t{dividend.Distribution}\t{dividend.ReferencePrice}");
- }
-}
- - For more information about accessing dividends, see - - Dividends - - . -
- - - -
- To get the current Delistings data, index the
-
- Delistings
-
-
- delistings
-
- property of the current
-
- Slice
-
- with the Equity
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Check if any delisting for the symbol
- if slice.delistings.contains_key(self._symbol):
- # If so, get the mapped delisting object
- delisting = slice.delistings[self._symbol]
- delisting_type = {0: "Warning", 1: "Delisted"}.get(delisting.type)
- self.log(f'Delistings: {delisting_type}')
- public override void OnData(Slice slice)
-{
- // Check if any delisting for the symbol
- if (slice.Delistings.ContainsKey(_symbol))
- {
- // If so, get the mapped delisting object
- var delisting = slice.Delistings[_symbol];
- Log($"Delistings: {delisting.Type}");
- }
-}
- - For more information about accessing delistings, see - - Delistings - - . -
- - - -
- To get the current Symbol change events, index the
-
- SymbolChangedEvents
-
-
- symbol_changed_events
-
- property of the current
-
- Slice
-
- with the Equity
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Check if any symbol change event for the symbol
- if slice.symbol_changed_events.contains_key(self._symbol):
- # If so, get the mapped SymbolChangeEvent object
- symbol_changed_event = slice.symbol_changed_events[self._symbol]
- self.log(f"Symbol changed: {symbol_changed_event.old_symbol} -> {symbol_changed_event.new_symbol}")
-
-
-public override void OnData(Slice slice){
- // Check if any symbol change event for the symbol
- if (slice.SymbolChangedEvents.ContainsKey(_symbol))
- {
- // If so, get the mapped SymbolChangeEvent object
- var symbolChangedEvent = slice.SymbolChangedEvents[_symbol];
- Log($"Symbol changed: {symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.NewSymbol}");
- }
-}
- - For more information about accessing Symbol change events, see - - Symbol Changes - - . -
- - - -
- To get historical US Equity Security Master data, call the
-
- History
-
-
- history
-
- method with the data type and the Equity
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# Splits -split_history_df = self.history(Split, self._symbol, timedelta(5*365)) -split_history = self.history[Split](self._symbol, timedelta(5*365)) - -# Dividends -dividend_history_df = self.history(Dividend, self._symbol, timedelta(5*365)) -dividend_history = self.history[Dividend](self._symbol, timedelta(5*365)) - -# Symbol Changes -symbol_change_history_df = self.history(SymbolChangedEvent, self._symbol, timedelta(5*365)) -symbol_change_history = self.history[SymbolChangedEvent](self._symbol, timedelta(5*365)) - -# Delistings -delisting_history_df = self.history(Delisting, self._symbol, timedelta(5*365)) -delisting_history = self.history[Delisting](self._symbol, timedelta(5*365))-
// Splits -var splitHistory = History<Split>(_symbol, TimeSpan.FromDays(5*365)); - -// Dividends -var dividendHistory = History<Dividend>(_symbol, TimeSpan.FromDays(5*365)); - -// Symbol Changes -var symbolChangeHistory = History<SymbolChangedEvent>(_symbol, TimeSpan.FromDays(5*365)); - -// Delistings -var delistingHistory = History<Delisting>(_symbol, TimeSpan.FromDays(5*365));-
- For more information about historical data, see - - History Requests - - . -
- - - -- In backtesting, corporate actions occurs at midnight (ET). In live trading, the live data for corporate actions arrives at 6/7 AM ET, so that's when they occur. -
- - - -- To view the supported assets in the US Equity Security Master dataset, see the - - Data Explorer - - . This dataset doesn't include Over-the-Counter (OTC) stocks. -
- - - -- The US Security Master enables you to accurately design strategies harnessing any core corporate actions. Examples include the following strategies: -
-
- The following example algorithm logs the
-
- Split
-
- ,
-
- Dividend
-
- ,
-
- Delisting
-
- , and
-
- SymbolChangedEvent
-
- objects of Apple:
-
from AlgorithmImports import *
-
-class USEquitySecurityMasterAlgorithm (QCAlgorithm):
-
- def initialize(self):
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000000)
-
- self.equity = self.add_equity("AAPL", Resolution.DAILY).symbol
-
- def on_data(self, slice: Slice) -> None:
- # Accessing Data - Splits
- split = slice.splits.get(self.equity)
- if split:
- self.debug(f"{self.time} >> SPLIT >> {split.symbol} - {split.split_factor} - {self.portfolio.cash} - {self.portfolio[self.equity].price}")
-
- # Accessing Data - Dividends
- dividend = slice.dividends.get(self.equity)
- if dividend:
- self.debug(f"{self.time} >> DIVIDEND >> {dividend.symbol} - {dividend.distribution} - {self.portfolio.cash} - {self.portfolio[self.equity].price}")
-
- # Accessing Data - Delisting
- delisting = slice.delistings.get(self.equity)
- if delisting:
- delistingType = {0: "Warning", 1: "Delisted"}.get(delisting.type)
- self.debug(f"{self.time} >> DELISTING >> {delisting.symbol} - {delistingType}")
-
- # Accessing Data - Symbol Changed Event
- symbolChangedEvent = slice.symbol_changed_events.get(self.equity)
- if symbolChangedEvent:
- self.debug(f"{self.time} >> SYMBOL CHANGED >> {symbolChangedEvent.old_symbol} -> {symbolChangedEvent.new_symbol}")
-
- public class USEquitySecurityMasterAlgorithm : QCAlgorithm
-{
- private Symbol _equity;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
-
- _equity = AddEquity("AAPL", Resolution.Daily).Symbol;
- }
-
- public override void OnData(Slice slice)
- {
- // Accessing Data - Splits
- if (slice.Splits.ContainsKey(_equity))
- {
- var split = slice.Splits[_equity];
- Debug($"Split: {split.Symbol}\t{split.SplitFactor}\t{split.ReferencePrice}\t{split.Type}");
- }
-
- // Accessing Data - Dividends
- if (slice.Dividends.ContainsKey(_equity))
- {
- var dividend = slice.Dividends[_equity];
- Log($"Dividend: {dividend.Symbol}\t{dividend.Distribution}\t{dividend.ReferencePrice}");
- }
-
- // Accessing Data - Delisting
- if (slice.Delistings.ContainsKey(_equity))
- {
- var delisting = slice.Delistings[_equity];
- Log($"Delistings: {delisting.Type}");
- }
-
- // Accessing Data - Symbol Changed Event
- if (slice.SymbolChangedEvents.ContainsKey(_equity))
- {
- var symbolChangedEvent = slice.SymbolChangedEvents[_equity];
- Log($"Symbol changed: {symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.NewSymbol}");
- }
- }
-}
-
- The following algorithm demonstrates the payments for cash dividends in backtesting. When the data normalization mode is
-
- Raw
-
- , your portfolio receives cash dividends.
-
from AlgorithmImports import *
-
-class PaymentAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
-
- # this will use the Tradier Brokerage open order split behavior
- # forward split will modify open order to maintain order value
- # reverse split open orders will be canceled
- self.set_brokerage_model(BrokerageName.TRADIER_BROKERAGE)
-
- self.universe_settings.resolution = Resolution.DAILY
- self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
-
- # MSFT: Splits and Dividends
- # GOOG: Symbol Changed Event
- # AAA.1: Delisting
-
- self.set_universe_selection(ManualUniverseSelectionModel(
- Symbol.create("MSFT", SecurityType.EQUITY, Market.USA)))
-
- self.set_alpha(PaymentAlphaModel())
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
- self.set_execution(BracketExecutionModel())
-
-class PaymentAlphaModel(AlphaModel):
-
- symbol = Symbol.EMPTY
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- # Accessing Data - Splits
- split = slice.splits.get(self.symbol)
- if split:
- algorithm.debug(f"{algorithm.time} >> SPLIT >> {split.symbol} - {split.split_factor} - {algorithm.portfolio.cash} - {algorithm.portfolio[self.symbol].price}")
-
- # Accessing Data - Dividends
- dividend = slice.dividends.get(self.symbol)
- if dividend:
- algorithm.debug(f"{algorithm.time} >> DIVIDEND >> {dividend.symbol} - {dividend.distribution} - {algorithm.portfolio.cash} - {algorithm.portfolio[self.symbol].price}")
-
- # Accessing Data - Delistings
- delisting = slice.delistings.get(self.symbol)
- if delisting:
- delistingType = {0: "Warning", 1: "Delisted"}.get(delisting.type)
- algorithm.debug(f"{algorithm.time} >> DELISTING >> {delisting.symbol} - {delistingType}")
-
- # Accessing Data - Symbol Changed Events
- symbolChangedEvent = slice.symbol_changed_events.get(self.symbol)
- if symbolChangedEvent:
- algorithm.debug(f"{algorithm.time} >> SYMBOL CHANGED >> {symbolChangedEvent.old_symbol} -> {symbolChangedEvent.new_symbol}")
-
- bar = slice.bars.get(self.symbol)
- return [Insight.price(self.symbol, timedelta(1), InsightDirection.UP)] if bar else []
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- self.symbol = list(changes.added_securities)[0].symbol
-
-class BracketExecutionModel(ExecutionModel):
-
- def __init__(self) -> None:
- '''Initializes a new instance of the ImmediateExecutionModel class'''
- self.targets_collection = PortfolioTargetCollection()
-
- def execute(self, algorithm: QCAlgorithm, targets: List[PortfolioTarget]) -> None:
-
- # for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
- self.targets_collection.add_range(targets)
- if self.targets_collection.count > 0:
- for target in self.targets_collection.order_by_margin_impact(algorithm):
- # calculate remaining quantity to be ordered
- quantity = OrderSizing.get_unordered_quantity(algorithm, target)
- if quantity != 0 and algorithm.transactions.orders_count == 0:
- bar = algorithm.securities[target.symbol].get_last_data()
- algorithm.market_order(target.symbol, quantity)
- # place some orders that won't fill, when the split comes in they'll get modified to reflect the split
- algorithm.stop_market_order(target.symbol, -quantity, bar.low/2)
- algorithm.limit_order(target.symbol, -quantity, bar.high*2)
-
- self.targets_collection.clear_fulfilled(algorithm)
-
- public class PaymentsAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
-
- // this will use the Tradier Brokerage open order split behavior
- // forward split will modify open order to maintain order value
- // reverse split open orders will be canceled
- SetBrokerageModel(BrokerageName.TradierBrokerage);
-
- UniverseSettings.Resolution = Resolution.Daily;
- UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw;
-
- // MSFT: Splits and Dividends
- // GOOG: Symbol Changed Event
- // AAA.1: Delisting
- SetUniverseSelection(new ManualUniverseSelectionModel(
- QuantConnect.Symbol.Create("MSFT", SecurityType.Equity, Market.USA)));
-
- SetAlpha(new PaymentAlphaModel());
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- SetExecution(new BracketExecutionModel());
- }
-}
-
-public class PaymentAlphaModel : AlphaModel
-{
- private Symbol _symbol = Symbol.Empty;
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- // Accessing Data - Splits
- if (slice.Splits.ContainsKey(_symbol))
- {
- var split = slice.Splits[_symbol];
- algorithm.Debug($"{split.Time.ToIso8601Invariant()} >> SPLIT >> {split.Symbol} - " +
- $"{split.SplitFactor.ToStringInvariant()} - " +
- $"{algorithm.Portfolio.Cash.ToStringInvariant()} - " +
- $"{algorithm.Portfolio[_symbol].Quantity.ToStringInvariant()}");
- }
-
- // Accessing Data - Dividends
- if (slice.Dividends.ContainsKey(_symbol))
- {
- var dividend = slice.Dividends[_symbol];
- algorithm.Debug($"{dividend.Time.ToStringInvariant("o")} >> DIVIDEND >> {dividend.Symbol} - " +
- $"{dividend.Distribution.ToStringInvariant("C")} - {algorithm.Portfolio.Cash} - " +
- $"{algorithm.Portfolio[_symbol].Price.ToStringInvariant("C")}");
- }
-
- // Accessing Data - Delisting
- if (slice.Delistings.ContainsKey(_symbol))
- {
- var delisting = slice.Delistings[_symbol];
- algorithm.Debug($"{delisting.Time.ToStringInvariant("o")} >> DELISTING >> {delisting.Type}");
- }
-
- // Accessing Data - Symbol Changed Event
- if (slice.SymbolChangedEvents.ContainsKey(_symbol))
- {
- var symbolChangedEvent = slice.SymbolChangedEvents[_symbol];
- algorithm.Debug($"{symbolChangedEvent.Time.ToStringInvariant("o")} >> Symbol Changed Event >> " +
- $"{symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.OldSymbol}");
- }
-
- return slice.Bars.ContainsKey(_symbol)
- ? new [] { Insight.Price(_symbol, TimeSpan.FromDays(1), InsightDirection.Up) }
- : Enumerable.Empty<Insight>();
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- _symbol = changes.AddedSecurities.First().Symbol;
- }
-}
-
-public class BracketExecutionModel : ExecutionModel
-{
- private readonly PortfolioTargetCollection _targetsCollection = new PortfolioTargetCollection();
-
- public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets)
- {
- _targetsCollection.AddRange(targets);
- // for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
- if (_targetsCollection.Count > 0)
- {
- foreach (var target in _targetsCollection.OrderByMarginImpact(algorithm))
- {
- // calculate remaining quantity to be ordered
- var quantity = OrderSizing.GetUnorderedQuantity(algorithm, target);
- if (quantity != 0 && algorithm.Transactions.OrdersCount == 0)
- {
- var bar = algorithm.Securities[target.Symbol].GetLastData() as TradeBar;
- algorithm.MarketOrder(target.Symbol, quantity);
- // place some orders that won't fill, when the split comes in they'll get modified to reflect the split
- algorithm.StopMarketOrder(target.Symbol, -quantity, bar.Low/2);
- algorithm.LimitOrder(target.Symbol, -quantity, bar.High*2);
- }
- }
-
- _targetsCollection.ClearFulfilled(algorithm);
- }
- }
-}
-
- The US Equity Security Master dataset provides
-
- Split
-
- ,
-
- Dividend
-
- ,
-
- Delisting
-
- , and
-
- SymbolChangedEvent
-
- objects.
-
- When a split or merger occurs, we pass the previous
-
- Symbol
-
- data into your algorithm.
-
- Split
-
- objects have the following attributes:
-
- Dividend events are triggered on the payment date.
-
- Dividend
-
- objects have the following attributes:
-
- When a security is delisted, we notify your algorithm.
-
- Delisting
-
- objects have the following attributes:
-
- When a security changes their ticker, we notify your algorithm.
-
- SymbolChangedEvent
-
- objects have the following attributes:
-
- -
- The US Future Option Universe dataset by QuantConnect lists the available US Future Options contracts and the current open interest. The data covers 15 Monthly Future contracts, starts in January 2012, and is delivered on a daily update frequency. This dataset is created by monitoring the trading activity on the CME, CBOT, NYMEX, and COMEX markets. -
-- The US Future Option Universe dataset depends on the - - US Future Universe - - dataset because the US Future Universe dataset contains the universe of underlying Futures contracts. - This dataset also depends on the - - US Futures Security Master - - dataset because the US Futures Security Master dataset contains information on symbol changes of the contracts. -
-
- This dataset
-
- does not
-
- contain market data. For market data, see
-
- US Future Options by AlgoSeek
-
- .
-
- For more information about the US Future Option Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US Future Options Universe dataset: -
-future = self.add_future(Futures.Metals.GOLD, Resolution.MINUTE) -future.set_filter(0, 90) -self.add_future_option(future.symbol, lambda universe: universe.strikes(-1, 1))-
var future = AddFuture(Futures.Metals.Gold, Resolution.Minute); -future.SetFilter(0, 90); -AddFutureOption(future.Symbol, universe => universe.Strikes(-1, 1));-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012 - | -
| - Asset Coverage - | -- 15 Monthly Future Contracts. Standard expires only. No weeklies or 0DTE contracts. - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
| - Market Hours - | -- - Regular and Extended - - | -
- To add US Future Options Universe data to your algorithm, call the
-
- AddFutureOption
-
-
- add_future_option
-
- method. To define which contracts should be in your universe, specify the filter when requesting the Future Option data.
-
- The
-
- AddFutureOption
-
-
- add_future_option
-
- method provides a daily stream of Option chain data. To get the most recent daily chain, call the
-
- OptionChain
-
-
- option_chain
-
- method with the underlying Future Symbol. The
-
- OptionChain
-
-
- option_chain
-
- method returns data on all the tradable contracts, not just the contracts that pass your universe filter.
-
class USFutureOptionsDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2020, 6, 1) - self.set_end_date(2021, 6, 1) - self.set_cash(100000) - self.universe_settings.asynchronous = True - - self.future = self.add_future(Futures.Metals.GOLD, Resolution.MINUTE) - self.future.set_filter(0, 90) - # Set our strike/expiry filter for this option chain - self.add_future_option(self.future.symbol, self._option_filter) - - def on_data(self, slice: Slice) -> None: - # Get the entire Option chain for the current day. - symbol = Symbol.create_canonical_option(self.future.mapped) - chain = self.option_chain(symbol, flatten=True).data_frame - - def _option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse: - # Contracts can be filtered by strike, and expiration - return universe.strikes(-1, 1)-
public class USFutureOptionsDataAlgorithm : QCAlgorithm
-{
- private Future _future;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
-
- _future = AddFuture(Futures.Metals.Gold, Resolution.Minute);
- _future.SetFilter(0, 90);
- // Set our strike/expiry filter for this option chain
- AddFutureOption(_future.Symbol, OptionFilter);
- }
-
- public override void OnData(Slice slice)
- {
- // Create canonical symbol for the mapped future contract, since option chains are mapped by canonical symbol.
- var symbol = QuantConnect.Symbol.CreateCanonicalOption(_future.Mapped);
- // Get the entire Option chain for the current day.
- var chain = OptionChain(symbol);
- }
-
- private OptionFilterUniverse OptionFilter(OptionFilterUniverse universe)
- {
- // Contracts can be filtered by strike, and expiration
- return universe.Strikes(-1, 1);
- }
-}
- - The Future resolution must be less than or equal to the Future Option resolution. For example, if you set the Future resolution to minute, then you must set the Future Option resolution to minute, hour, or daily. -
-- For more information about creating US Future Option universes, see - - Future Options - - . -
- - - -- For information about accessing US Future Options Universe data, see - - Future Options - - . -
- - - -- You can get historical US Future Options Universe data in an algorithm and the Research Environment. -
-
- To get historical US Future Options Universe data in an algorithm, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical mapped Future Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter. If there is no data in the period you request, the history result is empty.
-
future_option_symbol = Symbol.create_canonical_option(self.future.mapped) -# DataFrame -history_df = self.history(future_option_symbol, timedelta(10), flatten=True) -# OptionUniverse objects -history = self.history[OptionUniverse](future_option_symbol, timedelta(10))-
var futureOptionSymbol = QuantConnect.Symbol.CreateCanonicalOption(_future.Mapped); -var history = History<OptionUniverse>(futureOptionSymbol, TimeSpan.FromDays(10)).ToList();-
- For more information about historical US Future Options Universe data in algorithms, see - - Historical Data - - . -
-
- To get historical US Future Options Universe data in the Research Environment, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter.
-
qb = QuantBook() -future = qb.add_future(Futures.Metals.GOLD, Resolution.MINUTE) -future.set_filter(0, 90) -symbol = Symbol.create_canonical_option(future.mapped) -history = qb.history(symbol, datetime(2020, 6, 1), datetime(2020, 6, 5), flatten=True)-
var qb = new QuantBook();
-var future = qb.AddFuture(Futures.Metals.Gold, Resolution.Minute);
-var symbol = QuantConnect.Symbol.CreateCanonicalOption(future.Mapped);
-var history = qb.History<OptionUniverse>(symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 6));
-foreach (var chain in history)
-{
- var endTime = chain.EndTime;
- var filteredContracts = chain.Data
- .Select(contract => contract as OptionUniverse)
- .Where(contract => contract.Greeks.Delta > 0.3m);
- foreach (var contract in filteredContracts)
- {
- var price = contract.Price;
- var iv = contract.ImpliedVolatility;
- }
-}
- - For more information about historical Future Options Universe data in the Research Environment, see - - Universes - - . -
- - - -- The following list shows the available (15) Futures Options: -
-
- Futures.Energy.CrudeOilWTI
-
-
- Futures.Energy.CRUDE_OIL_WTI
-
- : Crude Oil WTI Futures (NYMEX: LO | Underlying: CL)
-
- Futures.Energy.Gasoline
-
-
- Futures.Energy.GASOLINE
-
- : Gasoline RBOB Futures (NYMEX: OB | Underlying: RB)
-
- Futures.Energy.HeatingOil
-
-
- Futures.Energy.HEATING_OIL
-
- : Heating Oil Futures (NYMEX: OH | Underlying: HO)
-
- Futures.Energy.NaturalGas
-
-
- Futures.Energy.NATURAL_GAS
-
- : Natural Gas Futures (NYMEX: ON | Underlying: NG)
-
- Futures.Financials.Y10TreasuryNote
-
-
- Futures.Financials.Y_10_TREASURY_NOTE
-
- : 10Y U.S. Treasury Note Futures (CBOT: OZN | Underlying: ZN)
-
- Futures.Financials.Y2TreasuryNote
-
-
- Futures.Financials.Y_2_TREASURY_NOTE
-
- : 2Y U.S. Treasury Note Futures (CBOT: OZT | Underlying: ZT)
-
- Futures.Financials.Y30TreasuryBond
-
-
- Futures.Financials.Y_30_TREASURY_BOND
-
- : 30Y U.S. Treasury Bond Futures (CBOT: OZB | Underlying: ZB)
-
- Futures.Grains.Corn
-
-
- Futures.Grains.CORN
-
- : Corn Futures (CBOT: OZC | Underlying: ZC)
-
- Futures.Grains.Soybeans
-
-
- Futures.Grains.SOYBEANS
-
- : Soybeans Futures (CBOT: OZS | Underlying: ZS)
-
- Futures.Grains.Wheat
-
-
- Futures.Grains.WHEAT
-
- : Default wheat contract is SRWWheat (CBOT: OZW | Underlying: ZW)
-
- Futures.Indices.NASDAQ100EMini
-
-
- Futures.Indices.NASDAQ_100_E_MINI
-
- : E-mini NASDAQ 100 Futures (CME: NQ)
-
- Futures.Indices.SP500EMini
-
-
- Futures.Indices.SP_500_E_MINI
-
- : E-mini S&P 500 Futures (CME: ES)
-
- Futures.Metals.Copper
-
-
- Futures.Metals.COPPER
-
- : Copper Futures (COMEX: HXE | Underlying: HG)
-
- Futures.Metals.Gold
-
-
- Futures.Metals.GOLD
-
- : Gold Futures (COMEX: OG | Underlying: GC)
-
- Futures.Metals.Silver
-
-
- Futures.Metals.SILVER
-
- : Silver Futures (COMEX: SO | Underlying: SI)
- - The US Future Options dataset enables you to accurately design Future Option strategies. Examples include the following strategies: -
-- The following example demonstrates a bull call spread Option strategy using universe filtering. -
-from AlgorithmImports import * - - -class FutureOptionAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - # Filter the underlying continuous Futures to narrow the FOP spectrum. - self.underlying = self.add_future(Futures.Indices.SP_500_E_MINI, - extended_market_hours=True, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, - contract_depth_offset=0) - self.underlying.set_filter(0, 182) - # Use CallSpread filter to obtain the 2 best-matched contracts that forms a call spread. - # It simplifies from further filtering and reduce computation on redundant subscription. - self.add_future_option(self.underlying.symbol, lambda u: u.call_spread(5, 5, -5)) - - def on_data(self, slice: Slice) -> None: - if self.portfolio.invested: - return - # Create canonical symbol for the mapped future contract, since we need that to access the option chain. - symbol = Symbol.create_canonical_option(self.underlying.mapped) - - # Get option chain data for the mapped future only. - # It requires 2 contracts with different strikes to form a call spread, so we make sure at least 2 contracts are present. - chain = slice.option_chains.get(symbol) - if not chain or len(list(chain)) < 2: - return - - # Separate the contracts by strike, as we need to access their strike. - expiry = min([x.expiry for x in chain]) - sorted_by_strike = sorted([x.strike for x in chain]) - itm_strike = sorted_by_strike[0] - otm_strike = sorted_by_strike[-1] - - # Use abstraction method to order a bull call spread to avoid manual error. - option_strategy = OptionStrategies.bull_call_spread(symbol, itm_strike, otm_strike, expiry) - self.buy(option_strategy, 1)-
public class FutureOptionAlgorithm : QCAlgorithm
-{
- private Future _underlying;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Filter the underlying continuous Futures to narrow the FOP spectrum.
- _underlying = AddFuture(Futures.Indices.SP500EMini,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- contractDepthOffset: 0);
- _underlying.SetFilter(0, 182);
- // Use CallSpread filter to obtain the 2 best-matched contracts that forms a call spread.
- // It simplifies from further filtering and reduce computation on redundant subscription.
- AddFutureOption(_underlying.Symbol, (u) => u.CallSpread(5, 5, -5));
- }
-
- public override void OnData(Slice slice)
- {
- if (Portfolio.Invested)
- return;
-
- // Create canonical symbol for the mapped future contract, since we need that to access the option chain.
- var symbol = QuantConnect.Symbol.CreateCanonicalOption(_underlying.Mapped);
-
- // Get option chain data for the mapped future only.
- // It requires 2 contracts with different strikes to form a call spread, so we make sure at least 2 contracts are present.
- if (!slice.OptionChains.TryGetValue(symbol, out var chain) || chain.Count() < 2)
- return;
-
- // Separate the contracts by strike, as we need to access their strike.
- var expiry = chain.Min(x => x.Expiry);
- var itmStrike = chain.Min(x => x.Strike);
- var otmStrike = chain.Max(x => x.Strike);
-
- // Use abstraction method to order a bull call spread to avoid manual error.
- var optionStrategy = OptionStrategies.BullCallSpread(symbol, itmStrike, otmStrike, expiry);
- Buy(optionStrategy, 1);
- }
-}
-
- The US Future Options Universe dataset provides
-
- OptionFilterUniverse
-
- and
-
- OptionUniverse
-
- objects.
-
-
- OptionFilterUniverse
-
- objects have the following attributes:
-
-
- OptionUniverse
-
- objects have the following attributes:
-
- -
- The US Future Universe dataset by QuantConnect lists the available US Future contracts, their daily trading volume, and Open Interest. The data covers the 157 most liquid contracts, starts in May 2009, and is delivered on daily frequency. This dataset is created by monitoring the trading activity on the CFE, CBOT, CME, COMEX, NYMEX, and ICE - - * - - . -
-- This dataset depends on the - - US Futures Security Master - - dataset because the US Futures Security Master dataset contains information on symbol changes of the contracts. -
-
- This dataset
-
- does not
-
- contain market data. For market data, see
-
- US Futures by AlgoSeek
-
- .
-
- For more information about the US Future Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US Future Universe dataset: -
-future = self.add_future(Futures.Metals.GOLD) -future.set_filter(0, 90)-
var future = AddFuture(Futures.Metals.Gold); -future.SetFilter(0, 90);-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- May 2009 - | -
| - Asset Coverage - | -- 157 Futures - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -
-
|
-
| - Market Hours - | -- - Regular and Extended - - | -
- To add US Future Universe data to your algorithm, call the
-
- AddFuture
-
-
- add_future
-
- method. Save a reference to the Future object so you can access the data later in your algorithm. To define which contracts should be in your universe, specify the filter when requesting the Future data.
-
- The
-
- AddFuture
-
-
- add_future
-
- method provides a daily stream of Future chain data. To get the most recent daily chain, call the
-
- FuturesChain
-
-
- futures_chain
-
- method with the underlying Future Symbol. The
-
- FuturesChain
-
-
- futures_chain
-
- method returns data on all the tradable contracts, not just the contracts that pass your universe filter.
-
class USFutureDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2020, 6, 1) - self.set_end_date(2021, 6, 1) - self.set_cash(100000) - self.universe_settings.asynchronous = True - self._future = self.add_future(Futures.Metals.GOLD) - # Set our contract filter for this Future chain. - self._future.set_filter(lambda universe: universe.standards_only().front_month()) - # Get the entire Futures chain for the current day. - chain = self.futures_chain(self._future.symbol, flatten=True).data_frame-
public class USFutureDataAlgorithm : QCAlgorithm
-{
- private Future _future;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- _future = AddFuture(Futures.Metals.Gold);
- // Set our contract filter for this Future chain.
- _future.SetFilter((universe) => universe.StandardsOnly().FrontMonth());
- // Get the entire Futures chain for the current day.
- var chain = FuturesChain(_future.Symbol);
- }
-}
- - For more information about creating US Future universes, see - - Futures - - . -
- - - -- For information about accessing US Future Universe data, see - - Futures - - . -
- - - -- You can get historical US Future Universe data in an algorithm and the Research Environment. -
-
- To get historical US Future Universe data in an algorithm, call the
-
- History<FutureUniverse>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a lookback period. This method returns the all the available contracts for each trading day, not the subset of contracts that pass your universe filter. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and save a reference to it. -future = self.add_future(Futures.Metals.GOLD) - -# DataFrame example where the columns are the FutureUniverse attributes: -history_df = self.history(FutureUniverse, future.symbol, 5, flatten=True) - -# Series example where the values are lists of FutureUniverse objects: -history_series = self.history(FutureUniverse, future.symbol, 5, flatten=False) - -# FutureUniverse objects example: -history = self.history[FutureUniverse](future.symbol, 5)-
// Add the Future and save a reference to it. -var future = AddFuture(Futures.Metals.Gold); - -// Get historical data. -var history = History<FutureUniverse>(future.Symbol, 5);-
- For more information about historical US Future Universe data in algorithms, see - - Contracts - - . -
-
- To get historical US Future Universe data in the Research Environment, call the
-
- History<FutureUniverse>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a time period. This method returns the all the available contracts for each trading day, not the subset of contracts that pass your universe filter. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and save a reference to it. -future = qb.add_future(Futures.Metals.GOLD) - -# DataFrame example where the columns are the FutureUniverse attributes: -history_df = qb.history(FutureUniverse, future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1), flatten=True) - -# Series example where the values are lists of FutureUniverse objects: -history_series = qb.history(FutureUniverse, future.symbol, 5, flatten=False) - -# FutureUniverse objects example: -history = qb.history[FutureUniverse](future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1))-
// Add the Future and save a reference to it. -var future = qb.AddFuture(Futures.Metals.Gold); - -// Get historical data. -var history = qb.History<FutureUniverse>(future.Symbol, new DateTime(2025, 1, 1), new DateTime(2025, 4, 1));-
- For more information about historical US Future Universe data in the Research Environment, see - - Daily Prices History - - . -
- - - -- The following list shows the available (157) Futures: -
-
- Futures.Currencies.AUD
-
- : Australian Dollar Futures (CME: 6A)
-
- Futures.Currencies.AUDCAD
-
- : Australian Dollar/Canadian Dollar Futures (CME: ACD)
-
- Futures.Currencies.AUDJPY
-
- : Australian Dollar/Japanese Yen Futures (CME: AJY)
-
- Futures.Currencies.AUDNZD
-
- : Australian Dollar/New Zealand Dollar Futures (CME: ANE)
-
- Futures.Currencies.BRL
-
- : Brazillian Real Futures (CME: 6L)
-
- Futures.Currencies.BTC
-
- : Bitcoin Futures (CME: BTC)
-
- Futures.Currencies.BTICMicroBTC
-
-
- Futures.Currencies.BTIC_MICRO_BTC
-
- : BTIC on Micro Bitcoin Futures (CME: MIB)
-
- Futures.Currencies.BTICMicroEther
-
-
- Futures.Currencies.BTIC_MICRO_ETHER
-
- : BTIC on Micro Ether Futures (CME: MRB)
-
- Futures.Currencies.CAD
-
- : Canadian Dollar Futures (CME: 6C)
-
- Futures.Currencies.CADJPY
-
- : Canadian Dollar/Japanese Yen Futures (CME: CJY)
-
- Futures.Currencies.CHF
-
- : Swiss Franc Futures (CME: 6S)
-
- Futures.Currencies.ETH
-
- : Ether Futures (CME: ETH)
-
- Futures.Currencies.EUR
-
- : Euro FX Futures (CME: 6E)
-
- Futures.Currencies.EURAUD
-
- : Euro/Australian Dollar Futures (CME: EAD)
-
- Futures.Currencies.EURCAD
-
- : Euro/Canadian Dollar Futures (CME: ECD)
-
- Futures.Currencies.EuroFXEmini
-
-
- Futures.Currencies.EURO_FX_EMINI
-
- : E-mini Euro FX Futures (CME: E7)
-
- Futures.Currencies.EURSEK
-
- : Euro/Swedish Krona Futures (CME: ESK)
-
- Futures.Currencies.GBP
-
- : British Pound Futures (CME: 6B)
-
- Futures.Currencies.JapaneseYenEmini
-
-
- Futures.Currencies.JAPANESE_YEN_EMINI
-
- : E-mini Japanese Yen Futures (CME: J7)
-
- Futures.Currencies.JPY
-
- : Japanese Yen Futures (CME: 6J)
-
- Futures.Currencies.MicroAUD
-
-
- Futures.Currencies.MICRO_AUD
-
- : Micro AUD/USD Futures (CME: M6A)
-
- Futures.Currencies.MicroBTC
-
-
- Futures.Currencies.MICRO_BTC
-
- : Micro Bitcoin Futures (CME: MBT)
-
- Futures.Currencies.MicroCAD
-
-
- Futures.Currencies.MICRO_CAD
-
- : Micro USD/CAD Futures (CME: M6C)
-
- Futures.Currencies.MicroCADUSD
-
-
- Futures.Currencies.MICRO_CADUSD
-
- : Micro CAD/USD Futures (CME: MCD)
-
- Futures.Currencies.MicroCHF
-
-
- Futures.Currencies.MICRO_CHF
-
- : Micro CHF/USD Futures (CME: MSF)
-
- Futures.Currencies.MicroEther
-
-
- Futures.Currencies.MICRO_ETHER
-
- : Micro Ether Futures (CME: MET)
-
- Futures.Currencies.MicroEUR
-
-
- Futures.Currencies.MICRO_EUR
-
- : Micro EUR/USD Futures (CME: M6E)
-
- Futures.Currencies.MicroGBP
-
-
- Futures.Currencies.MICRO_GBP
-
- : Micro GBP/USD Futures (CME: M6B)
-
- Futures.Currencies.MicroINRUSD
-
-
- Futures.Currencies.MICRO_INRUSD
-
- : Micro INR/USD Futures (CME: MIR)
-
- Futures.Currencies.MicroJPY
-
-
- Futures.Currencies.MICRO_JPY
-
- : Micro JPY/USD Futures (CME: MJY)
-
- Futures.Currencies.MicroUSDCHF
-
-
- Futures.Currencies.MICRO_USDCHF
-
- : Micro USD/CHF Futures (CME: M6S)
-
- Futures.Currencies.MicroUSDCNH
-
-
- Futures.Currencies.MICRO_USDCNH
-
- : Micro USD/CNH Futures (CME: MNH)
-
- Futures.Currencies.MicroUSDJPY
-
-
- Futures.Currencies.MICRO_USDJPY
-
- : Micro USD/JPY Futures (CME: M6J)
-
- Futures.Currencies.MXN
-
- : Mexican Peso Futures (CME: 6M)
-
- Futures.Currencies.NZD
-
- : New Zealand Dollar Futures (CME: 6N)
-
- Futures.Currencies.RUB
-
- : Russian Ruble Futures (CME: 6R)
-
- Futures.Currencies.StandardSizeUSDOffshoreRMBCNH
-
-
- Futures.Currencies.STANDARD_SIZE_USD_OFFSHORE_RMBCNH
-
- : Standard-Size USD/Offshore RMB (CNH) Futures (CME: CNH)
-
- Futures.Currencies.ZAR
-
- : South African Rand Futures (CME: 6Z)
-
- Futures.Energy.ArgusLLSvsWTIArgusTradeMonth
-
-
- Futures.Energy.ARGUS_LL_SVS_WTI_ARGUS_TRADE_MONTH
-
- : Argus LLS vs. WTI (Argus) Trade Month Futures (NYMEX: AE5)
-
- Futures.Energy.ArgusPropaneFarEastIndex
-
-
- Futures.Energy.ARGUS_PROPANE_FAR_EAST_INDEX
-
- : Argus Propane Far East Index Futures (NYMEX: A7E)
-
- Futures.Energy.ArgusPropaneSaudiAramco
-
-
- Futures.Energy.ARGUS_PROPANE_SAUDI_ARAMCO
-
- : Argus Propane (Saudi Aramco) Futures (NYMEX: A9N)
-
- Futures.Energy.BrentCrudeOilVsDubaiCrudeOilPlatts
-
-
- Futures.Energy.BRENT_CRUDE_OIL_VS_DUBAI_CRUDE_OIL_PLATTS
-
- : Brent Crude Oil vs. Dubai Crude Oil (Platts) Futures (NYMEX: ADB)
-
- Futures.Energy.BrentLastDayFinancial
-
-
- Futures.Energy.BRENT_LAST_DAY_FINANCIAL
-
- : Brent Last Day Financial Futures (NYMEX: BZ)
-
- Futures.Energy.ChicagoEthanolPlatts
-
-
- Futures.Energy.CHICAGO_ETHANOL_PLATTS
-
- : Chicago Ethaanol (Platts) Futures (NYMEX: CU)
-
- Futures.Energy.ConwayPropaneOPIS
-
-
- Futures.Energy.CONWAY_PROPANE_OPIS
-
- : Conway Propane (OPIS) Futures (NYMEX: A8K)
-
- Futures.Energy.CrudeOilWTI
-
-
- Futures.Energy.CRUDE_OIL_WTI
-
- : Crude Oil WTI Futures (NYMEX: CL)
-
- Futures.Energy.DubaiCrudeOilPlattsFinancial
-
-
- Futures.Energy.DUBAI_CRUDE_OIL_PLATTS_FINANCIAL
-
- : Dubai Crude Oil (Platts) Financial Futures (NYMEX: DCB)
-
- Futures.Energy.EastWestGasolineSpreadPlattsArgus
-
-
- Futures.Energy.EAST_WEST_GASOLINE_SPREAD_PLATTS_ARGUS
-
- : East-West Gasoline Spread (Platts-Argus) Futures (NYMEX: EWG)
-
- Futures.Energy.EastWestNaphthaJapanCFvsCargoesCIFNWESpreadPlatts
-
-
- Futures.Energy.EAST_WEST_NAPHTHA_JAPAN_C_FVS_CARGOES_CIFNWE_SPREAD_PLATTS
-
- : East-West Naphtha: Japan C&F vs. Cargoes CIF NWE Spread (Platts) Futures (NYMEX: EWN)
-
- Futures.Energy.Ethanol
-
-
- Futures.Energy.ETHANOL
-
- : Ethanol Futures (CBOT: EH)
-
- Futures.Energy.EthanolT2FOBRdamIncludingDutyPlatts
-
-
- Futures.Energy.ETHANOL_T_2_FOB_RDAM_INCLUDING_DUTY_PLATTS
-
- : Ethanol T2 FOB Rdam Including Duty (Platts) Futures (NYMEX: AZ1)
-
- Futures.Energy.EuropeanNaphthaPlattsCrackSpread
-
-
- Futures.Energy.EUROPEAN_NAPHTHA_PLATTS_CRACK_SPREAD
-
- : European Naphtha (Platts) Crack Spread Futures (NYMEX: EN)
-
- Futures.Energy.EuropeanPropaneCIFARAArgus
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS
-
- : European Propane CIF ARA (Argus) Futures (NYMEX: APS)
-
- Futures.Energy.EuropeanPropaneCIFARAArgusVsNaphthaCargoesCIFNWEPlatts
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS_VS_NAPHTHA_CARGOES_CIFNWE_PLATTS
-
- : European Propane CIF ARA (Argus) vs. Naphtha Cargoes CIF NWE (Platts) Futures (NYMEX: EPN)
-
- Futures.Energy.FreightRouteTC14Baltic
-
-
- Futures.Energy.FREIGHT_ROUTE_TC_14_BALTIC
-
- : Freight Route TC14 (Baltic) Futures (NYMEX: FRC)
-
- Futures.Energy.Gasoline
-
-
- Futures.Energy.GASOLINE
-
- : Gasoline RBOB Futures (NYMEX: RB)
-
- Futures.Energy.GasolineEurobobOxyNWEBargesArgus
-
-
- Futures.Energy.GASOLINE_EUROBOB_OXY_NWE_BARGES_ARGUS
-
- : Gasoline Euro-bob Oxy NWE Barges (Argus) Futures (NYMEX: B7H)
-
- Futures.Energy.GroupThreeSuboctaneGasolinePlattsVsRBOB
-
-
- Futures.Energy.GROUP_THREE_SUBOCTANE_GASOLINE_PLATTS_VS_RBOB
-
- : Group Three Sub-octane Gasoliine (Platts) vs. RBOB Futures (NYMEX: AA8)
-
- Futures.Energy.GroupThreeULSDPlattsVsNYHarborULSD
-
-
- Futures.Energy.GROUP_THREE_ULSD_PLATTS_VS_NY_HARBOR_ULSD
-
- : Group Three ULSD (Platts) vs. NY Harbor ULSD Futures (NYMEX: AA6)
-
- Futures.Energy.GulfCoastCBOBGasolineA2PlattsVsRBOBGasoline
-
-
- Futures.Energy.GULF_COAST_CBOB_GASOLINE_A_2_PLATTS_VS_RBOB_GASOLINE
-
- : Gulf Coast CBOB Gasoline A2 (Platts) vs. RBOB Gasoline Futures (NYMEX: CRB)
-
- Futures.Energy.GulfCoastHSFOPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.GULF_COAST_HSFO_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Gulf Coast HSFO (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: GCU)
-
- Futures.Energy.HeatingOil
-
-
- Futures.Energy.HEATING_OIL
-
- : Heating Oil Futures (NYMEX: HO)
-
- Futures.Energy.LosAngelesCARBOBGasolineOPISvsRBOBGasoline
-
-
- Futures.Energy.LOS_ANGELES_CARBOB_GASOLINE_OPI_SVS_RBOB_GASOLINE
-
- : Los Angeles CARBOB Gasoline (OPIS) vs. RBOB Gasoline Futures (NYMEX: AJL)
-
- Futures.Energy.LosAngelesCARBDieselOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_CARB_DIESEL_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles CARB Diesel (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AKL)
-
- Futures.Energy.LosAngelesJetOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_JET_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles Jet (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AJS)
-
- Futures.Energy.MarsArgusVsWTIFinancial
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_FINANCIAL
-
- : Mars (Argus) vs. WTI Financial Futures (NYMEX: AYX)
-
- Futures.Energy.MarsArgusVsWTITradeMonth
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_TRADE_MONTH
-
- : Mars (Argus) vs. WTI Trade Month Futures (NYMEX: AYV)
-
- Futures.Energy.MicroCrudeOilWTI
-
-
- Futures.Energy.MICRO_CRUDE_OIL_WTI
-
- : Micro WTI Crude Oil Futures (NYMEX: MCL)
-
- Futures.Energy.MicroEuropeanFOBRdamMarineFuelZeroPointFivePercentBargesPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_FOB_RDAM_MARINE_FUEL_ZERO_POINT_FIVE_PERCENT_BARGES_PLATTS
-
- : Micro European FOB Rdam Marine Fuel 0.5% Barges (Platts) Futures (NYMEX: R5O)
-
- Futures.Energy.MicroEuropeanThreePointFivePercentOilBargesFOBRdamPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_THREE_POINT_FIVE_PERCENT_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Micro European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: MEF)
-
- Futures.Energy.MicroGasoilZeroPointOnePercentBargesFOBARAPlatts
-
-
- Futures.Energy.MICRO_GASOIL_ZERO_POINT_ONE_PERCENT_BARGES_FOBARA_PLATTS
-
- : Micro Gasoil 0.1% Barges FOB ARA (Platts) Futures (NYMEX: M1B)
-
- Futures.Energy.MicroSingaporeFOBMarineFuelZeroPointFivePercetPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FOB_MARINE_FUEL_ZERO_POINT_FIVE_PERCET_PLATTS
-
- : Micro Singapore FOB Marine Fuel 0.5% (Platts) Futures (NYMEX: S5O)
-
- Futures.Energy.MicroSingaporeFuelOil380CSTPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FUEL_OIL_380_CST_PLATTS
-
- : Micro Singapore Fuel Oil 380CST (Platts) Futures (NYMEX: MAF)
-
- Futures.Energy.MiniEuropeanThreePointPercentFiveFuelOilBargesPlatts
-
-
- Futures.Energy.MINI_EUROPEAN_THREE_POINT_PERCENT_FIVE_FUEL_OIL_BARGES_PLATTS
-
- : Mini European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: A0D)
-
- Futures.Energy.MiniSingaporeFuelOil180CstPlatts
-
-
- Futures.Energy.MINI_SINGAPORE_FUEL_OIL_180_CST_PLATTS
-
- : Mini Singapore Fuel Oil 180 cst (Platts) Futures (NYMEX: A0F)
-
- Futures.Energy.MontBelvieuEthaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_ETHANE_OPIS
-
- : Mont Belvieu Ethane (OPIS) Futures (NYMEX: AC0)
-
- Futures.Energy.MontBelvieuLDHPropaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_LDH_PROPANE_OPIS
-
- : Mont Belvieu LDH Propane (OPIS) Futures (NYMEX: B0)
-
- Futures.Energy.MontBelvieuNaturalGasolineOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NATURAL_GASOLINE_OPIS
-
- : Mont Belvieu Natural Gasoline (OPIS) Futures (NYMEX: A7Q)
-
- Futures.Energy.MontBelvieuNormalButaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NORMAL_BUTANE_OPIS
-
- : Mont Belvieu Normal Butane (OPIS) Futures (NYMEX: AD0)
-
- Futures.Energy.NaturalGas
-
-
- Futures.Energy.NATURAL_GAS
-
- : Natural Gas Futures (NYMEX: NG)
-
- Futures.Energy.NaturalGasHenryHubLastDayFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_LAST_DAY_FINANCIAL
-
- : Natural Gas (Henry Hub) Last-day Financial Futures (NYMEX: HH)
-
- Futures.Energy.NaturalGasHenryHubPenultimateFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_PENULTIMATE_FINANCIAL
-
- : Natural Gas (Henry Hub) Penultimate Financial Futures (NYMEX: HP)
-
- Futures.Energy.OnePercentFuelOilCargoesFOBNWEPlattsVsThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.ONE_PERCENT_FUEL_OIL_CARGOES_FOBNWE_PLATTS_VS_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : 1% Fuel Oil Cargoes FOB NWE (Platts) vs. 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: FSS)
-
- Futures.Energy.PremiumUnleadedGasoline10ppmFOBMEDPlatts
-
-
- Futures.Energy.PREMIUM_UNLEADED_GASOLINE_10_PPM_FOBMED_PLATTS
-
- : Premium Unleaded Gasoline 10 ppm FOB MED (Platts) Futures (NYMEX: A3G)
-
- Futures.Energy.PropaneNonLDHMontBelvieuOPIS
-
-
- Futures.Energy.PROPANE_NON_LDH_MONT_BELVIEU_OPIS
-
- : Propane Non-LDH Mont Belvieu (OPIS) Futures (NYMEX: A1R)
-
- Futures.Energy.RBOBGasolineCrackSpread
-
-
- Futures.Energy.RBOB_GASOLINE_CRACK_SPREAD
-
- : RBOB Gasoline Crack Spread Futures (NYMEX: ARE)
-
- Futures.Energy.RBOBGasolineVsEurobobOxyNWEBargesArgusThreeHundredFiftyThousandGallons
-
-
- Futures.Energy.RBOB_GASOLINE_VS_EUROBOB_OXY_NWE_BARGES_ARGUS_THREE_HUNDRED_FIFTY_THOUSAND_GALLONS
-
- : RBOB Gasoline vs. Euro-bob Oxy NWE Barges (Argus) (350,000 gallons) Futures (NYMEX: EXR)
-
- Futures.Energy.SingaporeFuelOil380cstPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.SINGAPORE_FUEL_OIL_380_CST_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Singapore Fuel Oil 380 cst (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: EVC)
-
- Futures.Energy.SingaporeGasoilPlattsVsLowSulphurGasoilFutures
-
-
- Futures.Energy.SINGAPORE_GASOIL_PLATTS_VS_LOW_SULPHUR_GASOIL_FUTURES
-
- : Singapore Gasoil (Platts) vs. Low Sulphur Gasoil Futures (NYMEX: AGA)
-
- Futures.Energy.SingaporeMogas92UnleadedPlattsBrentCrackSpread
-
-
- Futures.Energy.SINGAPORE_MOGAS_92_UNLEADED_PLATTS_BRENT_CRACK_SPREAD
-
- : Singapore Mogas 92 Unleaded (Platts) Brent Crack Spread Futures (NYMEX: D1N)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread Futures (NYMEX: FO)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread1000mt
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD_1000_MT
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread (1000mt) Futures (NYMEX: BOO)
-
- Futures.Energy.WTIBrentFinancial
-
-
- Futures.Energy.WTI_BRENT_FINANCIAL
-
- : WTI-Brent Financial Futures (NYMEX: BK)
-
- Futures.Energy.WTIFinancial
-
-
- Futures.Energy.WTI_FINANCIAL
-
- : WTI Financial Futures (NYMEX: CSX)
-
- Futures.Energy.WTIHoustonArgusVsWTITradeMonth
-
-
- Futures.Energy.WTI_HOUSTON_ARGUS_VS_WTI_TRADE_MONTH
-
- : WTI Houston (Argus) vs. WTI Trade Month Futures (NYMEX: HTT)
-
- Futures.Energy.WTIHoustonCrudeOil
-
-
- Futures.Energy.WTI_HOUSTON_CRUDE_OIL
-
- : WTI Houston Crude Oil Futures (NYMEX: HCL)
-
- Futures.Financials.EuroDollar
-
-
- Futures.Financials.EURO_DOLLAR
-
- : EuroDollar Futures (CME: GE)
-
- Futures.Financials.FiveYearUSDMACSwap
-
-
- Futures.Financials.FIVE_YEAR_USDMAC_SWAP
-
- : 5-Year USD MAC Swap Futures (CBOT: F1U)
-
- Futures.Financials.MicroY10TreasuryNote
-
-
- Futures.Financials.MICRO_Y_10_TREASURY_NOTE
-
- : Micro 10-Year Yield Futures (CBOT: 10Y)
-
- Futures.Financials.MicroY2TreasuryBond
-
-
- Futures.Financials.MICRO_Y_2_TREASURY_BOND
-
- : Micro 2-Year Yield Futures (CBOT: 2YY)
-
- Futures.Financials.MicroY30TreasuryBond
-
-
- Futures.Financials.MICRO_Y_30_TREASURY_BOND
-
- : Micro 30-Year Yield Futures (CBOT: 30Y)
-
- Futures.Financials.MicroY5TreasuryBond
-
-
- Futures.Financials.MICRO_Y_5_TREASURY_BOND
-
- : Micro 5-Year Yield Futures (CBOT: 5YY)
-
- Futures.Financials.UltraTenYearUSTreasuryNote
-
-
- Futures.Financials.ULTRA_TEN_YEAR_US_TREASURY_NOTE
-
- : Ultra 10-Year U.S. Treasury Note Futures (CBOT: TN)
-
- Futures.Financials.UltraUSTreasuryBond
-
-
- Futures.Financials.ULTRA_US_TREASURY_BOND
-
- : Ultra U.S. Treasury Bond Futures (CBOT: UB)
-
- Futures.Financials.Y10TreasuryNote
-
-
- Futures.Financials.Y_10_TREASURY_NOTE
-
- : 10Y U.S. Treasury Note Futures (CBOT: ZN)
-
- Futures.Financials.Y2TreasuryNote
-
-
- Futures.Financials.Y_2_TREASURY_NOTE
-
- : 2Y U.S. Treasury Note Futures (CBOT: ZT)
-
- Futures.Financials.Y30TreasuryBond
-
-
- Futures.Financials.Y_30_TREASURY_BOND
-
- : 30Y U.S. Treasury Bond Futures (CBOT: ZB)
-
- Futures.Financials.Y5TreasuryNote
-
-
- Futures.Financials.Y_5_TREASURY_NOTE
-
- : 5Y U.S. Treasury Note Futures (CBOT: ZF)
-
- Futures.Forestry.Lumber
-
-
- Futures.Forestry.LUMBER
-
- : Lumber Futures (CME: LBR)
-
- Futures.Forestry.RandomLengthLumber
-
-
- Futures.Forestry.RANDOM_LENGTH_LUMBER
-
- : Random Length Lumber Futures (CME: LBS)
-
- Futures.Grains.BlackSeaCornFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_CORN_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Corn Financially Settled (Platts) Futures (CBOT: BCF)
-
- Futures.Grains.BlackSeaWheatFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_WHEAT_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Wheat Financially Settled (Platts) Futures (CBOT: BWF)
-
- Futures.Grains.Corn
-
-
- Futures.Grains.CORN
-
- : Corn Futures (CBOT: ZC)
-
- Futures.Grains.HRWWheat
-
-
- Futures.Grains.HRW_WHEAT
-
- : KC HRW Wheat Futures (CBOT: KE)
-
- Futures.Grains.Oats
-
-
- Futures.Grains.OATS
-
- : Oats Futures (CBOT: ZO)
-
- Futures.Grains.Soybeans
-
-
- Futures.Grains.SOYBEANS
-
- : Soybeans Futures (CBOT: ZS)
-
- Futures.Grains.SoybeanMeal
-
-
- Futures.Grains.SOYBEAN_MEAL
-
- : Soybean Meal Futures (CBOT: ZM)
-
- Futures.Grains.SoybeanOil
-
-
- Futures.Grains.SOYBEAN_OIL
-
- : Soybean Oil Futures (CBOT: ZL)
-
- Futures.Grains.Wheat
-
-
- Futures.Grains.WHEAT
-
- : Default wheat contract is SRWWheat (CBOT: ZW)
-
- Futures.Indices.BloombergCommodityIndex
-
-
- Futures.Indices.BLOOMBERG_COMMODITY_INDEX
-
- : Bloomberg Commodity Index Futures (CBOT: AW)
-
- Futures.Indices.Dow30EMini
-
-
- Futures.Indices.DOW_30_E_MINI
-
- : E-mini Dow Indu 30 Futures (CBOT: YM)
-
- Futures.Indices.DowJonesRealEstate
-
-
- Futures.Indices.DOW_JONES_REAL_ESTATE
-
- : Dow Jones Real Estate futures on CME (CME: RX)
-
- Futures.Indices.FTSEEmergingEmini
-
-
- Futures.Indices.FTSE_EMERGING_EMINI
-
- : E-mini FTSE Emerging Index Futures (CME: EI)
-
- Futures.Indices.MicroDow30EMini
-
-
- Futures.Indices.MICRO_DOW_30_E_MINI
-
- : Micro E-mini Dow Jones Industrial Average Index Futures (CBOT: MYM)
-
- Futures.Indices.MicroNASDAQ100EMini
-
-
- Futures.Indices.MICRO_NASDAQ_100_E_MINI
-
- : Micro E-mini Nasdaq-100 Index Futures (CME: MNQ)
-
- Futures.Indices.MicroRussell2000EMini
-
-
- Futures.Indices.MICRO_RUSSELL_2000_E_MINI
-
- : Micro E-mini Russell 2000 Index Futures (CME: M2K)
-
- Futures.Indices.MicroSP500EMini
-
-
- Futures.Indices.MICRO_SP_500_E_MINI
-
- : Micro E-mini S&P 500 Index Futures (CME: MES)
-
- Futures.Indices.NASDAQ100BiotechnologyEMini
-
-
- Futures.Indices.NASDAQ_100_BIOTECHNOLOGY_E_MINI
-
- : E-mini Nasdaq-100 Biotechnology Index Futures (CME: BIO)
-
- Futures.Indices.NASDAQ100EMini
-
-
- Futures.Indices.NASDAQ_100_E_MINI
-
- : E-mini NASDAQ 100 Futures (CME: NQ)
-
- Futures.Indices.Nikkei225Dollar
-
-
- Futures.Indices.NIKKEI_225_DOLLAR
-
- : Nikkei-225 Dollar Futures (CME: NKD)
-
- Futures.Indices.Nikkei225YenCME
-
-
- Futures.Indices.NIKKEI_225_YEN_CME
-
- : Nikkei-225 Yen denominated Futures on CME (CME: NIY)
-
- Futures.Indices.Russell1000EMini
-
-
- Futures.Indices.RUSSELL_1000_E_MINI
-
- : E-mini Russell 1000 futures on CME (CME: RS1)
-
- Futures.Indices.Russell2000EMini
-
-
- Futures.Indices.RUSSELL_2000_E_MINI
-
- : E-mini Russell 2000 Futures (CME: RTY)
-
- Futures.Indices.SPGSCICommodity
-
-
- Futures.Indices.SPGSCI_COMMODITY
-
- : S&P-GSCI Commodity Index Futures (CME: GD)
-
- Futures.Indices.SP400MidCapEmini
-
-
- Futures.Indices.SP_400_MID_CAP_EMINI
-
- : E-mini S&P MidCap 400 Futures (CME: EMD)
-
- Futures.Indices.SP500AnnualDividendIndex
-
-
- Futures.Indices.SP_500_ANNUAL_DIVIDEND_INDEX
-
- : (CME: SDA)
-
- Futures.Indices.SP500EMini
-
-
- Futures.Indices.SP_500_E_MINI
-
- : E-mini S&P 500 Futures (CME: ES)
-
- Futures.Indices.TOPIXYEN
-
- : YEN Denominated Topix Index Futures on CME (CME: TPY)
-
- Futures.Indices.USDDenominatedIbovespa
-
-
- Futures.Indices.USD_DENOMINATED_IBOVESPA
-
- : USD-Denominated Ibovespa Index Futures (CME: IBV)
-
- Futures.Indices.VIX
-
- : CBOE Volatility Index Futures (CFE: VX)
-
- Futures.Meats.FeederCattle
-
-
- Futures.Meats.FEEDER_CATTLE
-
- : Feeder Cattle Futures (CME: GF)
-
- Futures.Meats.LeanHogs
-
-
- Futures.Meats.LEAN_HOGS
-
- : Lean Hogs Futures (CME: HE)
-
- Futures.Meats.LiveCattle
-
-
- Futures.Meats.LIVE_CATTLE
-
- : Live Cattle Futures (CME: LE)
-
- Futures.Metals.AluminiumEuropeanPremiumDutyPaidMetalBulletin
-
-
- Futures.Metals.ALUMINIUM_EUROPEAN_PREMIUM_DUTY_PAID_METAL_BULLETIN
-
- : Aluminium European Premium Duty-Paid (Metal Bulletin) Futures (COMEX: EDP)
-
- Futures.Metals.AluminumMWUSTransactionPremiumPlatts25MT
-
-
- Futures.Metals.ALUMINUM_MWUS_TRANSACTION_PREMIUM_PLATTS_25_MT
-
- : Aluminum MW U.S. Transaction Premium Platts (25MT) Futures (COMEX: AUP)
-
- Futures.Metals.Copper
-
-
- Futures.Metals.COPPER
-
- : Copper Futures (COMEX: HG)
-
- Futures.Metals.Gold
-
-
- Futures.Metals.GOLD
-
- : Gold Futures (COMEX: GC)
-
- Futures.Metals.MicroGold
-
-
- Futures.Metals.MICRO_GOLD
-
- : Micro Gold Futures (COMEX: MGC)
-
- Futures.Metals.MicroGoldTAS
-
-
- Futures.Metals.MICRO_GOLD_TAS
-
- : Micro Gold TAS Futures (COMEX: MGT)
-
- Futures.Metals.MicroPalladium
-
-
- Futures.Metals.MICRO_PALLADIUM
-
- : Micro Palladium Futures (NYMEX: PAM)
-
- Futures.Metals.MicroSilver
-
-
- Futures.Metals.MICRO_SILVER
-
- : Micro Silver Futures (COMEX: SIL)
-
- Futures.Metals.Palladium
-
-
- Futures.Metals.PALLADIUM
-
- : Palladium Futures (NYMEX: PA)
-
- Futures.Metals.Platinum
-
-
- Futures.Metals.PLATINUM
-
- : Platinum Futures (NYMEX: PL)
-
- Futures.Metals.Silver
-
-
- Futures.Metals.SILVER
-
- : Silver Futures (COMEX: SI)
-
- Futures.Metals.USMidwestDomesticHotRolledCoilSteelCRUIndex
-
-
- Futures.Metals.US_MIDWEST_DOMESTIC_HOT_ROLLED_COIL_STEEL_CRU_INDEX
-
- : U.S. Midwest Domestic Hot-Rolled Coil Steel (CRU) Index Futures (NYMEX: HRC)
-
- Futures.Softs.Sugar11
-
-
- Futures.Softs.SUGAR_11
-
- : Sugar #11 Futures ICE (ICE: SB)
-
- Futures.Softs.Sugar11CME
-
-
- Futures.Softs.SUGAR_11_CME
-
- : Sugar #11 Futures CME (NYMEX: YO)
- - The US Future Universe dataset enables you to accurately design Futures strategies. Examples include the following strategies: -
-- The following example algorithm selects and buys the front-month Mini Gold Futures contract and sells the front-month Micro Gold Futures contract. When the front-month contract changes, the algorithm rebalances the portfolio. -
-from AlgorithmImports import *
-
-class USFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000000)
- self.universe_settings.asynchronous = True
- # Requesting data on gold and micro-gold contracts.
- # Filter the universe to trade only the contracts expiring within 90 days to ensure liquidity.
- self.mini_gold = self.add_future(Futures.Metals.GOLD)
- self.mini_gold.set_filter(0, 90)
-
- self.micro_gold = self.add_future(Futures.Metals.MICRO_GOLD)
- self.micro_gold.set_filter(0, 90)
-
- # Save a cache of the mapped symbol to trade.
- self.contract = {self.mini_gold.symbol: None, self.micro_gold.symbol: None}
-
- def on_data(self, slice: Slice) -> None:
- for symbol, chain in slice.future_chains.items():
- if symbol in self.contract:
- # Select the contract with the greatest open interest to trade with the most efficiency.
- most_liquid_contract = sorted(chain, key=lambda contract: contract.open_interest, reverse=True)[0]
-
- if self.contract[symbol] is None or most_liquid_contract.symbol != self.contract[symbol].symbol:
- # Liquidate any unmapped contracts.
- if self.contract[symbol] is not None:
- self.liquidate(self.contract[symbol].symbol)
- self.contract[symbol] = most_liquid_contract
-
- # Buy mini-gold and short micro-gold contracts as planned.
- if symbol == self.mini_gold.symbol:
- self.market_order(self.contract[symbol].symbol, 1)
- elif symbol == self.micro_gold.symbol:
- self.market_order(self.contract[symbol].symbol, -1)
- public class USFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _miniGold;
- private Future _microGold;
- // Save a cache of the mapped symbol to trade.
- private Dictionary<Symbol, FuturesContract?> _contract = new ();
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
-
- // Requesting data on gold and micro-gold contracts.
- // Filter the universe to trade only the contracts expiring within 90 days to ensure liquidity.
- _miniGold = AddFuture(Futures.Metals.Gold);
- _miniGold.SetFilter(0, 90);
- _contract.Add(_miniGold.Symbol, null);
-
- _microGold = AddFuture(Futures.Metals.MicroGold);
- _microGold.SetFilter(0, 90);
- _contract.Add(_microGold.Symbol, null);
- }
-
- public override void OnData(Slice slice)
- {
- foreach (var (symbol, chain) in slice.FutureChains)
- {
- if (_contract.ContainsKey(symbol))
- {
- // Select the contract with the greatest open interest to trade with the most efficiency.
- var mostLiquidContract = chain.OrderBy(x => x.OpenInterest).Last();
-
- if (_contract[symbol] == null || mostLiquidContract.Symbol != _contract[symbol].Symbol)
- {
- // Liquidate any unmapped contracts.
- if (_contract[symbol] != null)
- {
- Liquidate(_contract[symbol].Symbol);
- }
- _contract[symbol] = mostLiquidContract;
-
- // Buy mini-gold and short micro-gold contracts as planned.
- if (symbol == _miniGold.Symbol)
- {
- MarketOrder(_contract[symbol].Symbol, 1);
- }
- else if (symbol == _microGold.Symbol)
- {
- MarketOrder(_contract[symbol].Symbol, -1);
- }
- }
- }
- }
- }
-}
- - The following example algorithm selects and buys the front-month Mini Gold Futures contract and sells the front-month Micro Gold Futures contract. When the front-month contract changes, the algorithm rebalances the portfolio. -
-from AlgorithmImports import *
-
-class USFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- # Set up an universe selection model that selects the front month contract
- self.set_universe_selection(FrontMonthFutureUniverseSelectionModel())
- self.add_alpha(ConstantFuturesAlphaModel())
- # A portfolio construction model that only order a single share per insight signal
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
- def __init__(self,) -> None:
- # Daily updating with select_future_chain_symbols function
- super().__init__(timedelta(1), self.select_future_chain_symbols)
-
- def select_future_chain_symbols(self, utcTime: datetime) -> List[Symbol]:
- # Select gold and micro gold contracts for the strategy need
- future_pairs = [
- (Futures.Metals.GOLD, Market.COMEX),
- (Futures.Metals.MICRO_GOLD, Market.COMEX)
- ]
- return [Symbol.create(pair[0], SecurityType.FUTURE, pair[1]) for pair in future_pairs]
-
- def filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
- # Filter only front month contract for liquidity and most informed information
- return filter.front_month().only_apply_filter_at_market_open()
-
-class ConstantFuturesAlphaModel(AlphaModel):
- # Long gold and short micro gold in this strategy
- long_symbol = Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
- short_symbol = Symbol.create(Futures.Metals.MICRO_GOLD, SecurityType.FUTURE, Market.COMEX)
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- if algorithm.portfolio.invested:
- return []
-
- insights = []
- # For both gold and micro gold, select the front month contract (only contract) in the chain
- for kvp in slice.future_chains:
- chain = [contract for contract in kvp.Value]
- contract = chain[0]
-
- # Long gold and short micro gold as planned
- if kvp.Key == self.long_symbol:
- insights.append(Insight.price(contract.symbol, contract.expiry + timedelta(days=1), InsightDirection.UP))
- elif kvp.Key == self.short_symbol:
- insights.append(Insight.price(contract.symbol, contract.expiry + timedelta(days=1), InsightDirection.DOWN))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- # Historical data
- history = algorithm.history(security.symbol, 10, Resolution.MINUTE)
- algorithm.debug(f"We got {len(history)} from our history request for {security.symbol}")
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- # Single share only using integer portfolio target
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class USFuturesDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
- // Set up an universe selection model that selects the front month contract
- SetUniverseSelection(new FrontMonthFutureUniverseSelectionModel());
- SetAlpha(new ConstantFuturesAlphaModel());
- // A portfolio construction model that only order a single share per insight signal
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-class FrontMonthFutureUniverseSelectionModel : FutureUniverseSelectionModel
-{
- // Daily updating with select_future_chain_symbols function
- public FrontMonthFutureUniverseSelectionModel()
- : base(TimeSpan.FromDays(1), SelectFutureChainSymbols) {}
-
- private static IEnumerable<Symbol> SelectFutureChainSymbols(DateTime utcTime)
- {
- //Select gold and micro gold contracts for the strategy need
- return new List<Symbol> {
- QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX),
- QuantConnect.Symbol.Create(Futures.Metals.MicroGold, SecurityType.Future, Market.COMEX)
- };
- }
-
- protected override FutureFilterUniverse Filter(FutureFilterUniverse filter)
- {
- // Filter only front month contract for liquidity and most informed information
- return filter.FrontMonth().OnlyApplyFilterAtMarketOpen();
- }
-}
-
-
-class ConstantFuturesAlphaModel : AlphaModel
-{
- // Long gold and short micro gold in this strategy
- private Symbol
- _longSymbol = QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX),
- _shortSymbol = QuantConnect.Symbol.Create(Futures.Metals.MicroGold, SecurityType.Future, Market.COMEX);
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- if (algorithm.Portfolio.Invested)
- {
- return insights;
- }
-
- // For both gold and micro gold, select the front month contract (only contract) in the chain
- foreach (var kvp in slice.FutureChains)
- {
- var symbol = kvp.Key;
- var chain = kvp.Value;
- var contract = chain.First();
-
- // Long gold and short micro gold as planned
- if (symbol == _longSymbol)
- {
- insights.Add(Insight.Price(contract.Symbol, contract.Expiry + TimeSpan.FromDays(1), InsightDirection.Up));
- }
- else if (symbol == _shortSymbol)
- {
- insights.Add(Insight.Price(contract.Symbol, contract.Expiry + TimeSpan.FromDays(1), InsightDirection.Down));
- }
- }
-
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- // Historical data
- var history = algorithm.History(security.Symbol, 100, Resolution.Minute);
- algorithm.Debug($"We got {history.Count()} from our history request for {security.Symbol}");
- }
- }
-}
-
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- // Single share only using integer portfolio target
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Future Universe dataset provides
-
- FutureFilterUniverse
-
- and
-
- FutureUniverse
-
- objects.
-
-
- FutureFilterUniverse
-
- objects have the following attributes:
-
-
- FutureUniverse
-
- objects have the following attributes:
-
- -
- The US Futures Security Master dataset by QuantConnect provides mapping reference data for the most liquid contracts of the CME Group exchanges, calculated with popular rolling techniques. The data covers 157 root Future contracts, starts in May 2009, and is delivered on a daily frequency with a zip file with all the contract mappings. This dataset is created by daily processing of the US historical Future chains. -
-- This dataset, paired with the US Futures dataset, supports the following rolling techniques: forward panama canal, backwards panama canal, and backwards ratio. You can set the specific rolling date to occur on the last trading day, first day month, or the day when the contract with the greatest open interest changes. -
-- VIX Futures don't support continous contract rolling with open interest. -
-
- This is
-
- NOT
-
- the underlying Futures data (
-
- US Futures
-
- dataset), which you need to purchase separately with a license from AlgoSeek. This security master dataset is required to purchase the US Futures or US Future Options datasets.
-
- For more information about the US Futures Security Master dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- You don't need any special code to utilize the US Futures Security Master. It automatically loads when you - - request US Futures data - - . -
- - - -- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- May 2009 - | -
| - Asset Coverage - | -- 157 Liquid Futures - | -
| - Data Density - | -- Regular - | -
| - Resolution - | -- Daily - | -
- VIX Futures don't support continous contract rolling with open interest. -
- - - -- The US Futures Security Master lets you to construct continuous Futures, allowing the access of normalized historical data of the underlying assets, as well as trading the “lead” Future contracts for those assets. -
-- Continuous Futures refer to sets of rolling lead Future contracts during their actively trading periods. Since Future contracts expire at their maturities, to analyze the historical price of a Future and to apply technical indicators, you need the continuous Future price series. -
-
- To access the continuous Future, use the Future's
-
- Symbol
-
-
- symbol
-
- property.
-
# Set the data normalization mode and data mapping mode to select the contract as the continuous contract with price adjustment for smooth price series -future = self.add_future(Futures.Energy.CRUDE_OIL_WTI, - data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - contract_depth_offset=0) -self.continuous_contract_symbol = future.symbol-
// Set the data normalization mode and data mapping mode to select the contract as the continuous contract with price adjustment for smooth price series -var future = AddFuture(Futures.Energy.CrudeOilWTI, - dataNormalizationMode: DataNormalizationMode.BackwardsRatio, - dataMappingMode: DataMappingMode.OpenInterest, - contractDepthOffset: 0 -); -_continuousFutureSymbol = future.Symbol;-
- The
-
- dataNormalizationMode
-
- and
-
- dataMappingMode
-
- arguments makes the transition of the underlying contracts seemless. However, the Future
-
- Symbol
-
- doesn't map to an underlying Future contract. It works fine to trade within backtests, but could be subjected to friction costs during live trading since the order price could be a normalized price. For more information about this topic, see the
-
- Live Trading Considerations
-
- section.
-
- The data normalization mode defines how the price series of two contracts are stitched together when the contract rollovers occur. The
-
- DataNormalizatoinMode
-
- enumeration has the following members available for continuous contracts:
-
- If you use a data normalization mode that's not in the preceding list, LEAN automatically converts it to
-
- DataNormalizationMode.BackwardsRatio
-
- .
-
- The data mapping mode defines when contract rollovers occur. The
-
- DataMappingMode
-
- enumeration has the following members:
-
- VIX Futures don't support continous contract rolling with
-
- DataMappingMode.OpenInterest
-
-
- DataMappingMode.OPEN_INTEREST
-
- and
-
- DataMappingMode.OpenInterestAnnuak
-
-
- DataMappingMode.OPEN_INTEREST_ANNUAL
-
- .
-
- As the contracts roll over, the
-
- Mapped
-
-
- mapped
-
- property of the
-
- Future
-
- object references the next contract in the series and you receive a
-
- SymbolChangedEvent
-
- . To get the current
-
- Symbol
-
- change events, index the
-
- SymbolChangedEvents
-
-
- symbol_changed_events
-
- property of the current
-
-
- Slice
-
-
- with the continuous Futures
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your Future at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Get Symbol Change Event of the Continuous Future (change in mapped contract)
- changed_event = slice.symbol_changed_events.get(self.continuous_future_symbol)
- if changed_event:
- old_symbol = changed_event.old_symbol
- new_symbol = self.add_future_contract(changed_event.new_symbol).symbol
- tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}"
- quantity = self.portfolio[old_symbol].quantity
-
- # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- self.liquidate(old_symbol, tag = tag)
- if quantity != 0: self.market_order(new_symbol, quantity, tag = tag)
- self.log(tag)
- public override void OnData(Slice slice)
-{
- // Get Symbol Change Event of the Continuous Future (change in mapped contract)
- if (slice.SymbolChangedEvents.TryGetValue(_continuousFutureSymbol, out var changedEvent))
- {
- var oldSymbol = changedEvent.OldSymbol;
- var newSymbol = AddFutureContract(changedEvent.NewSymbol).Symbol;
- var tag = $"Rollover - Symbol changed at {Time}: {oldSymbol} -> {newSymbol}";
- var quantity = Portfolio[oldSymbol].Quantity;
- // Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- Liquidate(oldSymbol, tag: tag);
- if (quantity != 0) MarketOrder(newSymbol, quantity, tag: tag);
- Log(tag);
- }
-}
-
-
- SymbolChangedEvent
-
- objects have the following attributes:
-
- You can trade continuous Futures, but the continuous Future
-
- Symbol
-
- doesn't map to a single underlying Future contract. Instead, it represents a set of rolling contracts. Thus, the prices could be frictional during a contract rollover, which could be catastrophic in live trading! For live trading, you should place your orders directly on the underlying contracts. To get the current underlying contract in the continuous Future series, use the
-
- Mapped
-
-
- mapped
-
- property.
-
# Get the mapped symbol -current_contract = self.continuous_contract.mapped -self.buy(current_contract, 1)-
// Get the mapped symbol -var currentContract = _continuousContract.Mapped; -Buy(currentContract, 1);-
- If you download the files in the US Futures Security Master, you get a factor file and a map file for each of the exchanges with supported continuous Futures. To view the files, see the - - \data\future\<exchange_name> - - directory under your LEAN CLI base directory. -
-
- For the factor file, it is a
-
- .zip
-
- collection of REST API styled
-
- .csv
-
- files for each Future
-
- Symbol
-
- , including the date, scaling factors for each type of data normalization and the data mapping mode that indicates the Symbol changing event is on that day for that mapping mode. The following line is an example line in the
-
- .csv
-
- file:
-
- {"Date":"2009-10-31T00:00:00","BackwardsRatioScale":[0.9914163090128755364806866953,1.0,1.0],"BackwardsPanamaCanalScale":[-2.0,0.0,0.0],"ForwardPanamaCanalScale":[0.0,0.0,0.0],"DataMappingMode":1}
-
-
- For the map file, it is a
-
- .zip
-
- collection of
-
- .csv
-
- files for each Future
-
- Symbol
-
- , including the date, new underlying contract Symbol, the exchange code, and the data mapping mode that indicates the Symbol changing event is on that day for that mapping mode. The following line is an example line in the
-
- .csv
-
- file:
-
- 20091130,aw uii3j0m6zbj9,CBOT,1
-
-
-
-
-- You can get historical US Future Security Master data in an algorithm and the Research Environment. -
-
- To get historical US Future Security Master data in an algorithm, call the
-
- History<SymbolChangedEvent>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a lookback period. This method returns the old and new contract of each rollover. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and define its rollover settings. -future = self.add_future( - Futures.Indices.SP_500_E_MINI, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, - contract_depth_offset=0 -) - -# DataFrame example where the columns are the SymbolChangedEvent attributes: -history_df = self.history(SymbolChangedEvent, future.symbol, timedelta(365)) - -# SymbolChangedEvent objects example: -history = self.history[SymbolChangedEvent](future.symbol, timedelta(365))-
// Add the Future and define its rollover settings. -var future = AddFuture( - Futures.Indices.SP500EMini, - dataMappingMode: DataMappingMode.OpenInterest, - dataNormalizationMode: DataNormalizationMode.BackwardsRatio, - contractDepthOffset: 0 -); - -// Get historical data. -var history = History<SymbolChangedEvent>(future.Symbol, TimeSpan.FromDays(365));-
- For more information about historical US Future Security Master data in algorithms, see - - Symbol Changes - - . -
-
- To get historical US Future Security Master data in the Research Environment, call the
-
- History<SymbolChangedEvent>
-
-
- history
-
- method with continuous Future
-
- Symbol
-
- and a time period. This method returns the old and new contract of each rollover. If there is no data for the period you requested, the history result is empty.
-
# Add the Future and define its rollover settings. -future = qb.add_future( - Futures.Indices.SP_500_E_MINI, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, - contract_depth_offset=0 -) - -# DataFrame example where the columns are the SymbolChangedEvent attributes: -history_df = qb.history(SymbolChangedEvent, future.symbol, datetime(2023, 1, 1), datetime(2025, 1, 1)) - -# SymbolChangedEvent objects example: -history = qb.history[SymbolChangedEvent](future.symbol, datetime(2023, 1, 1), datetime(2025, 1, 1))-
// Add the Future and define its rollover settings. -var future = qb.AddFuture( - Futures.Indices.SP500EMini, - dataMappingMode: DataMappingMode.OpenInterest, - dataNormalizationMode: DataNormalizationMode.BackwardsRatio, - contractDepthOffset: 0 -); - -// Get historical data. -var history = qb.History<SymbolChangedEvent>(future.Symbol, new DateTime(2023, 1, 1), new DateTime(2025, 1, 1));-
- For more information about historical US Future Security Master data in the Research Environment, see - - Symbol Changes History - - . -
- - - -- The following list shows the available (157) Futures: -
-
- Futures.Currencies.AUD
-
- : Australian Dollar Futures (CME: 6A)
-
- Futures.Currencies.AUDCAD
-
- : Australian Dollar/Canadian Dollar Futures (CME: ACD)
-
- Futures.Currencies.AUDJPY
-
- : Australian Dollar/Japanese Yen Futures (CME: AJY)
-
- Futures.Currencies.AUDNZD
-
- : Australian Dollar/New Zealand Dollar Futures (CME: ANE)
-
- Futures.Currencies.BRL
-
- : Brazillian Real Futures (CME: 6L)
-
- Futures.Currencies.BTC
-
- : Bitcoin Futures (CME: BTC)
-
- Futures.Currencies.BTICMicroBTC
-
-
- Futures.Currencies.BTIC_MICRO_BTC
-
- : BTIC on Micro Bitcoin Futures (CME: MIB)
-
- Futures.Currencies.BTICMicroEther
-
-
- Futures.Currencies.BTIC_MICRO_ETHER
-
- : BTIC on Micro Ether Futures (CME: MRB)
-
- Futures.Currencies.CAD
-
- : Canadian Dollar Futures (CME: 6C)
-
- Futures.Currencies.CADJPY
-
- : Canadian Dollar/Japanese Yen Futures (CME: CJY)
-
- Futures.Currencies.CHF
-
- : Swiss Franc Futures (CME: 6S)
-
- Futures.Currencies.ETH
-
- : Ether Futures (CME: ETH)
-
- Futures.Currencies.EUR
-
- : Euro FX Futures (CME: 6E)
-
- Futures.Currencies.EURAUD
-
- : Euro/Australian Dollar Futures (CME: EAD)
-
- Futures.Currencies.EURCAD
-
- : Euro/Canadian Dollar Futures (CME: ECD)
-
- Futures.Currencies.EuroFXEmini
-
-
- Futures.Currencies.EURO_FX_EMINI
-
- : E-mini Euro FX Futures (CME: E7)
-
- Futures.Currencies.EURSEK
-
- : Euro/Swedish Krona Futures (CME: ESK)
-
- Futures.Currencies.GBP
-
- : British Pound Futures (CME: 6B)
-
- Futures.Currencies.JapaneseYenEmini
-
-
- Futures.Currencies.JAPANESE_YEN_EMINI
-
- : E-mini Japanese Yen Futures (CME: J7)
-
- Futures.Currencies.JPY
-
- : Japanese Yen Futures (CME: 6J)
-
- Futures.Currencies.MicroAUD
-
-
- Futures.Currencies.MICRO_AUD
-
- : Micro AUD/USD Futures (CME: M6A)
-
- Futures.Currencies.MicroBTC
-
-
- Futures.Currencies.MICRO_BTC
-
- : Micro Bitcoin Futures (CME: MBT)
-
- Futures.Currencies.MicroCAD
-
-
- Futures.Currencies.MICRO_CAD
-
- : Micro USD/CAD Futures (CME: M6C)
-
- Futures.Currencies.MicroCADUSD
-
-
- Futures.Currencies.MICRO_CADUSD
-
- : Micro CAD/USD Futures (CME: MCD)
-
- Futures.Currencies.MicroCHF
-
-
- Futures.Currencies.MICRO_CHF
-
- : Micro CHF/USD Futures (CME: MSF)
-
- Futures.Currencies.MicroEther
-
-
- Futures.Currencies.MICRO_ETHER
-
- : Micro Ether Futures (CME: MET)
-
- Futures.Currencies.MicroEUR
-
-
- Futures.Currencies.MICRO_EUR
-
- : Micro EUR/USD Futures (CME: M6E)
-
- Futures.Currencies.MicroGBP
-
-
- Futures.Currencies.MICRO_GBP
-
- : Micro GBP/USD Futures (CME: M6B)
-
- Futures.Currencies.MicroINRUSD
-
-
- Futures.Currencies.MICRO_INRUSD
-
- : Micro INR/USD Futures (CME: MIR)
-
- Futures.Currencies.MicroJPY
-
-
- Futures.Currencies.MICRO_JPY
-
- : Micro JPY/USD Futures (CME: MJY)
-
- Futures.Currencies.MicroUSDCHF
-
-
- Futures.Currencies.MICRO_USDCHF
-
- : Micro USD/CHF Futures (CME: M6S)
-
- Futures.Currencies.MicroUSDCNH
-
-
- Futures.Currencies.MICRO_USDCNH
-
- : Micro USD/CNH Futures (CME: MNH)
-
- Futures.Currencies.MicroUSDJPY
-
-
- Futures.Currencies.MICRO_USDJPY
-
- : Micro USD/JPY Futures (CME: M6J)
-
- Futures.Currencies.MXN
-
- : Mexican Peso Futures (CME: 6M)
-
- Futures.Currencies.NZD
-
- : New Zealand Dollar Futures (CME: 6N)
-
- Futures.Currencies.RUB
-
- : Russian Ruble Futures (CME: 6R)
-
- Futures.Currencies.StandardSizeUSDOffshoreRMBCNH
-
-
- Futures.Currencies.STANDARD_SIZE_USD_OFFSHORE_RMBCNH
-
- : Standard-Size USD/Offshore RMB (CNH) Futures (CME: CNH)
-
- Futures.Currencies.ZAR
-
- : South African Rand Futures (CME: 6Z)
-
- Futures.Energy.ArgusLLSvsWTIArgusTradeMonth
-
-
- Futures.Energy.ARGUS_LL_SVS_WTI_ARGUS_TRADE_MONTH
-
- : Argus LLS vs. WTI (Argus) Trade Month Futures (NYMEX: AE5)
-
- Futures.Energy.ArgusPropaneFarEastIndex
-
-
- Futures.Energy.ARGUS_PROPANE_FAR_EAST_INDEX
-
- : Argus Propane Far East Index Futures (NYMEX: A7E)
-
- Futures.Energy.ArgusPropaneSaudiAramco
-
-
- Futures.Energy.ARGUS_PROPANE_SAUDI_ARAMCO
-
- : Argus Propane (Saudi Aramco) Futures (NYMEX: A9N)
-
- Futures.Energy.BrentCrudeOilVsDubaiCrudeOilPlatts
-
-
- Futures.Energy.BRENT_CRUDE_OIL_VS_DUBAI_CRUDE_OIL_PLATTS
-
- : Brent Crude Oil vs. Dubai Crude Oil (Platts) Futures (NYMEX: ADB)
-
- Futures.Energy.BrentLastDayFinancial
-
-
- Futures.Energy.BRENT_LAST_DAY_FINANCIAL
-
- : Brent Last Day Financial Futures (NYMEX: BZ)
-
- Futures.Energy.ChicagoEthanolPlatts
-
-
- Futures.Energy.CHICAGO_ETHANOL_PLATTS
-
- : Chicago Ethaanol (Platts) Futures (NYMEX: CU)
-
- Futures.Energy.ConwayPropaneOPIS
-
-
- Futures.Energy.CONWAY_PROPANE_OPIS
-
- : Conway Propane (OPIS) Futures (NYMEX: A8K)
-
- Futures.Energy.CrudeOilWTI
-
-
- Futures.Energy.CRUDE_OIL_WTI
-
- : Crude Oil WTI Futures (NYMEX: CL)
-
- Futures.Energy.DubaiCrudeOilPlattsFinancial
-
-
- Futures.Energy.DUBAI_CRUDE_OIL_PLATTS_FINANCIAL
-
- : Dubai Crude Oil (Platts) Financial Futures (NYMEX: DCB)
-
- Futures.Energy.EastWestGasolineSpreadPlattsArgus
-
-
- Futures.Energy.EAST_WEST_GASOLINE_SPREAD_PLATTS_ARGUS
-
- : East-West Gasoline Spread (Platts-Argus) Futures (NYMEX: EWG)
-
- Futures.Energy.EastWestNaphthaJapanCFvsCargoesCIFNWESpreadPlatts
-
-
- Futures.Energy.EAST_WEST_NAPHTHA_JAPAN_C_FVS_CARGOES_CIFNWE_SPREAD_PLATTS
-
- : East-West Naphtha: Japan C&F vs. Cargoes CIF NWE Spread (Platts) Futures (NYMEX: EWN)
-
- Futures.Energy.Ethanol
-
-
- Futures.Energy.ETHANOL
-
- : Ethanol Futures (CBOT: EH)
-
- Futures.Energy.EthanolT2FOBRdamIncludingDutyPlatts
-
-
- Futures.Energy.ETHANOL_T_2_FOB_RDAM_INCLUDING_DUTY_PLATTS
-
- : Ethanol T2 FOB Rdam Including Duty (Platts) Futures (NYMEX: AZ1)
-
- Futures.Energy.EuropeanNaphthaPlattsCrackSpread
-
-
- Futures.Energy.EUROPEAN_NAPHTHA_PLATTS_CRACK_SPREAD
-
- : European Naphtha (Platts) Crack Spread Futures (NYMEX: EN)
-
- Futures.Energy.EuropeanPropaneCIFARAArgus
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS
-
- : European Propane CIF ARA (Argus) Futures (NYMEX: APS)
-
- Futures.Energy.EuropeanPropaneCIFARAArgusVsNaphthaCargoesCIFNWEPlatts
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS_VS_NAPHTHA_CARGOES_CIFNWE_PLATTS
-
- : European Propane CIF ARA (Argus) vs. Naphtha Cargoes CIF NWE (Platts) Futures (NYMEX: EPN)
-
- Futures.Energy.FreightRouteTC14Baltic
-
-
- Futures.Energy.FREIGHT_ROUTE_TC_14_BALTIC
-
- : Freight Route TC14 (Baltic) Futures (NYMEX: FRC)
-
- Futures.Energy.Gasoline
-
-
- Futures.Energy.GASOLINE
-
- : Gasoline RBOB Futures (NYMEX: RB)
-
- Futures.Energy.GasolineEurobobOxyNWEBargesArgus
-
-
- Futures.Energy.GASOLINE_EUROBOB_OXY_NWE_BARGES_ARGUS
-
- : Gasoline Euro-bob Oxy NWE Barges (Argus) Futures (NYMEX: B7H)
-
- Futures.Energy.GroupThreeSuboctaneGasolinePlattsVsRBOB
-
-
- Futures.Energy.GROUP_THREE_SUBOCTANE_GASOLINE_PLATTS_VS_RBOB
-
- : Group Three Sub-octane Gasoliine (Platts) vs. RBOB Futures (NYMEX: AA8)
-
- Futures.Energy.GroupThreeULSDPlattsVsNYHarborULSD
-
-
- Futures.Energy.GROUP_THREE_ULSD_PLATTS_VS_NY_HARBOR_ULSD
-
- : Group Three ULSD (Platts) vs. NY Harbor ULSD Futures (NYMEX: AA6)
-
- Futures.Energy.GulfCoastCBOBGasolineA2PlattsVsRBOBGasoline
-
-
- Futures.Energy.GULF_COAST_CBOB_GASOLINE_A_2_PLATTS_VS_RBOB_GASOLINE
-
- : Gulf Coast CBOB Gasoline A2 (Platts) vs. RBOB Gasoline Futures (NYMEX: CRB)
-
- Futures.Energy.GulfCoastHSFOPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.GULF_COAST_HSFO_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Gulf Coast HSFO (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: GCU)
-
- Futures.Energy.HeatingOil
-
-
- Futures.Energy.HEATING_OIL
-
- : Heating Oil Futures (NYMEX: HO)
-
- Futures.Energy.LosAngelesCARBOBGasolineOPISvsRBOBGasoline
-
-
- Futures.Energy.LOS_ANGELES_CARBOB_GASOLINE_OPI_SVS_RBOB_GASOLINE
-
- : Los Angeles CARBOB Gasoline (OPIS) vs. RBOB Gasoline Futures (NYMEX: AJL)
-
- Futures.Energy.LosAngelesCARBDieselOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_CARB_DIESEL_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles CARB Diesel (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AKL)
-
- Futures.Energy.LosAngelesJetOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_JET_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles Jet (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AJS)
-
- Futures.Energy.MarsArgusVsWTIFinancial
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_FINANCIAL
-
- : Mars (Argus) vs. WTI Financial Futures (NYMEX: AYX)
-
- Futures.Energy.MarsArgusVsWTITradeMonth
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_TRADE_MONTH
-
- : Mars (Argus) vs. WTI Trade Month Futures (NYMEX: AYV)
-
- Futures.Energy.MicroCrudeOilWTI
-
-
- Futures.Energy.MICRO_CRUDE_OIL_WTI
-
- : Micro WTI Crude Oil Futures (NYMEX: MCL)
-
- Futures.Energy.MicroEuropeanFOBRdamMarineFuelZeroPointFivePercentBargesPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_FOB_RDAM_MARINE_FUEL_ZERO_POINT_FIVE_PERCENT_BARGES_PLATTS
-
- : Micro European FOB Rdam Marine Fuel 0.5% Barges (Platts) Futures (NYMEX: R5O)
-
- Futures.Energy.MicroEuropeanThreePointFivePercentOilBargesFOBRdamPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_THREE_POINT_FIVE_PERCENT_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Micro European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: MEF)
-
- Futures.Energy.MicroGasoilZeroPointOnePercentBargesFOBARAPlatts
-
-
- Futures.Energy.MICRO_GASOIL_ZERO_POINT_ONE_PERCENT_BARGES_FOBARA_PLATTS
-
- : Micro Gasoil 0.1% Barges FOB ARA (Platts) Futures (NYMEX: M1B)
-
- Futures.Energy.MicroSingaporeFOBMarineFuelZeroPointFivePercetPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FOB_MARINE_FUEL_ZERO_POINT_FIVE_PERCET_PLATTS
-
- : Micro Singapore FOB Marine Fuel 0.5% (Platts) Futures (NYMEX: S5O)
-
- Futures.Energy.MicroSingaporeFuelOil380CSTPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FUEL_OIL_380_CST_PLATTS
-
- : Micro Singapore Fuel Oil 380CST (Platts) Futures (NYMEX: MAF)
-
- Futures.Energy.MiniEuropeanThreePointPercentFiveFuelOilBargesPlatts
-
-
- Futures.Energy.MINI_EUROPEAN_THREE_POINT_PERCENT_FIVE_FUEL_OIL_BARGES_PLATTS
-
- : Mini European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: A0D)
-
- Futures.Energy.MiniSingaporeFuelOil180CstPlatts
-
-
- Futures.Energy.MINI_SINGAPORE_FUEL_OIL_180_CST_PLATTS
-
- : Mini Singapore Fuel Oil 180 cst (Platts) Futures (NYMEX: A0F)
-
- Futures.Energy.MontBelvieuEthaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_ETHANE_OPIS
-
- : Mont Belvieu Ethane (OPIS) Futures (NYMEX: AC0)
-
- Futures.Energy.MontBelvieuLDHPropaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_LDH_PROPANE_OPIS
-
- : Mont Belvieu LDH Propane (OPIS) Futures (NYMEX: B0)
-
- Futures.Energy.MontBelvieuNaturalGasolineOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NATURAL_GASOLINE_OPIS
-
- : Mont Belvieu Natural Gasoline (OPIS) Futures (NYMEX: A7Q)
-
- Futures.Energy.MontBelvieuNormalButaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NORMAL_BUTANE_OPIS
-
- : Mont Belvieu Normal Butane (OPIS) Futures (NYMEX: AD0)
-
- Futures.Energy.NaturalGas
-
-
- Futures.Energy.NATURAL_GAS
-
- : Natural Gas Futures (NYMEX: NG)
-
- Futures.Energy.NaturalGasHenryHubLastDayFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_LAST_DAY_FINANCIAL
-
- : Natural Gas (Henry Hub) Last-day Financial Futures (NYMEX: HH)
-
- Futures.Energy.NaturalGasHenryHubPenultimateFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_PENULTIMATE_FINANCIAL
-
- : Natural Gas (Henry Hub) Penultimate Financial Futures (NYMEX: HP)
-
- Futures.Energy.OnePercentFuelOilCargoesFOBNWEPlattsVsThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.ONE_PERCENT_FUEL_OIL_CARGOES_FOBNWE_PLATTS_VS_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : 1% Fuel Oil Cargoes FOB NWE (Platts) vs. 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: FSS)
-
- Futures.Energy.PremiumUnleadedGasoline10ppmFOBMEDPlatts
-
-
- Futures.Energy.PREMIUM_UNLEADED_GASOLINE_10_PPM_FOBMED_PLATTS
-
- : Premium Unleaded Gasoline 10 ppm FOB MED (Platts) Futures (NYMEX: A3G)
-
- Futures.Energy.PropaneNonLDHMontBelvieuOPIS
-
-
- Futures.Energy.PROPANE_NON_LDH_MONT_BELVIEU_OPIS
-
- : Propane Non-LDH Mont Belvieu (OPIS) Futures (NYMEX: A1R)
-
- Futures.Energy.RBOBGasolineCrackSpread
-
-
- Futures.Energy.RBOB_GASOLINE_CRACK_SPREAD
-
- : RBOB Gasoline Crack Spread Futures (NYMEX: ARE)
-
- Futures.Energy.RBOBGasolineVsEurobobOxyNWEBargesArgusThreeHundredFiftyThousandGallons
-
-
- Futures.Energy.RBOB_GASOLINE_VS_EUROBOB_OXY_NWE_BARGES_ARGUS_THREE_HUNDRED_FIFTY_THOUSAND_GALLONS
-
- : RBOB Gasoline vs. Euro-bob Oxy NWE Barges (Argus) (350,000 gallons) Futures (NYMEX: EXR)
-
- Futures.Energy.SingaporeFuelOil380cstPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.SINGAPORE_FUEL_OIL_380_CST_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Singapore Fuel Oil 380 cst (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: EVC)
-
- Futures.Energy.SingaporeGasoilPlattsVsLowSulphurGasoilFutures
-
-
- Futures.Energy.SINGAPORE_GASOIL_PLATTS_VS_LOW_SULPHUR_GASOIL_FUTURES
-
- : Singapore Gasoil (Platts) vs. Low Sulphur Gasoil Futures (NYMEX: AGA)
-
- Futures.Energy.SingaporeMogas92UnleadedPlattsBrentCrackSpread
-
-
- Futures.Energy.SINGAPORE_MOGAS_92_UNLEADED_PLATTS_BRENT_CRACK_SPREAD
-
- : Singapore Mogas 92 Unleaded (Platts) Brent Crack Spread Futures (NYMEX: D1N)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread Futures (NYMEX: FO)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread1000mt
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD_1000_MT
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread (1000mt) Futures (NYMEX: BOO)
-
- Futures.Energy.WTIBrentFinancial
-
-
- Futures.Energy.WTI_BRENT_FINANCIAL
-
- : WTI-Brent Financial Futures (NYMEX: BK)
-
- Futures.Energy.WTIFinancial
-
-
- Futures.Energy.WTI_FINANCIAL
-
- : WTI Financial Futures (NYMEX: CSX)
-
- Futures.Energy.WTIHoustonArgusVsWTITradeMonth
-
-
- Futures.Energy.WTI_HOUSTON_ARGUS_VS_WTI_TRADE_MONTH
-
- : WTI Houston (Argus) vs. WTI Trade Month Futures (NYMEX: HTT)
-
- Futures.Energy.WTIHoustonCrudeOil
-
-
- Futures.Energy.WTI_HOUSTON_CRUDE_OIL
-
- : WTI Houston Crude Oil Futures (NYMEX: HCL)
-
- Futures.Financials.EuroDollar
-
-
- Futures.Financials.EURO_DOLLAR
-
- : EuroDollar Futures (CME: GE)
-
- Futures.Financials.FiveYearUSDMACSwap
-
-
- Futures.Financials.FIVE_YEAR_USDMAC_SWAP
-
- : 5-Year USD MAC Swap Futures (CBOT: F1U)
-
- Futures.Financials.MicroY10TreasuryNote
-
-
- Futures.Financials.MICRO_Y_10_TREASURY_NOTE
-
- : Micro 10-Year Yield Futures (CBOT: 10Y)
-
- Futures.Financials.MicroY2TreasuryBond
-
-
- Futures.Financials.MICRO_Y_2_TREASURY_BOND
-
- : Micro 2-Year Yield Futures (CBOT: 2YY)
-
- Futures.Financials.MicroY30TreasuryBond
-
-
- Futures.Financials.MICRO_Y_30_TREASURY_BOND
-
- : Micro 30-Year Yield Futures (CBOT: 30Y)
-
- Futures.Financials.MicroY5TreasuryBond
-
-
- Futures.Financials.MICRO_Y_5_TREASURY_BOND
-
- : Micro 5-Year Yield Futures (CBOT: 5YY)
-
- Futures.Financials.UltraTenYearUSTreasuryNote
-
-
- Futures.Financials.ULTRA_TEN_YEAR_US_TREASURY_NOTE
-
- : Ultra 10-Year U.S. Treasury Note Futures (CBOT: TN)
-
- Futures.Financials.UltraUSTreasuryBond
-
-
- Futures.Financials.ULTRA_US_TREASURY_BOND
-
- : Ultra U.S. Treasury Bond Futures (CBOT: UB)
-
- Futures.Financials.Y10TreasuryNote
-
-
- Futures.Financials.Y_10_TREASURY_NOTE
-
- : 10Y U.S. Treasury Note Futures (CBOT: ZN)
-
- Futures.Financials.Y2TreasuryNote
-
-
- Futures.Financials.Y_2_TREASURY_NOTE
-
- : 2Y U.S. Treasury Note Futures (CBOT: ZT)
-
- Futures.Financials.Y30TreasuryBond
-
-
- Futures.Financials.Y_30_TREASURY_BOND
-
- : 30Y U.S. Treasury Bond Futures (CBOT: ZB)
-
- Futures.Financials.Y5TreasuryNote
-
-
- Futures.Financials.Y_5_TREASURY_NOTE
-
- : 5Y U.S. Treasury Note Futures (CBOT: ZF)
-
- Futures.Forestry.Lumber
-
-
- Futures.Forestry.LUMBER
-
- : Lumber Futures (CME: LBR)
-
- Futures.Forestry.RandomLengthLumber
-
-
- Futures.Forestry.RANDOM_LENGTH_LUMBER
-
- : Random Length Lumber Futures (CME: LBS)
-
- Futures.Grains.BlackSeaCornFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_CORN_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Corn Financially Settled (Platts) Futures (CBOT: BCF)
-
- Futures.Grains.BlackSeaWheatFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_WHEAT_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Wheat Financially Settled (Platts) Futures (CBOT: BWF)
-
- Futures.Grains.Corn
-
-
- Futures.Grains.CORN
-
- : Corn Futures (CBOT: ZC)
-
- Futures.Grains.HRWWheat
-
-
- Futures.Grains.HRW_WHEAT
-
- : KC HRW Wheat Futures (CBOT: KE)
-
- Futures.Grains.Oats
-
-
- Futures.Grains.OATS
-
- : Oats Futures (CBOT: ZO)
-
- Futures.Grains.Soybeans
-
-
- Futures.Grains.SOYBEANS
-
- : Soybeans Futures (CBOT: ZS)
-
- Futures.Grains.SoybeanMeal
-
-
- Futures.Grains.SOYBEAN_MEAL
-
- : Soybean Meal Futures (CBOT: ZM)
-
- Futures.Grains.SoybeanOil
-
-
- Futures.Grains.SOYBEAN_OIL
-
- : Soybean Oil Futures (CBOT: ZL)
-
- Futures.Grains.Wheat
-
-
- Futures.Grains.WHEAT
-
- : Default wheat contract is SRWWheat (CBOT: ZW)
-
- Futures.Indices.BloombergCommodityIndex
-
-
- Futures.Indices.BLOOMBERG_COMMODITY_INDEX
-
- : Bloomberg Commodity Index Futures (CBOT: AW)
-
- Futures.Indices.Dow30EMini
-
-
- Futures.Indices.DOW_30_E_MINI
-
- : E-mini Dow Indu 30 Futures (CBOT: YM)
-
- Futures.Indices.DowJonesRealEstate
-
-
- Futures.Indices.DOW_JONES_REAL_ESTATE
-
- : Dow Jones Real Estate futures on CME (CME: RX)
-
- Futures.Indices.FTSEEmergingEmini
-
-
- Futures.Indices.FTSE_EMERGING_EMINI
-
- : E-mini FTSE Emerging Index Futures (CME: EI)
-
- Futures.Indices.MicroDow30EMini
-
-
- Futures.Indices.MICRO_DOW_30_E_MINI
-
- : Micro E-mini Dow Jones Industrial Average Index Futures (CBOT: MYM)
-
- Futures.Indices.MicroNASDAQ100EMini
-
-
- Futures.Indices.MICRO_NASDAQ_100_E_MINI
-
- : Micro E-mini Nasdaq-100 Index Futures (CME: MNQ)
-
- Futures.Indices.MicroRussell2000EMini
-
-
- Futures.Indices.MICRO_RUSSELL_2000_E_MINI
-
- : Micro E-mini Russell 2000 Index Futures (CME: M2K)
-
- Futures.Indices.MicroSP500EMini
-
-
- Futures.Indices.MICRO_SP_500_E_MINI
-
- : Micro E-mini S&P 500 Index Futures (CME: MES)
-
- Futures.Indices.NASDAQ100BiotechnologyEMini
-
-
- Futures.Indices.NASDAQ_100_BIOTECHNOLOGY_E_MINI
-
- : E-mini Nasdaq-100 Biotechnology Index Futures (CME: BIO)
-
- Futures.Indices.NASDAQ100EMini
-
-
- Futures.Indices.NASDAQ_100_E_MINI
-
- : E-mini NASDAQ 100 Futures (CME: NQ)
-
- Futures.Indices.Nikkei225Dollar
-
-
- Futures.Indices.NIKKEI_225_DOLLAR
-
- : Nikkei-225 Dollar Futures (CME: NKD)
-
- Futures.Indices.Nikkei225YenCME
-
-
- Futures.Indices.NIKKEI_225_YEN_CME
-
- : Nikkei-225 Yen denominated Futures on CME (CME: NIY)
-
- Futures.Indices.Russell1000EMini
-
-
- Futures.Indices.RUSSELL_1000_E_MINI
-
- : E-mini Russell 1000 futures on CME (CME: RS1)
-
- Futures.Indices.Russell2000EMini
-
-
- Futures.Indices.RUSSELL_2000_E_MINI
-
- : E-mini Russell 2000 Futures (CME: RTY)
-
- Futures.Indices.SPGSCICommodity
-
-
- Futures.Indices.SPGSCI_COMMODITY
-
- : S&P-GSCI Commodity Index Futures (CME: GD)
-
- Futures.Indices.SP400MidCapEmini
-
-
- Futures.Indices.SP_400_MID_CAP_EMINI
-
- : E-mini S&P MidCap 400 Futures (CME: EMD)
-
- Futures.Indices.SP500AnnualDividendIndex
-
-
- Futures.Indices.SP_500_ANNUAL_DIVIDEND_INDEX
-
- : (CME: SDA)
-
- Futures.Indices.SP500EMini
-
-
- Futures.Indices.SP_500_E_MINI
-
- : E-mini S&P 500 Futures (CME: ES)
-
- Futures.Indices.TOPIXYEN
-
- : YEN Denominated Topix Index Futures on CME (CME: TPY)
-
- Futures.Indices.USDDenominatedIbovespa
-
-
- Futures.Indices.USD_DENOMINATED_IBOVESPA
-
- : USD-Denominated Ibovespa Index Futures (CME: IBV)
-
- Futures.Indices.VIX
-
- : CBOE Volatility Index Futures (CFE: VX)
-
- Futures.Meats.FeederCattle
-
-
- Futures.Meats.FEEDER_CATTLE
-
- : Feeder Cattle Futures (CME: GF)
-
- Futures.Meats.LeanHogs
-
-
- Futures.Meats.LEAN_HOGS
-
- : Lean Hogs Futures (CME: HE)
-
- Futures.Meats.LiveCattle
-
-
- Futures.Meats.LIVE_CATTLE
-
- : Live Cattle Futures (CME: LE)
-
- Futures.Metals.AluminiumEuropeanPremiumDutyPaidMetalBulletin
-
-
- Futures.Metals.ALUMINIUM_EUROPEAN_PREMIUM_DUTY_PAID_METAL_BULLETIN
-
- : Aluminium European Premium Duty-Paid (Metal Bulletin) Futures (COMEX: EDP)
-
- Futures.Metals.AluminumMWUSTransactionPremiumPlatts25MT
-
-
- Futures.Metals.ALUMINUM_MWUS_TRANSACTION_PREMIUM_PLATTS_25_MT
-
- : Aluminum MW U.S. Transaction Premium Platts (25MT) Futures (COMEX: AUP)
-
- Futures.Metals.Copper
-
-
- Futures.Metals.COPPER
-
- : Copper Futures (COMEX: HG)
-
- Futures.Metals.Gold
-
-
- Futures.Metals.GOLD
-
- : Gold Futures (COMEX: GC)
-
- Futures.Metals.MicroGold
-
-
- Futures.Metals.MICRO_GOLD
-
- : Micro Gold Futures (COMEX: MGC)
-
- Futures.Metals.MicroGoldTAS
-
-
- Futures.Metals.MICRO_GOLD_TAS
-
- : Micro Gold TAS Futures (COMEX: MGT)
-
- Futures.Metals.MicroPalladium
-
-
- Futures.Metals.MICRO_PALLADIUM
-
- : Micro Palladium Futures (NYMEX: PAM)
-
- Futures.Metals.MicroSilver
-
-
- Futures.Metals.MICRO_SILVER
-
- : Micro Silver Futures (COMEX: SIL)
-
- Futures.Metals.Palladium
-
-
- Futures.Metals.PALLADIUM
-
- : Palladium Futures (NYMEX: PA)
-
- Futures.Metals.Platinum
-
-
- Futures.Metals.PLATINUM
-
- : Platinum Futures (NYMEX: PL)
-
- Futures.Metals.Silver
-
-
- Futures.Metals.SILVER
-
- : Silver Futures (COMEX: SI)
-
- Futures.Metals.USMidwestDomesticHotRolledCoilSteelCRUIndex
-
-
- Futures.Metals.US_MIDWEST_DOMESTIC_HOT_ROLLED_COIL_STEEL_CRU_INDEX
-
- : U.S. Midwest Domestic Hot-Rolled Coil Steel (CRU) Index Futures (NYMEX: HRC)
-
- Futures.Softs.Sugar11
-
-
- Futures.Softs.SUGAR_11
-
- : Sugar #11 Futures ICE (ICE: SB)
-
- Futures.Softs.Sugar11CME
-
-
- Futures.Softs.SUGAR_11_CME
-
- : Sugar #11 Futures CME (NYMEX: YO)
- - The US Futures Security Master enables you to design strategies harnessing continuous Futures contracts. Examples include the following strategies: -
-- The following example algorithm buys the continuous Future contract for Crude Oil when its price rises above its simple moving average. When its price drops below its simple moving average, the algorithm sells the continuous contract. Each time the continuous Future contract rolls over, the algorithm logs the event. -
-from AlgorithmImports import *
-
-
-class USFuturesSecurityMasterDataClassicAlgorithm(QCAlgorithm):
- # Define a threshold for the SMA cross.
- _threshold = 0.01
-
- def initialize(self) -> None:
- self.set_cash(1000000)
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Seed the price of each asset with its last known price to
- # avoid trading errors.
- self.settings.seed_initial_prices = True
- # Add a Future. Set the continuous contract mapping criteria to
- # the contract with highest open interest to provide the best
- # price information for trend estimation.
- self._future = self.add_future(
- Futures.Energy.CRUDE_OIL_WTI,
- data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
- data_mapping_mode=DataMappingMode.OPEN_INTEREST,
- contract_depth_offset=0
- )
- # Historical data: Get the contract rollovers for the trailing
- # year.
- history = self.history(
- SymbolChangedEvent, self._future.symbol, timedelta(365)
- )
- # Set up an SMA indicator for to estimate the trend direction.
- self._sma = self.sma(self._future.symbol, 10, Resolution.DAILY)
- # Warm up the SMA indicator so we can trade right away.
- self.warm_up_indicator(self._future.symbol, self._sma)
-
- def on_data(self, slice: Slice) -> None:
- # Wait until we have the latest TradeBar and the indicator is
- # ready.
- if not (self._future.symbol in slice.bars and self._sma.is_ready):
- return
- contract = self.portfolio[self._future.mapped]
- # Long during an uptrend.
- if (not contract.is_long and
- self._future.price > self._sma.current.value * (1+self._threshold)):
- quantity = 1
- # Short during an downtrend.
- elif (not contract.is_short and
- self._future.price < self._sma.current.value * (1-self._threshold)):
- quantity = -1
- else:
- return
- self.market_order(self._future.mapped, quantity - contract.quantity)
-
- def on_symbol_changed_events(self, symbol_changed_events):
- for symbol, changed_event in symbol_changed_events.items():
- old_symbol = changed_event.old_symbol
- new_symbol = changed_event.new_symbol
- # The quantity to roll over should be consistent.
- quantity = self.portfolio[old_symbol].quantity
- if not quantity:
- continue
- # Rolling over: Liquidate the old mapped contract and switch
- # to the new mapped contract.
- tag = f"Rollover: {old_symbol} -> {new_symbol}"
- self.liquidate(old_symbol, tag=tag)
- self.market_order(new_symbol, quantity, tag=tag)
- public class USFuturesSecurityMasterDataClassicAlgorithm : QCAlgorithm
-{
- private Future _future;
- // Define a threshold for the SMA cross.
- private decimal _threshold = 0.01m;
- private SimpleMovingAverage _sma;
-
- public override void Initialize()
- {
- SetCash(1000000);
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Seed the price of each asset with its last known price to
- // avoid trading errors.
- Settings.SeedInitialPrices = true;
- // Add a Future. Set the continuous contract mapping criteria to
- // the contract with highest open interest to provide the best
- // price information for trend estimation.
- _future = AddFuture(
- Futures.Energy.CrudeOilWTI,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- dataMappingMode: DataMappingMode.OpenInterest,
- contractDepthOffset: 0
- );
- // Historical data: Get the contract rollovers for the trailing
- // year.
- var history = History<SymbolChangedEvent>(_future.Symbol, TimeSpan.FromDays(365));
- foreach (var symbolChangedEvent in history)
- {
- var t = symbolChangedEvent.EndTime;
- var oldSymbol = symbolChangedEvent.OldSymbol;
- var newSymbol = symbolChangedEvent.NewSymbol;
- }
- // Set up an SMA indicator for to estimate the trend direction.
- _sma = SMA(_future.Symbol, 10, Resolution.Daily);
- // Warm up the SMA indicator so we can trade right away.
- WarmUpIndicator(_future.Symbol, _sma);
- }
-
- public override void OnData(Slice slice)
- {
- // Wait until we have the latest TradeBar and the indicator is
- // ready.
- if (!(slice.Bars.ContainsKey(_future.Symbol) && _sma.IsReady))
- {
- return;
- }
- var contract = Portfolio[_future.Mapped];
- int quantity;
- // Long during an uptrend.
- if (!contract.IsLong && _future.Price > _sma.Current.Value * (1+_threshold))
- {
- quantity = 1;
- }
- // Short during an downtrend.
- else if (!contract.IsShort && _future.Price < _sma.Current.Value * (1-_threshold))
- {
- quantity = -1;
- }
- else
- {
- return;
- }
- MarketOrder(_future.Mapped, quantity - contract.Quantity);
- }
-
- public override void OnSymbolChangedEvents(SymbolChangedEvents symbolChangedEvents)
- {
- foreach (var (symbol, changedEvent) in symbolChangedEvents)
- {
- var oldSymbol = changedEvent.OldSymbol;
- var newSymbol = changedEvent.NewSymbol;
- // The quantity to roll over should be consistent.
- var quantity = Portfolio[oldSymbol].Quantity;
- if (quantity == 0)
- {
- continue;
- }
- // Rolling over: Liquidate the old mapped contract and switch
- // to the new mapped contract.
- var tag = $"Rollover: {oldSymbol} -> {newSymbol}";
- Liquidate(oldSymbol, tag: tag);
- MarketOrder(newSymbol, quantity, tag: tag);
- }
- }
-}
- - The following example algorithm buys the continuous Future contract for Crude Oil when its price rises above its simple moving average. When its price drops below its simple moving average, the algorithm sells the continuous contract. Each time the contract rolls over, the algorithm logs the event. -
-from AlgorithmImports import *
-
-
-class USFuturesSecurityMasterDataFrameworkAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_cash(1000000)
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
-
- # Setting the continuous contract mapping criteria, the contract with highest open interest provide the best price information for trend estimation
- self.add_future(Futures.Energies.CRUDE_OIL_WTI,
- data_normalization_mode = DataNormalizationMode.BACKWARDS_RATIO,
- data_mapping_mode = DataMappingMode.OPEN_INTEREST,
- contract_depth_offset = 0)
- self.add_alpha(ContinuousFuturesAlphaModel())
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-class ContinuousFuturesAlphaModel(AlphaModel):
- # 1% margin to reassure trend direction
- threshold = 0.01
- symbol = None
- continuous_contract = None
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
- # Check if contract data available, since all trades are based on that only
- if self.continuous_contract_symbol is None or self.continuous_contract is None:
- return insights
-
- # Up-to-date handling of switching the mapped contract for trade liquidity
- for symbol, changed_event in slice.symbol_changed_events.items():
- old_symbol = changed_event.old_symbol
- if algorithm.insights.has_active_insights(old_symbol, algorithm.utc_time):
- new_symbol = changed_event.new_symbol
- tag = f"Rollover - Symbol changed at {algorithm.time}: {old_symbol} -> {new_symbol}"
- last_insight = sorted(algorithm.insights[old_symbol], key=lambda x: x.close_time_utc)[-1]
- insights.append(Insight.price(new_symbol, last_insight.close_time_utc, last_insight.direction, tag= tag))
- algorithm.insights.clear([old_symbol])
- algorithm.log(tag)
-
- mapped_symbol = self.continuous_contract.mapped
- # Make sure trade decisions are based on newly received data
- if not slice.bars.contains_key(self.continuous_contract_symbol) or not self.sma.is_ready or not mapped_symbol:
- return insights
-
- direction = None
- # Long if trend up by threshold to follow the trend
- if slice.bars[self.continuous_contract_symbol].price > self.sma.current.value * (1+self.threshold) and not algorithm.portfolio[mapped_symbol].is_long:
- direction = InsightDirection.UP
- # Short if trend down by threshold to follow the trend
- elif slice.bars[self.continuous_contract_symbol].price < self.sma.current.value * (1-self.threshold) and not algorithm.portfolio[mapped_symbol].is_short:
- direction = InsightDirection.DOWN
-
- if direction:
- insights.append(Insight.price(mapped_symbol, timedelta(days=14), direction))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- symbol = security.symbol
- # Set up SMA indicator for trend direction estimator, only for the canonical symbol
- if symbol.is_canonical():
- self.continuous_contract = security
- self.continuous_contract_symbol = symbol
- self.sma = algorithm.SMA(self.continuous_contract_symbol, 10, Resolution.DAILY)
-
- # Historical data
- history = algorithm.history(symbol, 60*24*10, Resolution.MINUTE)
- algorithm.debug(f"We got {len(history)} from our history request for {symbol}")
-
- if history.empty:
- continue
- # Warm up the SMA indicator for its readiness for immediate use
- for time, row in history.droplevel(0).loc[self.continuous_contract_symbol].iterrows():
- self.sma.update(IndicatorDataPoint(time, row.close))
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class USFuturesSecurityMasterDataFrameworkAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetCash(1000000);
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
-
- // Setting the continuous contract mapping criteria, the contract with highest open interest provide the best price information for trend estimation
- AddFuture(Futures.Energies.CrudeOilWTI,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- dataMappingMode: DataMappingMode.OpenInterest,
- contractDepthOffset: 0
- );
- AddAlpha(new ContinuousFuturesAlphaModel());
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-
- class ContinuousFuturesAlphaModel : AlphaModel
- {
- private Future _continuousContract;
- private Symbol _symbol;
- // 1% margin to reassure trend direction
- private decimal _threshold = 0.01m;
- private SimpleMovingAverage _sma;
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- // Check if contract data available, since all trades are based on that only
- if (_symbol == null || _continuousContract == null)
- {
- return insights;
- }
-
- // Up-to-date handling of switching the mapped contract for trade liquidity
- foreach (var (symbol, changedEvent) in slice.SymbolChangedEvents)
- {
- var oldSymbol = changedEvent.OldSymbol;
- if (algorithm.Insights.HasActiveInsights(oldSymbol, algorithm.UtcTime))
- {
- var newSymbol = changedEvent.NewSymbol;
- var tag = $"Rollover - Symbol changed at {algorithm.Time}: {oldSymbol} -> {newSymbol}";
- var lastInsight = algorithm.Insights[oldSymbol].OrderBy(x => x.CloseTimeUtc).LastOrDefault();
- insights.Add(Insight.Price(newSymbol, lastInsight.CloseTimeUtc, lastInsight.Direction, tag: tag));
- algorithm.Insights.Clear(new Symbol[] { oldSymbol });
- algorithm.Log(tag);
- }
- }
-
- var mappedSymbol = _continuousContract.Mapped;
- // Make sure trade decisions are based on newly received data
- if (!slice.Bars.ContainsKey(_symbol) || !_sma.IsReady || mappedSymbol == null)
- {
- return insights;
- }
-
- // Long if trend up by threshold to follow the trend
- if (slice.Bars[_symbol].Price > _sma.Current.Value * (1+_threshold) && !algorithm.Portfolio[mappedSymbol].IsLong)
- {
- insights.Add(Insight.Price(mappedSymbol, TimeSpan.FromDays(14), InsightDirection.Up));
- }
- // Short if trend down by threshold to follow the trend
- else if (slice.Bars[_symbol].Price < _sma.Current.Value * (1-_threshold) && !algorithm.Portfolio[mappedSymbol].IsShort)
- {
- insights.Add(Insight.Price(mappedSymbol, TimeSpan.FromDays(14), InsightDirection.Down));
- }
-
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- var symbol = security.Symbol;
- // Set up SMA indicator for trend direction estimator, only for the canonical symbol
- if (symbol.IsCanonical())
- {
- _continuousContract = (Future)security;
- _symbol = symbol;
- _sma = algorithm.SMA(_symbol, 10, Resolution.Daily);
-
- // Historical data
- var history = algorithm.History(symbol, 60*24*10, Resolution.Minute);
- algorithm.Debug($"We got {history.Count()} from our history request for {symbol}");
-
- // Warm up the SMA indicator for its readiness for immediate use
- foreach (var bar in history)
- {
- _sma.Update(new IndicatorDataPoint(bar.Time, bar.Close));
- }
- }
- }
- }
- }
-
- class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
- {
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
- }
-}
-
- The US Futures Security Master dataset provides
-
- SymbolChangedEvent
-
- objects, which have the following attributes:
-
- -
- The US Index Option Universe dataset by QuantConnect lists the available US Index Options contracts and the current Implied Volatility and Greeks. The data covers European Option contracts for 3 US Indices: SPX, VIX, and NDX. It starts in January 2012 and is delivered on a daily update frequency. To create this dataset, we use - - our implementation - - of the forward tree pricing model, which accounts for the interest rate, dividend payments, and daily closing prices. The values in this dataset are the same values you can get from daily - - indicators - - with mirror Options. -
-
- This dataset
-
- does not
-
- contain market data. For market data, see
-
- US Index Options by AlgoSeek
-
- .
-
- For more information about the US Index Option Universe dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. -
- - - -- The following snippet demonstrates how to request data from the US Index Options Universe dataset: -
-option = self.add_index_option('VIX')
-option.set_filter(lambda universe: universe.delta(0.4, 0.6))
-self.option_symbol = option.symbol
- var option = AddIndexOption("VIX");
-option.SetFilter(universe => universe.delta(0.4m, 0.6m));
-_optionSymbol = option.Symbol;
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012 - | -
| - Asset Coverage - | -- 7 Index Options - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- According to the SPX Options - - contract specification - - , some SPX contracts expire every month and SPXW contracts expires every day. Before 2021, you could only trade SPX contracts with the following expiration dates: -
-- During this time, SPXW didn't have 0DTE every day. -
-
-
- Sources
-
- :
-
- -
-
- Cboe Options Exchange to List Three Long-Dated SPX Options Expirations, Beginning November 1, 2021
-
-
- -
-
- S&P 500 Weekly Options Now Expire Five Days a Week
-
-
- To add US Index Options Universe data to your algorithm, call the
-
- AddIndexOption
-
-
- add_index_option
-
- method. Save a reference to the Index Option
-
- Symbol
-
- so you can access the data later in your algorithm. To define which contracts should be in your universe, call the
-
- SetFilter
-
-
- set_filter
-
- method of the
-
- IndexOption
-
- object.
-
- The
-
- AddIndexOption
-
-
- add_index_option
-
- method provides a daily stream of Option chain data. To get the most recent daily chain, call the
-
- OptionChain
-
-
- option_chain
-
- method with the canonical Index Option Symbol. The
-
- OptionChain
-
-
- option_chain
-
- method returns data on all the tradable contracts, not just the contracts that pass your universe filter.
-
class IndexOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2021, 1, 1)
- self.set_end_date(2021, 6, 1)
- self.set_cash(1_000_000)
- self.universe_settings.asynchronous = True
- self.index_symbol = self.add_index('VIX').symbol
-
- standard_option = self.add_index_option(self.index_symbol)
- standard_option.set_filter(self._option_filter)
- self.standard_option_symbol = standard_option.symbol
- standard_chain = self.option_chain(standard_option.symbol, flatten=True).data_frame
-
- weekly_option = self.add_index_option(self.index_symbol, "VIXW")
- weekly_option.set_filter(self._option_filter)
- self.weekly_option_symbol = weekly_option.symbol
- weekly_chain = self.option_chain(weekly_option.symbol, flatten=True).data_frame
- weekly_chain = weekly_chain[
- weekly_chain.index.map(lambda symbol: not IndexOptionSymbol.is_standard(symbol))
- ]
-
-
- def _option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Contracts can be filtered by greeks, implied volatility, open interest:
- return universe \
- .delta(0.5, 1.5) \
- .gamma(0.0001, 0.0006) \
- .vega(0.01, 1.5) \
- .theta(-2.0, -0.5) \
- .rho(0.5, 3.0) \
- .implied_volatility(1, 3) \
- .open_interest(100,500)
- public class IndexOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _indexSymbol, _standardOptionSymbol, _weeklyOptionSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2021, 1, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- _indexSymbol = AddIndex("VIX").Symbol;
-
- var standardOption = AddIndexOption(_indexSymbol);
- standardOption.SetFilter(OptionFilter);
- _standardOptionSymbol = standardOption.Symbol;
- var standardChain = OptionChain(_standardOptionSymbol);
-
- var weeklyOption = AddIndexOption(_indexSymbol, "VIXW");
- weeklyOption.SetFilter(OptionFilter);
- _weeklyOptionSymbol = weeklyOption.Symbol;
- var weeklyChain = OptionChain(_weeklyOptionSymbol)
- .Where(contract => !IndexOptionSymbol.IsStandard(contract.Symbol));
- }
-
- private OptionFilterUniverse OptionFilter(OptionFilterUniverse universe)
- {
- // Contracts can be filtered by greeks, implied volatility, open interest:
- return universe
- .Delta(0.5m, 1.5m)
- .Gamma(0.0001m, 0.0006m)
- .Vega(0.01m, 1.5m)
- .Theta(-2.0m, -0.5m)
- .Rho(0.5m, 3.0m)
- .ImpliedVolatility(1.0m, 3.0m)
- .OpenInterest(100, 500);
- }
-}
- - The Index resolution must be less than or equal to the Index Option resolution. For example, if you set the Index resolution to minute, then you must set the Index Option resolution to minute, hour, or daily. -
-- For more information about creating US Index Option subscriptions, see - - Index Options - - . -
- - - -- For information about accessing US Equity Options data, see - - Handling Data - - . -
- - - -- You can get historical US Index Options data in an algorithm and the Research Environment. -
-
- To get historical US Index Options Universe data in an algorithm, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical Index Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter. If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.standard_option_symbol, timedelta(3)) - -# OptionUniverse objects -history = self.history[OptionUniverse](self.standard_option_symbol, timedelta(3))-
// OptionUniverse objects -var history = History<OptionUniverse>(_standardOptionSymbol, TimeSpan.FromDays(3)).ToList();-
- For more information about Index Options Universe data in algorithms, see - - Historical Data - - . -
-
- To get historical US Index Options Universe data in the Research Environment, call the
-
- History<OptionUniverse>
-
-
- history
-
- method with the canonical Option
-
- Symbol
-
- . This method returns data on all of the tradable contracts, not just the contracts that pass your universe filter.
-
qb = QuantBook()
-index_symbol = qb.add_index('VIX').symbol
-option = qb.add_index_option(index_symbol) # or qb.add_index_option(index_symbol, "VIXW")
-history = qb.history(option.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5))
- var qb = new QuantBook();
-var indexSymbol = qb.AddIndex("VIX").Symbol;
-var option = qb.AddIndexOption(indexSymbol); // or qb.AddIndexOption(indexSymbol, "VIXW");
-var history = qb.History<OptionUniverse>(option.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 6));
-foreach (var chain in history)
-{
- var endTime = chain.EndTime;
- var filteredContracts = chain.Data
- .Select(contract => contract as OptionUniverse)
- .Where(contract => contract.Greeks.Delta > 0.3m);
- foreach (var contract in filteredContracts)
- {
- var price = contract.Price;
- var iv = contract.ImpliedVolatility;
- }
-}
- - For more information about historical Index Options Universe data in the Research Environment, see - - Universes - - . -
- - - -- The following table shows the available Index Options: -
-| - Underlying Index - | -- Underlying Ticker - | -- Target Ticker - | -- Standard Contracts - | -- Weekly Contracts - | -- Tradable on Expiry Day - | -
|---|---|---|---|---|---|
| - NASDAQ-100 - | -- NDX - | -- | -
- |
- - | -- | -
| - NASDAQ-100 - | -- NDX - | -- NDXP - | -
- |
- - | -
- |
-
| - NASDAQ-100 - | -- NDX - | -- NQX - | -
- |
-
- |
-
- |
-
| - Russell 2000 - | -- RUT - | -- | -
- |
- - | -- | -
| - Russell 2000 - | -- RUT - | -- RUTW - | -- | -
- |
-
- |
-
| - S&P500 - | -- SPX - | -- | -
- |
- - | -- | -
| - S&P500 - | -- SPX - | -- SPXW - | -- | -
- |
-
- |
-
| - S&P500 - | -- VIX - | -- | -
- |
- - | -- | -
| - S&P500 - | -- VIX - | -- VIXW - | -- | -
- |
- - | -
- For more information about each underlying Index, see - - Supported Indices - - . -
- - - -- The US Index Options Universe dataset enables you to accurately design strategies for Index Options. Examples include the following strategies: -
-- The following example algorithm subscribes to SPX put options that fall within delta range between -1 and -0.95, open interest range between 10 and 1000, and expire within seven days. Within this Option chain, the algorithm holds the put Option contract that has the minimum delta (closest to -1) during market hour to hedge the underlying intra-day movement completely. It avoid volatility from sentiment and only earns from inter-day movement from longer-term factors. When the contract expires, the algorithm rolls over to the next contract that meets this criteria. -
-from AlgorithmImports import *
-
-class IndexOptionsUniverseAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(10000000)
-
- # Asynchronous can use computational resources efficiently
- self.universe_settings.asynchronous = True
- # Subscribe to the underlying for the underlying position
- # Set the data normalization mode to raw for strike price comparability
- self.index = self.add_index("SPX").symbol
- # Requesting option data and filter for the hedge candidates
- option = self.add_index_option(self.index)
- option.set_filter(self.option_filter)
- self.option_symbol = option.symbol
-
- # Set scheduled event to buy a hedge option contract at market open to eliminate the intra-day movement
- self.schedule.on(
- self.date_rules.every_day(self.index),
- self.time_rules.after_market_open(self.index, 1),
- self.buy_hedge_contract
- )
-
- # Set a scheduled event to sell the hedge contract before market close, since we want to earn from inter-day movement
- # Leave 2 minutes contingency to fill
- self.schedule.on(
- self.date_rules.every_day(self.index),
- self.time_rules.before_market_close(self.index, 2),
- self.sell_hedge_contract
- )
-
- self.hedge = None
-
- def option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Select the contracts with delta very close to -1 and high open interest
- # This can effectively hedge most of the price change of the underlying and ensure the liquidity
- # Make sure the contract is expiring close for its tradbility
- return universe.puts_only().expiration(2, 7).delta(-1, -0.95).open_interest(10, 1000)
-
- def buy_hedge_contract(self) -> None:
- chain = self.current_slice.option_chains.get(self.option_symbol)
- if chain:
- # Order the underlying if not hold, the order size should match the option contract
- # Order only if option chain data ready for hedging
- if not self.portfolio[self.index].invested:
- self.market_order(self.index, self.securities[self.option_symbol].symbol_properties.contract_multiplier)
-
- # Get the contract with delta closest to -1 (lowest possible delta)
- contract = sorted(chain, key=lambda x: x.greeks.delta)[0]
- self.hedge = contract.symbol
- # Buy 1 deep ITM put with delta close to -1 to eliminate the intraday movement
- self.market_order(self.hedge, 1)
-
- def sell_hedge_contract(self) -> None:
- # Check if any hedge contract position, if so, liquidate before market close to expose to underlying overnight movement
- if self.hedge:
- self.liquidate(self.hedge)
- self.hedge = None
- public class IndexOptionsUniverseAlgorithm : QCAlgorithm
-{
- private Symbol _index, _optionSymbol, _hedge;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(10000000);
- // Asynchronous can use computational resources efficiently
- UniverseSettings.Asynchronous = true;
-
- // Subscribe to the underlying for the underlying position
- // Set the data normalization mode to raw for strike price comparability
- _index = AddIndex("SPX").Symbol;
- // Requesting option data and filter for the hedge candidates
- var option = AddIndexOption(_index);
- _optionSymbol = option.Symbol;
- option.SetFilter(OptionFilter);
-
- // Set scheduled event to buy a hedge option contract at market open to eliminate the intra-day movement
- Schedule.On(
- DateRules.EveryDay(_index),
- TimeRules.AfterMarketOpen(_index, 1),
- BuyHedgeContract
- );
-
- // Set a scheduled event to sell the hedge contract before market close, since we want to earn from inter-day movement
- // Leave 2 minutes contingency to fill
- Schedule.On(
- DateRules.EveryDay(_index),
- TimeRules.BeforeMarketClose(_index, 2),
- SellHedgeContract
- );
- }
-
- private OptionFilterUniverse OptionFilter(OptionFilterUniverse universe)
- {
- // Select the contracts with delta very close to -1 and high open interest
- // This can effectively hedge most of the price change of the underlying and ensure the liquidity
- // Make sure the contract is expiring close for its tradbility
- return universe
- .PutsOnly()
- .Expiration(2, 7)
- .Delta(-1m, -0.95m)
- .OpenInterest(10, 1000);
- }
-
- private void BuyHedgeContract()
- {
- if (CurrentSlice.OptionChains.TryGetValue(_optionSymbol, out var chain))
- {
- // Order the underlying if not hold, the order size should match the option contract
- // Order only if option chain data ready for hedging
- if (!Portfolio[_index].Invested)
- {
- MarketOrder(_index, Securities[_optionSymbol].SymbolProperties.ContractMultiplier);
- }
-
- // Get the contract with delta closest to -1 (lowest possible delta)
- var contract = chain.MinBy(x => x.Greeks.Delta);
- _hedge = contract.Symbol;
- // Buy 1 deep ITM put with delta close to -1 to eliminate the intraday movement
- MarketOrder(_hedge, 1);
- }
- }
-
- private void SellHedgeContract()
- {
- // Check if any hedge contract position, if so, liquidate before market close to expose to underlying overnight movement
- if (_hedge != null)
- {
- Liquidate(_hedge);
- _hedge = null;
- }
- }
-}
- - The following example algorithm demonstrating a Gamma Scalping strategy through framework algorithm. It filters SPX options with expiration between 30 to 90 days and open interest between 50 and 1000, due to liquidity concern and lower Gamma fluctuation. Assuming a significant upward trend is expecting, it orders a long straddle strategy from the strike price with Delta-neutral and the highest Gamma to earn the highest profit from upward underlying movement. -
-from AlgorithmImports import *
-
-class IndexOptionsUniverseFrameworkAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 12, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000000)
- # Asynchronous can use computational resources efficiently
- self.universe_settings.asynchronous = True
-
- # Universe selection that select based on liquidity of the option contracts (by open interest)
- self.add_universe_selection(IndexOptionsUniverseSelectionModel())
- # Custom alpha model that use Delta and Gamma to signal insights
- self.add_alpha(OptionDeltaGammaAlphaModel())
- # To maintain long-short size equal, use a PCM that order a single contract
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-class IndexOptionsUniverseSelectionModel(OptionUniverseSelectionModel):
- def __init__(self) -> None:
- # Daily update with the select_option_chain_symbols function
- super().__init__(timedelta(1), self.select_option_chain_symbols)
-
- def select_option_chain_symbols(self, dt: datetime) -> List[Symbol]:
- # Select only SPX options as our focus, which is a highly traded volatile index with great upward momentum
- return [Symbol.create("SPX", SecurityType.INDEX_OPTION, Market.USA)]
-
- def filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # To ensure the liquidity and tradability, make sure the option is not 0-DTE and have a fair open interest
- # A longer TTM will have lower Gamma thus more stable in the local delta-neutral position
- return universe.expiration(30, 90).open_interest(50, 1000)
-
-class OptionDeltaGammaAlphaModel(AlphaModel):
- def __init__(self) -> None:
- # A day count variable to control the alpha model only trade once a day
- self._day = -1
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
-
- if self._day != slice.time.day:
- # We open position for each option underlying as separate bet
- for _, chain in slice.option_chains.items():
- # For theta-neutral, select the same expiry for both call and put
- expiry = min(x.expiry for x in chain)
- contracts = [x for x in chain if x.expiry == expiry]
-
- # Calculate delta and gamma per strike price group for later filtering, ensure both call and put available for option strategy
- delta_gamma_symbols = []
- strikes = set(x.strike for x in contracts if len([y for y in contracts if y.strike == x.strike]) == 2)
- for strike in strikes:
- # Get both call and put for their aggregated delta and gamma
- call = next(filter(lambda x: x.right == OptionRight.CALL and x.strike == strike, contracts))
- put = next(filter(lambda x: x.right == OptionRight.PUT and x.strike == strike, contracts))
- delta_gamma_symbols.append((call.greeks.delta + put.greeks.delta, call.greeks.gamma + put.greeks.gamma, call.symbol, put.symbol))
-
- if len(delta_gamma_symbols) == 0:
- continue
-
- # We want a delta-neutral position, so it is likely to be ATM (like a long straddle)
- # Less than 2d.p. difference is non-significant, which we can risk for better reward
- # Assuming the market direction is up in most scenario, we try to get the strike providing max overall Gamma
- # Make sure the aggregated gamma to be positive to bet on large uptrend
- # So it will earn more when the price really go up higher and higher, but locally immune for small noise
- filtered = [item for item in delta_gamma_symbols if round(item[0], 2) <= 0.01 and item[1] > 0]
- if len(filtered) == 0:
- continue
- selected = sorted(filtered, key=lambda x: x[1])[0]
-
- # Provide trade signal and roll the day count to let the position stay for the whole day
- selected_call = selected[2]
- selected_put = selected[3]
- insights.extend([
- Insight.price(selected_call, Expiry.END_OF_DAY, InsightDirection.UP),
- Insight.price(selected_put, Expiry.END_OF_DAY, InsightDirection.UP)
- ])
- self._day = slice.time.day
-
- return insights
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- # Use a whole number target to order the exact number of share for size-matching
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class IndexOptionsUniverseFrameworkAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 12, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
- // Asynchronous can use computational resources efficiently
- UniverseSettings.Asynchronous = true;
-
- // Universe selection that select based on liquidity of the option contracts (by open interest)
- AddUniverseSelection(new IndexOptionsUniverseSelectionModel());
- // Custom alpha model that use Delta and Gamma to signal insights
- AddAlpha(new OptionDeltaGammaAlphaModel());
- // To maintain long-short size equal, use a PCM that order a single contract
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-class IndexOptionsUniverseSelectionModel : OptionUniverseSelectionModel
-{
- // Daily update with the SelectOptionChainSymbols function
- public IndexOptionsUniverseSelectionModel()
- : base(TimeSpan.FromDays(1), SelectOptionChainSymbols) {}
-
- private static IEnumerable<Symbol> SelectOptionChainSymbols(DateTime utcTime)
- {
- // Select only SPX options as our focus, which is a highly traded volatile index with great upward momentum
- return new[] {QuantConnect.Symbol.Create("SPX", SecurityType.IndexOption, Market.USA)};
- }
-
- protected override OptionFilterUniverse Filter(OptionFilterUniverse filter)
- {
- // To ensure the liquidity and tradability, make sure the option is not 0-DTE and have a fair open interest
- // A longer TTM will have lower Gamma thus more stable in the local delta-neutral position
- return filter
- .Expiration(30, 90)
- .OpenInterest(50, 1000);
- }
-}
-
-class OptionDeltaGammaAlphaModel : AlphaModel
-{
- // A day count variable to control the alpha model only trade once a day
- private int _day = -1;
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- if (_day != slice.Time.Day)
- {
- // We open position for each option underlying as separate bet
- foreach (var kvp in slice.OptionChains)
- {
- var chain = kvp.Value;
-
- // For theta-neutral, select the same expiry for both call and put
- var expiry = chain.Min(x => x.Expiry);
- var contracts = chain.Where(x => x.Expiry == expiry).ToList();
-
- // Calculate delta and gamma per strike price group for later filtering, ensure both call and put available for option strategy
- var deltaGammaSymbols = new List<(decimal, decimal, Symbol, Symbol)>();
- var strikes = contracts.Select(x => x.Strike)
- .Where(x => contracts.Count(y => y.Strike == x) == 2)
- .Distinct();
- foreach (var strike in strikes)
- {
- // Get both call and put for their aggregated delta and gamma
- var call = contracts.Single(x => x.Right == OptionRight.Call && x.Strike == strike);
- var put = contracts.Single(x => x.Right == OptionRight.Put && x.Strike == strike);
- deltaGammaSymbols.Add((call.Greeks.Delta + put.Greeks.Delta, call.Greeks.Gamma + put.Greeks.Gamma, call.Symbol, put.Symbol));
- }
-
- if (deltaGammaSymbols.Count == 0)
- {
- continue;
- }
-
- // We want a delta-neutral position, so it is likely to be ATM (like a long straddle)
- // Less than 2d.p. difference is non-significant, which we can risk for better reward
- // Assuming the market direction is up in most scenario, we try to get the strike providing max overall Gamma
- // Make sure the aggregated gamma to be positive to bet on large uptrend
- // So it will earn more when the price really go up higher and higher, but locally immune for small noise
- var filtered = deltaGammaSymbols.Where(item => Math.Round(item.Item1, 2) <= 0.01m && item.Item2 > 0).ToList();
- if (filtered.Count == 0)
- {
- continue;
- }
- var selected = filtered.OrderByDescending(item => item.Item2).First();
-
- // Provide trade signal and roll the day count to let the position stay for the whole day
- var selectedCall = selected.Item3;
- var selectedPut = selected.Item4;
- insights.AddRange(new[] {
- Insight.Price(selectedCall, Expiry.EndOfDay, InsightDirection.Up),
- Insight.Price(selectedPut, Expiry.EndOfDay, InsightDirection.Up)
- });
- _day = slice.Time.Day;
- }
- }
-
- return insights;
- }
-}
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- // Use a whole number target to order the exact number of share for size-matching
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Index Options Universe dataset provides
-
- OptionFilterUniverse
-
- ,
-
- OptionUniverse
-
- , and
-
- OptionChain
-
- objects.
-
-
- OptionFilterUniverse
-
- objects have the following attributes:
-
-
- OptionUniverse
-
- objects have the following attributes:
-
-
- OptionChain
-
- objects have the following attributes:
-
- -
- AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit - - algoseek.com - - . -
-- -
- The US Equities dataset by AlgoSeek is survivorship bias-free daily coverage of every stock traded in the US Securities Information Processors (SIP) CTA/UTP feed since 1998. The dataset covers approximately 27,500 securities, starts in January 1998, and is delivered in any resolution from tick to daily. The Data is collected from the full SIP feed via our Equinix co-located servers, including all trades and quotes published to every exchange as well as FINRA. Over-the-Counter (OTC) trades are not included. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- For more information about the US Equities dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit - - algoseek.com - - . -
- - - -- AlgoSeek is the default US Equities dataset on QuantConnect. The following snippet demonstrates how to request data from the US Equities dataset: -
-self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
- _aapl = AddEquity("AAPL", Resolution.Daily).Symbol;
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 1998 - | -
| - Asset Coverage - | -- 27,500 US Equities - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Tick, Second, Minute, Hourly, & Daily - | -
| - Timezone - | -- New York - | -
| - Market Hours - | -- - Regular and Extended - - | -
- To add US Equities data to your algorithm, call the
-
- AddEquity
-
-
- add_equity
-
- method. Save a reference to the Equity
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class USEquityDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2018, 1, 1)
- self.set_end_date(2021, 6, 1)
- self.set_cash(100000)
- # Subscribe to AAPL data
- self.aapl = self.add_equity("AAPL", Resolution.MINUTE).symbol
- public class USEquityDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2018, 1, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- // Subscribe to AAPL data
- _symbol = AddEquity("AAPL", Resolution.Minute).Symbol;
- }
-}
- - For more information about creating US Equity subscriptions, see - - Requesting Data - - or - - US Equity Universes - - . -
- - - -
- To get the current US Equities data, index the
-
- Bars
-
-
- bars
-
- ,
-
- QuoteBars
-
-
- quote_bars
-
- , or
-
- Ticks
-
-
- ticks
-
- properties of the current
-
-
- Slice
-
-
- with the Equity
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Access data: TradeBar data
- if self.aapl in slice.bars:
- trade_bar = slice.bars[self.aapl]
- self.log(f"{self.aapl} close at {slice.time}: {trade_bar.close}")
-
- # Access data: QuoteBar data
- if self.aapl in slice.quote_bars:
- quote_bar = slice.quote_bars[self.aapl]
- self.log(f"{self.aapl} bid at {slice.time}: {quote_bar.bid.close}")
-
- # Access data: Ticks data
- if self.aapl in slice.ticks:
- ticks = slice.ticks[self.aapl]
- for tick in ticks:
- self.log(f"{self.aapl} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- // Access data: TradeBar data
- if (slice.Bars.ContainsKey(_symbol))
- {
- var tradeBar = slice.Bars[_symbol];
- Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- // Access data: QuoteBar data
- if (slice.QuoteBars.ContainsKey(_symbol))
- {
- var quoteBar = slice.QuoteBars[_symbol];
- Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- // Access data: Ticks data
- if (slice.Ticks.ContainsKey(_symbol))
- {
- var ticks = slice.Ticks[_symbol];
- foreach (var tick in ticks)
- {
- Log($"{_symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- # Iterate all TradeBar received
- for symbol, trade_bar in slice.bars.items():
- self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
-
- # Iterate all QuoteBar received
- for symbol, quote_bar in slice.quote_bars.items():
- self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- # Iterate all Ticks received
- for symbol, ticks in slice.ticks.items():
- for tick in ticks:
- self.log(f"{symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- // Iterate all TradeBar received
- foreach (var kvp in slice.Bars)
- {
- var symbol = kvp.Key;
- var tradeBar = kvp.Value;
- Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- // Iterate all QuoteBar received
- foreach (var kvp in slice.QuoteBars)
- {
- var symbol = kvp.Key;
- var quoteBar = kvp.Value;
- Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- // Iterate all Ticks received
- foreach (var kvp in slice.Ticks)
- {
- var symbol = kvp.Key;
- var ticks = kvp.Value;
- foreach (var tick in ticks)
- {
- Log($"{symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
- - For more information about accessing US Equities data, see - - Handling Data - - . -
- - - -
- To get historical US Equity data, call the
-
- History
-
-
- history
-
- method with the Equity
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.aapl, 100, Resolution.DAILY) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](self.aapl, 100, Resolution.DAILY) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](self.aapl, 100, Resolution.MINUTE) - -# Tick objects -history_ticks = self.history[Tick](self.aapl, timedelta(seconds=10), Resolution.TICK)-
// TradeBar objects -var historyTradeBars = History(_symbol, 100, Resolution.Daily); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); - -// Tick objects -var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);-
- For more information about historical data, see - - History Requests - - . -
- - - -- To select a universe of US Equities, see - - Equity Universes - - . -
- - - -
- To unsubscribe from a US Equity that you added with the
-
- AddEquity
-
-
- add_equity
-
- method, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.aapl)-
RemoveSecurity(_symbol);-
- The
-
- RemoveSecurity
-
-
- remove_security
-
- method cancels your open orders for the security and liquidates your holdings.
-
- To view the supported assets in the US Equities dataset, see the - - Data Explorer - - . This dataset doesn't include Over-the-Counter (OTC) stocks. -
- - - -- The US Equities dataset enables you to accurately design Equity trading strategies. Examples include the following strategies: -
-- The following example algorithm buys and holds Apple stock: -
-from AlgorithmImports import *
-
-
-class USEquityDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- # Requesting single equity data, since we only trade AAPL
- self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
-
- # Historical data
- history = self.history(self.aapl, 60, Resolution.DAILY)
- self.debug(f"We got {len(history)} items from our history request")
-
- def on_data(self, slice: Slice) -> None:
- # Check if the current slice containing AAPL and if we hold any position
- # As we make use of the most updated price data to decide the order size
- if slice.contains_key(self.aapl) and slice[self.aapl] is not None and not self.portfolio.invested:
- self.set_holdings(self.aapl, 1)
- public class USEquityDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Requesting single equity data, since we only trade AAPL
- _symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
-
- // Historical data
- var history = History(_symbol, 60, Resolution.Daily);
- Debug($"We got {history.Count()} items from our history request");
- }
-
- public override void OnData(Slice slice)
- {
- // Check if the current slice containing AAPL and if we hold any position
- // As we make use of the most updated price data to decide the order size
- if (slice.ContainsKey(_symbol) && slice[_symbol] != null && !Portfolio.Invested)
- {
- SetHoldings(_symbol, 1);
- }
- }
-}
- - The following example algorithm buys and holds Apple stock: -
-from AlgorithmImports import *
-
-
-class USEquityDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
-
- self.universe_settings.resolution = Resolution.DAILY
- # To select only AAPL, use a manual selection universe
- symbols = [Symbol.create("AAPL", SecurityType.EQUITY, Market.USA)]
- self.add_universe_selection(ManualUniverseSelectionModel(symbols))
-
- # Constant investment signal
- self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(days=7), 0.025, None))
-
- # Invest in all members equally
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
- public class USEquityDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- UniverseSettings.Resolution = Resolution.Daily;
- // To select only AAPL, use a manual selection universe
- var symbols = new[] {QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA)};
- AddUniverseSelection(new ManualUniverseSelectionModel(symbols));
-
- // Constant investment signal
- AddAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(7), 0.025, null));
-
- // Invest in all members equally
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- }
-}
-
- The US Equities dataset provides
-
- TradeBar
-
- ,
-
- QuoteBar
-
- , and
-
- Tick
-
- objects.
-
-
- TradeBar
-
- objects have the following attributes:
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- Tick
-
- objects have the following attributes:
-
- -
- The US Equity Options data by AlgoSeek provides Option data, including prices, strikes, expires, and open interest. The data covers 4,000 Symbols, starts in January 2012, and is delivered on a minute frequency. This dataset is created by monitoring Options Price Reporting Authority (OPRA) data feed, which consolidates last sale and quotation information originating from the national securities exchanges that have been approved by the Securities and Exchange Commission. -
-- This dataset depends on the following datasets: -
-- For more information about the US Equity Options dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- - AlgoSeek - - was in 2014 with the goal of providing the highest quality, most accurate, ready-to-use data in the financial data industry. AlgoSeek provides access to Equities, ETFs, ETNs, Equity Indices, Equity Options, Futures, and Future Options for quantitative firms and traders. -
- - - -- The following snippet demonstrates how to request data from the US Equity Options dataset: -
-option = self.add_option("GOOG")
-self.option_symbol = option.symbol
-option.set_filter(-2, +2, 0, 180)
- var option = AddOption("GOOG");
-_optionSymbol = option.Symbol;
-option.SetFilter(-2, +2, 0, 180);
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012* - | -
| - Asset Coverage - | -- 4,000 Symbols - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Minute, Hourly, & Daily - | -
| - Timezone - | -- New York - | -
| - Market Hours - | -- - Regular Only - - | -
- * Some data is available before this date. In 2012, AlgoSeek started to fetch data from 48 OPRA channels instead of 24, increasing the quality of the data. -
- - - -
- To add US Equity Options data to your algorithm, call the
-
- AddOption
-
-
- add_option
-
- method. Save a reference to the Equity Option
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class USEquityOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2020, 6, 1)
- self.set_end_date(2021, 6, 1)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- # Request GOOG option data
- option = self.add_option("GOOG")
- self.option_symbol = option.symbol
- # Set our strike/expiry filter for this option chain
- option.set_filter(-2, +2, 0, 180)
-
- public class USEquityOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _optionSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- // Request GOOG option data
- var option = AddOption("GOOG");
- _optionSymbol = option.Symbol;
- // Set our strike/expiry filter for this option chain
- option.SetFilter(-2, +2, 0, 180);
- }
-}
- - The Equity resolution must be less than or equal to the Equity Option resolution. For example, if you set the Equity resolution to minute, then you must set the Equity Option resolution to minute, hour, or daily. -
-- For more information about creating US Equity Option subscriptions, see - - Requesting Data - - or - - Equity Options Universes - - . -
- - - -
- To get the current US Equity Options data, index the
-
- OptionChains
-
-
- option_chains
-
- property of the current
-
-
- Slice
-
-
- with the canonical Equity Option
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your Index Option at every time step. To avoid issues, call the
-
- Get
-
-
- get
-
- method.
-
def on_data(self, slice: Slice) -> None:
- # Get the wanted option chain with the canonical symbol
- chain = slice.option_chains.get(self.option_symbol)
- if chain:
- # Iterate the option contracts in chain
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
-
- public override void OnData(Slice slice)
-{
- // Get the wanted option chain with the canonical symbol
- if (slice.OptionChains.TryGetValue(_optionSymbol, out var chain))
- {
- // Iterate the option contracts in chain
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
-
- You can also iterate through all of the
-
- OptionChain
-
- objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- # Iterate all option chains of all symbols
- for canonical_symbol, chain in slice.option_chains.items():
- # Iterate the option contracts in chain
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
-
- public override void OnData(Slice slice)
-{
- // Iterate all option chains of all symbols
- foreach (var kvp in slice.OptionChains)
- {
- var canonicalSymbol = kvp.Key;
- var chain = kvp.Value;
- // Iterate the option contracts in chain
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
- - For more information about accessing US Equity Options data, see - - Handling Data - - . -
- - - -- You can get historical US Equity Options data in an algorithm and the Research Environment. -
-
- To get historical US Equity Options data in an algorithm, call the
-
- History
-
-
- history
-
- method with the Equity Option contract
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame of trade and quote data -history_df = self.history(contract.symbol, 100, Resolution.MINUTE) - -# DataFrame of open interest data -history_oi_df = self.history(OpenInterest, contract.symbol, 100, Resolution.MINUTE) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE) - -# OpenInterest objects -history_oi = self.history[OpenInterest](contract.symbol, 100, Resolution.MINUTE)-
// TradeBar objects -var historyTradeBars = History(contract.Symbol, 100, Resolution.Minute); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(contract.Symbol, 100, Resolution.Minute); - -// OpenInterest objects -var historyOpenInterest = History<OpenInterest>(contract.Symbol, 100, Resolution.Minute);-
- For more information about historical data in algorithms, see - - History Requests - - . -
-
- To get historical US Equity Options data in the Research Environment, call the
-
- History
-
-
- history
-
- or
-
- OptionHistory
-
-
- option_history
-
- method. The
-
- History
-
-
- history
-
- method returns the price, volume, and open interest history for some given Option contract(s). The
-
- OptionHistory
-
-
- option_history
-
- method returns the price and volume history for the contracts that pass your daily universe filter.
-
qb = QuantBook()
-option = qb.add_option("GOOG")
-option.set_filter(-2, 2, 0, 90)
-history = qb.option_history(option.symbol.underlying, datetime(2020, 6, 1), datetime(2020, 6, 5))
-history_df = history.data_frame
-expiries = history.get_expiry_dates()
-strikes = history.get_strikes()
- var qb = new QuantBook();
-var option = qb.AddOption("GOOG");
-option.SetFilter(-2, 2, 0, 90);
-var history = qb.OptionHistory(option.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 5));
-
-var contracts = history
- .SelectMany(x => x.OptionChains.SelectMany(y => y.Value.Contracts.Keys))
- .Distinct().ToList();
-var expiries = contracts.Select(x => x.ID.Date).Distinct().ToList();
-var strikes = contracts.Select(x => x.ID.StrikePrice).Distinct().ToList();
-
- To get historical data for arbitrary US Equity Option contracts instead of just the that pass your universe filter, call the
-
- History
-
-
- history
-
- method like you would in an algorithm, but on the
-
- QuantBook
-
- object. For more information about historical data in the Research Environment, see
-
- Key Concepts
-
- .
-
- To get historical data for the Greeks and implied volatility of Equity Options, see the - - US Equity Option Universe - - dataset. -
- - - -- To view the supported assets in the US Equity Options dataset, see the - - Data Explorer - - . -
- - - -- The US Equity Options dataset enables you to accurately design Option strategies. Examples include the following strategies: -
-- The following example algorithm subscribes to Google Options that fall within two strikes of the underlying stock price and expire within seven days. Within this Option chain, the algorithm buys the call Option contract that has the furthest expiry and has its strike price closest to the underlying stock price. When the contract expires, the algorithm rolls over to the next contract that meets this criteria. -
-from AlgorithmImports import *
-
-class USEquityOptionsDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- # Requesting data
- self.underlying = self.add_equity("GOOG").symbol
- option = self.add_option("GOOG")
- self.option_symbol = option.symbol
- # To speculate trade the underlying with a low cost, filter for the ATM calls that expiring in the current week
- # -2/+2 strike buffer is given for small price change
- option.set_filter(lambda u: u.calls_only().strikes(-2, +2).expiration(0, 6))
-
- self.contract = None
-
- def on_data(self, slice: Slice) -> None:
- # If the Option contract is exercised, close the underlying position.
- if self.portfolio[self.underlying].invested:
- self.liquidate(self.underlying)
- # If the Option contract expires, rollover to the next contract.
- if self.contract and not self.portfolio[self.contract.symbol].invested:
- self.contract = None
- # Select with the lastest option chain data only
- chain = slice.option_chains.get(self.option_symbol)
- if not self.contract and chain:
- # Select the call contracts with the furthest expiration (week end)
- furthest_expiry = max([c.expiry for c in chain])
- furthest_expiry_calls = [contract for contract in chain if contract.expiry == furthest_expiry]
- # Get the ATM call for speculate trade with low cost and limited loss
- self.contract = sorted(furthest_expiry_calls, key = lambda x: abs(chain.underlying.price - x.strike))[0]
- self.market_order(self.contract.symbol, 1)
-
- def on_securities_changed(self, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- # Historical data
- history = self.history(security.symbol, 10, Resolution.MINUTE)
- self.debug(f"We got {len(history)} from our history request for {security.symbol}")
- public class USEquityOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _underlying, _optionSymbol;
- private OptionContract? _contract = null;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- // Requesting data
- _underlying = AddEquity("GOOG").Symbol;
- var option = AddOption("GOOG");
- _optionSymbol = option.Symbol;
- // To speculate trade the underlying with a low cost, filter for the ATM calls that expiring in the current week
- // -2/+2 strike buffer is given for small price change
- option.SetFilter((u) => u.CallsOnly().Strikes(-2, +2).Expiration(0, 7));
- }
-
- public override void OnData(Slice slice)
- {
- // If the Option contract is exercised, close the underlying position.
- if (Portfolio[_underlying].Invested)
- {
- Liquidate(_underlying);
- }
- // If the Option contract expires, rollover to the next contract.
- if (_contract != null && !Portfolio[_contract.Symbol].Invested)
- {
- _contract = null;
- }
- // Select with the lastest option chain data only
- if (_contract == null && slice.OptionChains.TryGetValue(_optionSymbol, out var chain))
- {
- // Select the call contracts with the furthest expiration (week end)
- var furthestExpiry = chain.Max(c => c.Expiry);
- var furthestExpiryCalls = chain.Where(c => c.Expiry == furthestExpiry);
- // Get the ATM call for speculate trade with low cost and limited loss
- _contract = furthestExpiryCalls.OrderByDescending(x => Math.Abs(chain.Underlying.Price - x.Strike)).Last();
- MarketOrder(_contract.Symbol, 1);
- }
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- // Historical data
- var history = History(security.Symbol, 100, Resolution.Minute);
- Debug($"We got {history.Count()} from our history request for {security.Symbol}");
- }
- }
-}
- - The following example algorithm buys a call Option contract for Google that falls within one strike of the underlying stock price and expires within seven days. When the contract expires, the algorithm rolls over to the next contract that meets this criteria. -
-from AlgorithmImports import *
-
-class USEquityOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- # Requesting data
- self.set_universe_selection(EarliestExpiringWeeklyAtTheMoneyCallOptionUniverseSelectionModel())
-
- self.set_alpha(ConstantOptionsAlphaModel())
-
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-
-class EarliestExpiringWeeklyAtTheMoneyCallOptionUniverseSelectionModel(OptionUniverseSelectionModel):
-
- def __init__(self) -> None:
- # Daily update with the select_option_chain_symbols function
- super().__init__(timedelta(1), self.select_option_chain_symbols)
-
- def select_option_chain_symbols(self, utcTime: datetime) -> List[Symbol]:
- # Always select only GOOG options as our focus
- return [ Symbol.create("GOOG", SecurityType.OPTION, Market.USA) ]
-
- def filter(self, filter: OptionFilterUniverse) -> OptionFilterUniverse:
- # To speculate trade the underlying with a low cost, filter for the ATM calls that expiring in the current week
- # -1/+1 strike buffer is given for small price change
- return (filter.calls_only()
- .strikes(-1, -1)
- .expiration(0, 7))
-
-
-class ConstantOptionsAlphaModel(AlphaModel):
-
- underlying = None
- contract = None
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
-
- insights = []
-
- # Liquidate the underlying if the option is being exercised/assigned
- if algorithm.portfolio[self.underlying].invested:
- insights.append(Insight.price(self.underlying, timedelta(days=7), InsightDirection.FLAT))
-
- if self.contract is not None and algorithm.portfolio[self.contract.symbol].invested:
- return insights
-
- # Get the ATM call for speculate trade with low cost and limited loss that expires at week end
- for kvp in slice.option_chains:
- chain = kvp.Value
- expiry = max(x.expiry for x in chain)
- self.contract = sorted([x for x in chain if x.expiry == expiry],
- key=lambda x: abs(x.strike - x.underlying_last_price))[0]
- insights.append(Insight.price(self.contract.symbol, self.contract.expiry + timedelta(days=1), InsightDirection.UP))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- if security.type == SecurityType.EQUITY:
- self.underlying = security.symbol
- else:
- # Historical data
- history = algorithm.history(security.symbol, 10, Resolution.MINUTE)
- algorithm.debug(f"We got {len(history)} from our history request for {security.symbol}")
-
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
-
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class USEquityOptionsDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- // Requesting data
- SetUniverseSelection(new EarliestExpiringWeeklyAtTheMoneyCallOptionUniverseSelectionModel());
-
- SetAlpha(new ConstantOptionsAlphaModel());
-
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-class EarliestExpiringWeeklyAtTheMoneyCallOptionUniverseSelectionModel : OptionUniverseSelectionModel
-{
- // Daily update with the SelectOptionChainSymbols function
- public EarliestExpiringWeeklyAtTheMoneyCallOptionUniverseSelectionModel()
- : base(TimeSpan.FromDays(1), SelectOptionChainSymbols) {}
-
- private static IEnumerable<Symbol> SelectOptionChainSymbols(DateTime utcTime)
- {
- // Select only GOOG options as our focus
- return new[] {QuantConnect.Symbol.Create("GOOG", SecurityType.Option, Market.USA)};
- }
-
- protected override OptionFilterUniverse Filter(OptionFilterUniverse filter)
- {
- // To speculate trade the underlying with a low cost, filter for the ATM calls that expiring in the current week
- // -2/+2 strike buffer is given for small price change
- return filter.CallsOnly()
- .Strikes(-1, -1)
- .Expiration(0, 7);
- }
-}
-
-class ConstantOptionsAlphaModel : AlphaModel
-{
- private Symbol? _underlying = null;
- private OptionContract? _contract = null;
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- // Liquidate the underlying if the option is being exercised/assigned
- if (algorithm.Portfolio[_underlying].Invested)
- {
- insights.Add(Insight.Price(_underlying, TimeSpan.FromDays(7), InsightDirection.Flat));
- }
-
- if (_contract != null && algorithm.Portfolio[_contract.Symbol].Invested)
- {
- return insights;
- }
-
- // Get the ATM call for speculate trade with low cost and limited loss that expires at week end
- foreach (var kvp in slice.OptionChains)
- {
- var chain = kvp.Value;
- var expiry = chain.Max(x => x.Expiry);
- _contract = chain.Where(x => x.Expiry == expiry)
- .OrderBy(x => Math.Abs(x.Strike - x.UnderlyingLastPrice))
- .First();
- insights.Add(Insight.Price(_contract.Symbol, _contract.Expiry + TimeSpan.FromDays(1), InsightDirection.Up));
- }
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- if (security.Type == SecurityType.Equity)
- {
- _underlying = security.Symbol;
- }
- else {
- // Historical data
- var history = algorithm.History(security.Symbol, 100, Resolution.Minute);
- algorithm.Debug($"We got {history.Count()} from our history request for {security.Symbol}");
- }
- }
- }
-}
-
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Equity Options dataset provides
-
- TradeBar
-
- ,
-
- QuoteBar
-
- , and
-
- OpenInterest
-
- objects.
-
-
- TradeBar
-
- objects have the following attributes:
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- OpenInterest
-
- objects have the following attributes:
-
- -
- The US Future Options dataset by AlgoSeek provides Option data on US Future contracts, including prices, strikes, and expires. The data covers 15 Monthly Future contracts, starts in January 2012, and is delivered on a minute frequency. This dataset is created by monitoring the trading activity on the CME, CBOT, NYMEX, and COMEX markets. -
-- This dataset depends on the following datasets: -
-- For more information about the US Future Options dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering equities, futures, options, cash forex, and cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit - - algoseek.com - - . -
- - - -- The following snippet demonstrates how to request data from the US Future Options dataset: -
-future = self.add_future(Futures.Metals.GOLD, Resolution.MINUTE) -future.set_filter(0, 90) -self.add_future_option(future.symbol, lambda universe: universe.strikes(-5, +5))-
var future = AddFuture(Futures.Metals.Gold, Resolution.Minute); -future.SetFilter(0, 90); -AddFutureOption(future.Symbol, universe => universe.Strikes(-5, +5));-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012 - | -
| - Asset Coverage - | -- 15 Monthly Future Contracts. Standard expires only*. - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Minute, Hourly, & Daily - | -
| - Timezone - | -- New York - | -
| - Market Hours - | -- - Regular and Extended - - | -
- To add US Future Options data to your algorithm, call the
-
- AddFutureOption
-
-
- add_future_option
-
- method.
-
class FutureOptionDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2020, 1, 28) - self.set_end_date(2020, 6, 1) - self.set_cash(100000) - self.universe_settings.asynchronous = True - future = self.add_future(Futures.Metals.GOLD, Resolution.MINUTE) - future.set_filter(0, 90) - self.add_future_option(future.symbol, lambda universe: universe.strikes(-5, +5))-
public class FutureOptionDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2020, 1, 28);
- SetEndDate(2020, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- var future = AddFuture(Futures.Metals.Gold, Resolution.Minute);
- future.SetFilter(0, 90);
- AddFutureOption(future.Symbol, universe => universe.Strikes(-5, +5));
- }
-}
- - The Future resolution must be less than or equal to the Future Option resolution. For example, if you set the Future resolution to minute, then the Future Option resolution must be minute, hour, or daily. -
-- For more information about creating Future Options subscriptions, see - - Requesting Data - - or - - Future Options Universes - - . -
- - - -
- To get the current Future Options data, iterate through the
-
- OptionChains
-
-
- option_chains
-
- property of the current
-
-
- Slice
-
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your Future Options at every time step.
-
def on_data(self, slice: Slice) -> None:
- for canonical_fop_symbol, chain in slice.option_chains.items():
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.OptionChains)
- {
- var canonicalFOPSymbol = kvp.Key;
- var chain = kvp.Value;
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
-
- You can also iterate through the
-
- FuturesChains
-
-
- futures_chains
-
- in the current
-
- Slice
-
- first.
-
def on_data(self, slice: Slice) -> None:
- for continuous_future_symbol, futures_chain in slice.futures_chains.items():
- # Select a Future Contract and create its canonical FOP Symbol
- futures_contract = [contract for contract in futures_chain][0]
- canonical_fop_symbol = Symbol.create_canonical_option(futures_contract.symbol)
- option_chain = slice.option_chains.get(canonical_fop_symbol)
- if option_chain:
- for fop_contract in option_chain:
- self.log(f"{fop_contract.symbol} price at {slice.time}: {fop_contract.last_price}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.FuturesChains)
- {
- var continuousContractSymbol = kvp.Key;
- var futuresChain = kvp.Value;
-
- // Select a Future Contract and create its canonical FOP Symbol
- var futuresContract = futuresChain.First();
- var canonicalFOPSymbol = QuantConnect.Symbol.CreateCanonicalOption(futuresContract.Symbol);
- if (slice.OptionChains.TryGetValue(canonicalFOPSymbol, out var optionChain))
- {
- foreach (var fopContract in optionChain)
- {
- Log($"{fopContract.Symbol} price at {slice.Time}: {fopContract.LastPrice}");
- }
- }
- }
-}
- - For more information about accessing Future Options data, see - - Handling Data - - . -
- - - -- You can get historical US Future Options data in an algorithm and the Research Environment. -
-
- To get historical US Future Options data in an algorithm, call the
-
- History
-
-
- history
-
- method with the Future Option contract
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame of trade and quote data -history_df = self.history(contract.symbol, 100, Resolution.MINUTE) - -# DataFrame of open interest data -history_oi_df = self.history(OpenInterest, contract.symbol, 100, Resolution.MINUTE) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE) - -# OpenInterest objects -history_oi = self.history[OpenInterest](contract.symbol, 100, Resolution.MINUTE) --
// TradeBar objects -var historyTradeBars = History(contract.Symbol, 100, Resolution.Minute); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(contract.Symbol, 100, Resolution.Minute); - -// OpenInterest objects -var historyOpenInterest = History<OpenInterest >(contract.Symbol, 100, Resolution.Minute);-
- For more information about historical data in algorithms, see - - History Requests - - . -
-
- To get historical US Future Options data in the Research Environment, call the
-
- History
-
-
- history
-
- or
-
- OptionHistory
-
-
- option_history
-
- method. The
-
- History
-
-
- history
-
- method returns the price, volume, and open interest history for some given Future Option contract(s). The
-
- OptionHistory
-
-
- option_history
-
- method returns the price and volume history for the contracts that pass your daily universe filter.
-
qb = QuantBook() -future = qb.add_future(Futures.Indices.SP_500_E_MINI) -start_date = datetime(2024, 1, 2) -future_contract_symbol = sorted( - qb.future_chain_provider.get_future_contract_list(future.symbol, start_date), - key=lambda s: s.id.date -)[0] -history = qb.option_history( - future_contract_symbol, start_date, future_contract_symbol.id.date, Resolution.HOUR -) -history_df = history.data_frame -expiries = history.get_expiry_dates() -strikes = history.get_strikes()-
var qb = new QuantBook(); -var future = qb.AddFuture(Futures.Indices.SP500EMini); -var startDate = new DateTime(2024, 1, 2); -var futureContractSymbol = qb.FutureChainProvider.GetFutureContractList(future.Symbol, startDate) - .OrderBy(x => x.ID.Date) - .First(); -var history = qb.OptionHistory( - futureContractSymbol, startDate, futureContractSymbol.ID.Date, Resolution.Hour -); - -var contracts = history - .SelectMany(x => x.OptionChains.SelectMany(y => y.Value.Contracts.Keys)) - .Distinct().ToList(); -var expiries = contracts.Select(x => x.ID.Date).Distinct().ToList(); -var strikes = contracts.Select(x => x.ID.StrikePrice).Distinct().ToList();-
- To get historical data for arbitrary US Equity Option contracts instead of just the that pass your universe filter, call the
-
- History
-
-
- history
-
- method like you would in an algorithm, but on the
-
- QuantBook
-
- object. For more information about historical data in the Research Environment, see
-
- Key Concepts
-
- .
-
- The following list shows the available (15) Futures Options: -
-
- Futures.Energy.CrudeOilWTI
-
-
- Futures.Energy.CRUDE_OIL_WTI
-
- : Crude Oil WTI Futures (NYMEX: LO | Underlying: CL)
-
- Futures.Energy.Gasoline
-
-
- Futures.Energy.GASOLINE
-
- : Gasoline RBOB Futures (NYMEX: OB | Underlying: RB)
-
- Futures.Energy.HeatingOil
-
-
- Futures.Energy.HEATING_OIL
-
- : Heating Oil Futures (NYMEX: OH | Underlying: HO)
-
- Futures.Energy.NaturalGas
-
-
- Futures.Energy.NATURAL_GAS
-
- : Natural Gas Futures (NYMEX: ON | Underlying: NG)
-
- Futures.Financials.Y10TreasuryNote
-
-
- Futures.Financials.Y_10_TREASURY_NOTE
-
- : 10Y U.S. Treasury Note Futures (CBOT: OZN | Underlying: ZN)
-
- Futures.Financials.Y2TreasuryNote
-
-
- Futures.Financials.Y_2_TREASURY_NOTE
-
- : 2Y U.S. Treasury Note Futures (CBOT: OZT | Underlying: ZT)
-
- Futures.Financials.Y30TreasuryBond
-
-
- Futures.Financials.Y_30_TREASURY_BOND
-
- : 30Y U.S. Treasury Bond Futures (CBOT: OZB | Underlying: ZB)
-
- Futures.Grains.Corn
-
-
- Futures.Grains.CORN
-
- : Corn Futures (CBOT: OZC | Underlying: ZC)
-
- Futures.Grains.Soybeans
-
-
- Futures.Grains.SOYBEANS
-
- : Soybeans Futures (CBOT: OZS | Underlying: ZS)
-
- Futures.Grains.Wheat
-
-
- Futures.Grains.WHEAT
-
- : Default wheat contract is SRWWheat (CBOT: OZW | Underlying: ZW)
-
- Futures.Indices.NASDAQ100EMini
-
-
- Futures.Indices.NASDAQ_100_E_MINI
-
- : E-mini NASDAQ 100 Futures (CME: NQ)
-
- Futures.Indices.SP500EMini
-
-
- Futures.Indices.SP_500_E_MINI
-
- : E-mini S&P 500 Futures (CME: ES)
-
- Futures.Metals.Copper
-
-
- Futures.Metals.COPPER
-
- : Copper Futures (COMEX: HXE | Underlying: HG)
-
- Futures.Metals.Gold
-
-
- Futures.Metals.GOLD
-
- : Gold Futures (COMEX: OG | Underlying: GC)
-
- Futures.Metals.Silver
-
-
- Futures.Metals.SILVER
-
- : Silver Futures (COMEX: SO | Underlying: SI)
- - The US Future Options dataset enables you to accurately design Future Option strategies. Examples include the following strategies: -
-
- The following example demonstrates a weekly-renewing
-
- covered call
-
- strategy to collect credit of selling the option. It filters the ATM call contract that expires within the current week at week start using
-
- SetFilter
-
- filtering function.
-
from AlgorithmImports import * - -class FutureOptionExampleAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - self.set_cash(5_000_000) - # Subscribe the underlying since the updated price is needed for filtering - self.underlying = self.add_future(Futures.Indices.SP_500_E_MINI, - extended_market_hours=True, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, - contract_depth_offset=0) - # Filter the underlying continuous Futures to narrow the FOP spectrum - self.underlying.set_filter(0, 182) - # Filter for the current-week-expiring calls to formulate a covered call that expires at the end of week - self.add_future_option(self.underlying.symbol, lambda u: u.calls_only().expiration(0, 5)) - - def on_data(self, slice: Slice) -> None: - # Create canonical symbol for the mapped future contract, since option chains are mapped by canonical symbol - symbol = Symbol.create_canonical_option(self.underlying.mapped) - - # Get option chain data for the mapped future, as both the underlying and FOP have the highest liquidity among all other contracts - chain = slice.option_chains.get(symbol) - if not self.portfolio.invested and chain: - # Obtain the ATM call that expires at the end of week, such that both underlying and the FOP expires the same time - expiry = max(x.expiry for x in chain) - atm_call = sorted([x for x in chain if x.expiry == expiry], - key=lambda x: abs(x.strike - x.underlying_last_price))[0] - - # Use abstraction method to order a covered call to avoid manual error - option_strategy = OptionStrategies.covered_call(symbol, atm_call.strike,expiry) - self.buy(option_strategy, 1) - - def on_securities_changed(self, changes: SecurityChanges) -> None: - for security in changes.added_securities: - if security.type == SecurityType.FUTURE_OPTION: - # Historical data - history = self.history(security.symbol, 10, Resolution.MINUTE)-
public class FutureOptionExampleAlgorithm : QCAlgorithm
-{
- private Future _underlying;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(5000000);
- // Subscribe the underlying since the updated price is needed for filtering
- _underlying = AddFuture(Futures.Indices.SP500EMini,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- contractDepthOffset: 0);
- // Filter the underlying continuous Futures to narrow the FOP spectrum
- _underlying.SetFilter(0, 182);
- // Filter for the current-week-expiring calls to formulate a covered call that expires at the end of week
- AddFutureOption(_underlying.Symbol, (u) => u.CallsOnly().Expiration(0, 5));
- }
-
- public override void OnData(Slice slice)
- {
- // Create canonical symbol for the mapped future contract, since option chains are mapped by canonical symbol
- var symbol = QuantConnect.Symbol.CreateCanonicalOption(_underlying.Mapped);
-
- // Get option chain data for the mapped future, as both the underlying and FOP have the highest liquidity among all other contracts
- if (!Portfolio.Invested &&
- slice.OptionChains.TryGetValue(symbol, out var chain))
- {
- // Obtain the ATM call that expires at the end of week, such that both underlying and the FOP expires the same time
- var expiry = chain.Max(x => x.Expiry);
- var atmCall = chain.Where(x => x.Expiry == expiry)
- .OrderBy(x => Math.Abs(x.Strike - x.UnderlyingLastPrice))
- .First();
-
- // Use abstraction method to order a covered call to avoid manual error
- var optionStrategy = OptionStrategies.CoveredCall(symbol, atmCall.Strike, expiry);
- Buy(optionStrategy, 1);
- }
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- if (security.Type == SecurityType.FutureOption)
- {
- // Historical data
- var history = History(security.Symbol, 10, Resolution.Minute);
- }
- }
- }
-}
- - The following example demonstrates a daily renewing speculation trade on upward movement of Gold with FOP using algorithm framework. Using FOP, traders can achieve lower cost to get similar absolute profit, given the FOP is selected to be deep ITM with high Delta value. -
-from AlgorithmImports import *
-
-class USFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- # Override an option universe selection model to select the FOPs
- self.set_universe_selection(GoldFOPUniverseSelectionModel(self))
- # Handle the FOP trading logic in an alpha model
- self.add_alpha(ConstantFutureOptionsAlphaModel())
- # To order a single contract per insight, use a custom portfolio construction model
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-
-class GoldFOPUniverseSelectionModel(OptionUniverseSelectionModel):
-
- # Daily renewed universe since option contract list is updated on a daily basis
- def __init__(self, algorithm) -> None:
- self._algorithm = algorithm
- super().__init__(timedelta(1), self.select_fop_symbols)
-
- def select_fop_symbols(self, utc_time: datetime) -> List[Symbol]:
- # Create the underlying symbol to get the FOP contracts later
- future_symbol = Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
- # Get all gold FOP contracts of the front month gold contract expiring within 3 months, since their liquidity is the highest
- future_contract_list = self._algorithm.future_chain_provider.get_future_contract_list(future_symbol, self._algorithm.time)
- return [Symbol.create_canonical_option(x) for x in future_contract_list
- if x.id.date <= self._algorithm.time + timedelta(90)]
-
- def filter(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Filter for the ATM calls that expires latest (same expiry as the underlying)
- # +/-5 strike range buffer for price movement
- return option_filter_universe.back_month().strikes(-5, +5).calls_only()
-
-
-class ConstantFutureOptionsAlphaModel(AlphaModel):
-
- # A dictionary to cache the mapped FOP of the underlying Future for filtering wanted option chain data and check if invested
- option_contract_by_future_underlying_contract = {}
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
-
- for kvp in slice.option_chains:
- # Liquidate underlying Future contract after Option assignment
- underlying_future_contract = kvp.key.underlying
- if algorithm.portfolio[underlying_future_contract].invested:
- algorithm.insights.cancel([underlying_future_contract])
- del self.option_contract_by_future_underlying_contract[underlying_future_contract]
-
- # Do not repeatly invest in the same underlying's FOP
- chain = [contract for contract in kvp.value if algorithm.securities[contract.symbol].is_tradable]
- if not chain or underlying_future_contract in self.option_contract_by_future_underlying_contract:
- continue
-
- # Select the Option contract with the lowest strike price to speculate trade the underlying with lowest cost and highest delta
- contract = sorted(chain, key=lambda x: x.strike)[0]
- insights.append(Insight.price(contract.symbol, contract.expiry + timedelta(1), InsightDirection.UP))
- self.option_contract_by_future_underlying_contract[underlying_future_contract] = contract
-
- return insights
-
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
-
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- # Use integer target to create a portfolio target to trade a single contract
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class FutureOptionDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Override an option universe selection model to select the FOPs
- AddUniverseSelection(new GoldFOPUniverseSelectionModel(this));
- // Handle the FOP trading logic in an alpha model
- SetAlpha(new ConstantFutureOptionsAlphaModel());
- // To order a single contract per insight, use a custom portfolio construction model
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-public class GoldFOPUniverseSelectionModel : OptionUniverseSelectionModel
-{
- // Daily renewed universe since option contract list is updated on a daily basis
- public GoldFOPUniverseSelectionModel(QCAlgorithm algorithm)
- : base(TimeSpan.FromDays(1), _ => OptionChainSymbolSelector(algorithm, _))
- {
- }
-
- private static IEnumerable<Symbol> OptionChainSymbolSelector(QCAlgorithm algorithm, DateTime utcTime)
- {
- // Create the underlying symbol to get the FOP contracts later
- var futureSymbol = QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX);
- // Get all gold FOP contracts of the front month gold contract expiring within 3 months, since their liquidity is the highest
- return algorithm.FutureChainProvider.GetFutureContractList(futureSymbol, algorithm.Time)
- .Where(futureContractSymbol => futureContractSymbol.ID.Date <= algorithm.Time + TimeSpan.FromDays(90))
- .Select(futureContractSymbol => QuantConnect.Symbol.CreateCanonicalOption(futureContractSymbol));
- }
-
- protected override OptionFilterUniverse Filter(OptionFilterUniverse optionFilterUniverse)
- {
- // Filter for the ATM calls that expires latest (same expiry as the underlying)
- // +/-5 strike range buffer for price movement
- return optionFilterUniverse.BackMonth().Strikes(-5, +5).CallsOnly();
- }
-}
-
-
-class ConstantFutureOptionsAlphaModel : AlphaModel
-{
- // A dictionary to cache the mapped FOP of the underlying Future for filtering wanted option chain data and check if invested
- private Dictionary<Symbol, OptionContract> optionContractByUnderlyingFutureContract = new Dictionary<Symbol, OptionContract>();
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- foreach (var kvp in slice.OptionChains)
- {
- // Liquidate underlying Future contract after Option assignment
- var underlyingFutureContract = kvp.Key.Underlying;
- if (algorithm.Portfolio[underlyingFutureContract].Invested)
- {
- algorithm.Insights.Cancel(new[] { underlyingFutureContract });
- optionContractByUnderlyingFutureContract.Remove(underlyingFutureContract);
- }
-
- // Do not repeatly invest in the same underlying's FOP
- var chain = kvp.Value.Where(contract => algorithm.Securities[contract.Symbol].IsTradable);
- if (chain.Count() == 0 || optionContractByUnderlyingFutureContract.ContainsKey(underlyingFutureContract))
- {
- continue;
- }
-
- // Select the Option contract with the lowest strike price to speculate trade the underlying with lowest cost and highest delta
- var contract = chain.MinBy(contract => contract.Strike);
- insights.Add(Insight.Price(contract.Symbol, contract.Expiry.AddDays(1), InsightDirection.Up));
- optionContractByUnderlyingFutureContract.Add(kvp.Key.Underlying, contract);
- }
- return insights;
- }
-}
-
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- // Use integer target to create a portfolio target to trade a single contract
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Future Options dataset provides
-
- TradeBar
-
- ,
-
- QuoteBar
-
- , and
-
- OpenInterest
-
- objects.
-
-
- TradeBar
-
- objects have the following attributes:
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- OpenInterest
-
- objects have the following attributes:
-
- -
- The US Futures dataset by AlgoSeek provides Futures data, including price, volume, open interest, and expiry. The data covers the 157 most liquid contracts, starts in May 2009, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on the CFE - - * - - , CBOT, CME, COMEX, NYMEX, and ICE - - * - - . -
-- This dataset also depends on the - - US Futures Security Master - - because the US Futures Security Master dataset contains information to construct continuous Futures. -
-- For more information about the US Futures dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering equities, futures, options, cash forex, and cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit - - algoseek.com - - . -
- - - -- The following snippet demonstrates how to request data from the US Futures dataset: -
-future = self.add_future(Futures.Metals.GOLD) -future.set_filter(0, 90)-
var future = AddFuture(Futures.Metals.Gold); -future.SetFilter(0, 90);-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- May 2009 - | -
| - Asset Coverage - | -- 157 Futures - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Tick, Second, Minute, Hour, & Daily - | -
| - Timezone - | -
-
|
-
| - Market Hours - | -- - Regular and Extended - - | -
- This dataset only includes Sugar (SB) from the ICE exchange. -
-- This data provider doesn't include a live data feed for the CFE market (VIX). -
-- LBS (Random Length Lumber) was deprecated for LBR (Lumber). -
- - - -- The volume of the daily trade bars from this dataset is different from the daily volume that CME and other platforms like Yahoo Finance report because the CME includes pit trades in their daily volume calculation. In contrast, the volume of the daily trade bars in this dataset (from AlgoSeek) doesn't include pit trades because pit trades are over-the-counter, which algorithms can't trade. -
-- Another discrepancy occurs from the start and end times of the daily bars. Daily bars from the CME and Yahoo Finance span from 5 PM Central Time (CT) to 4 PM CT on the following day. In contrast, QuantConnect consolidates daily bars from from 12 AM Eastern Time (ET) to 12 AM ET the following day. Therefore, to calculate the daily volume in the same way that CME does (excluding the pit trades), sum the volume of intraday bars that span 5 PM CT to 4 PM CT on the following day. For an example implementation, see - - Examples - - . -
- - - -
- To add US Futures data to your algorithm, call the
-
- AddFuture
-
-
- add_future
-
- method. Save a reference to the Future so you can access the data later in your algorithm.
-
class USFuturesDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2013, 12, 20) - self.set_end_date(2014, 2, 20) - self.set_cash(1000000) - self.universe_settings.asynchronous = True - # Request Gold Future data - future = self.add_future(Futures.Metals.GOLD) - # Set filter to obtain the contracts expire within 90 days - future.set_filter(0, 90) - self.future_symbol = future.symbol-
public class USFuturesDataAlgorithm : QCAlgorithm
-{
- private Symbol _futureSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2013, 12, 20);
- SetEndDate(2014, 2, 20);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
- // Request Gold Future data
- var future = AddFuture(Futures.Metals.Gold);
- // Set filter to obtain the contracts expire within 90 days
- future.SetFilter(0, 90);
- _futureSymbol = future.Symbol;
- }
-}
-
- - For more information about creating Future subscriptions, see - - Requesting Data - - or - - Futures Universes - - . -
- - - -
- To get the current US Futures data, index the
-
- Bars
-
-
- bars
-
- ,
-
- QuoteBars
-
-
- quote_bars
-
- , or
-
- Ticks
-
-
- ticks
-
- properties of the current
-
-
- Slice
-
-
- with the Future
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- # Access data: TradeBar data
- if self.future_symbol in slice.bars:
- trade_bar = slice.bars[self.future_symbol]
- self.log(f"{self.future_symbol} close at {slice.time}: {trade_bar.close}")
-
- # Access data: QuoteBar data
- if self.future_symbol in slice.quote_bars:
- quote_bar = slice.quote_bars[self.future_symbol]
- self.log(f"{self.future_symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- # Access data: Ticks data
- if self.future_symbol in slice.ticks:
- ticks = slice.ticks[self.future_symbol]
- for tick in ticks:
- self.log(f"{self.future_symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- // Access data: TradeBar data
- if (slice.Bars.TryGetValue(_futureSymbol, out var tradeBar))
- {
- Log($"{_futureSymbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- // Access data: QuoteBar data
- if (slice.QuoteBars.TryGetValue(_futureSymbol, out var quoteBar))
- {
- Log($"{_futureSymbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- // Access data: Ticks data
- if (slice.Ticks.TryGetValue(_futureSymbol, out var ticks))
- {
- foreach (var tick in ticks)
- {
- Log($"{_futureSymbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- # Iterate all TradeBar received
- for symbol, trade_bar in slice.bars.items():
- self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
-
- # Iterate all QuoteBar received
- for symbol, quote_bar in slice.quote_bars.items():
- self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- # Iterate all Ticks received
- for symbol, ticks in slice.ticks.items():
- for tick in ticks:
- self.log(f"{symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- // Iterate all TradeBar received
- foreach (var kvp in slice.Bars)
- {
- var symbol = kvp.Key;
- var tradeBar = kvp.Value;
- Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- // Iterate all QuoteBar received
- foreach (var kvp in slice.QuoteBars)
- {
- var symbol = kvp.Key;
- var quoteBar = kvp.Value;
- Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- // Iterate all Ticks received
- foreach (var kvp in slice.Ticks)
- {
- var symbol = kvp.Key;
- var ticks = kvp.Value;
- foreach (var tick in ticks)
- {
- Log($"{symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
- - For more information about accessing US Futures data, see - - Handling Data - - . -
- - - -- You can get historical US Futures data in an algorithm and the Research Environment. -
-
- To get historical US Futures data in an algorithm, call the
-
- History
-
-
- history
-
- method with the canonical Futures
-
- Symbol
-
- or a Futures contract
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame objects -contract_history_df = self.history(contract.symbol, 100, Resolution.MINUTE) -continuous_history_df = self.history(self.future_symbol, - start=self.time - timedelta(days=15), - end=self.time, - resolution=Resolution.MINUTE, - fill_forward=False, - extended_market_hours=False, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.RAW, - contract_depth_offset=0) - -# TradeBar objects -contract_history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE) -continous_history_trade_bars = self.history[TradeBar](self.future_symbol, 100, Resolution.MINUTE) - -# QuoteBar objects -contract_history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE) -continous_history_quote_bars = self.history[QuoteBar](self.future_symbol, 100, Resolution.MINUTE) - -# Tick objects -contract_history_ticks = self.history[Tick](contract.symbol, timedelta(seconds=10), Resolution.TICK) -continous_history_ticks = self.history[Tick](self.future_symbol, timedelta(seconds=10), Resolution.TICK)-
// TradeBar objects
-var contractHistoryTradeBars = History(contract.Symbol, 100, Resolution.Minute);
-var continuousHistoryTradeBars = History(
- symbols: new[] {_futureSymbol},
- start: Time - TimeSpan.FromDays(15),
- end: Time,
- resolution: Resolution.Minute,
- fillForward: false,
- extendedMarketHours: false,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.Raw,
- contractDepthOffset: 0);
-
-// QuoteBar objects
-var contractHistoryQuoteBars = History<QuoteBar>(contract.Symbol, 100, Resolution.Minute);
-var continuousHistoryQuoteBars = History<QuoteBar>(_futureSymbol, 100, Resolution.Minute);
-
-// Tick objects
-var contractHistoryTicks = History<Tick>(contract.Symbol, TimeSpan.FromSeconds(10), Resolution.Tick);
-var continuousHistoryTicks = History<Tick>(_futureSymbol, TimeSpan.FromSeconds(10), Resolution.Tick);
- - For more information about historical data in algorithms, see - - History Requests - - . For more information about the price adjustments for continuous contracts, see - - Continous Contracts - - . -
-
- To get historical US Futures data in the Research Environment for an entire Futures chain, call the
-
- FutureHistory
-
-
- future_history
-
- method with the canonical Future
-
- Symbol
-
- .
-
qb = QuantBook() -future = qb.add_future(Futures.Metals.GOLD) -future.set_filter(0, 90) -history = qb.future_history(future.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5)) -history_df = history.data_frame -all_history = history.get_all_data() -expiries = history.get_expiry_dates()-
var qb = new QuantBook(); -var future = qb.AddFuture(Futures.Metals.Gold); -future.SetFilter(0, 90); -var history = qb.FutureHistory(future.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 5)); - -var contracts = history.SelectMany(x => x.OptionChains.SelectMany(y => y.Value.Contracts.Keys)).Distinct().ToList(); -var expiries = contracts.Select(x => x.ID.Date).Distinct().ToList();-
- To get historical data for a single US Futures contract or the continuous Futures contract, call the
-
- History
-
-
- history
-
- method like you would in an algorithm but on the
-
- QuantBook
-
- object. For more information about historical data in the Research Environment, see
-
- Futures
-
- .
-
- The following list shows the available (157) Futures: -
-
- Futures.Currencies.AUD
-
- : Australian Dollar Futures (CME: 6A)
-
- Futures.Currencies.AUDCAD
-
- : Australian Dollar/Canadian Dollar Futures (CME: ACD)
-
- Futures.Currencies.AUDJPY
-
- : Australian Dollar/Japanese Yen Futures (CME: AJY)
-
- Futures.Currencies.AUDNZD
-
- : Australian Dollar/New Zealand Dollar Futures (CME: ANE)
-
- Futures.Currencies.BRL
-
- : Brazillian Real Futures (CME: 6L)
-
- Futures.Currencies.BTC
-
- : Bitcoin Futures (CME: BTC)
-
- Futures.Currencies.BTICMicroBTC
-
-
- Futures.Currencies.BTIC_MICRO_BTC
-
- : BTIC on Micro Bitcoin Futures (CME: MIB)
-
- Futures.Currencies.BTICMicroEther
-
-
- Futures.Currencies.BTIC_MICRO_ETHER
-
- : BTIC on Micro Ether Futures (CME: MRB)
-
- Futures.Currencies.CAD
-
- : Canadian Dollar Futures (CME: 6C)
-
- Futures.Currencies.CADJPY
-
- : Canadian Dollar/Japanese Yen Futures (CME: CJY)
-
- Futures.Currencies.CHF
-
- : Swiss Franc Futures (CME: 6S)
-
- Futures.Currencies.ETH
-
- : Ether Futures (CME: ETH)
-
- Futures.Currencies.EUR
-
- : Euro FX Futures (CME: 6E)
-
- Futures.Currencies.EURAUD
-
- : Euro/Australian Dollar Futures (CME: EAD)
-
- Futures.Currencies.EURCAD
-
- : Euro/Canadian Dollar Futures (CME: ECD)
-
- Futures.Currencies.EuroFXEmini
-
-
- Futures.Currencies.EURO_FX_EMINI
-
- : E-mini Euro FX Futures (CME: E7)
-
- Futures.Currencies.EURSEK
-
- : Euro/Swedish Krona Futures (CME: ESK)
-
- Futures.Currencies.GBP
-
- : British Pound Futures (CME: 6B)
-
- Futures.Currencies.JapaneseYenEmini
-
-
- Futures.Currencies.JAPANESE_YEN_EMINI
-
- : E-mini Japanese Yen Futures (CME: J7)
-
- Futures.Currencies.JPY
-
- : Japanese Yen Futures (CME: 6J)
-
- Futures.Currencies.MicroAUD
-
-
- Futures.Currencies.MICRO_AUD
-
- : Micro AUD/USD Futures (CME: M6A)
-
- Futures.Currencies.MicroBTC
-
-
- Futures.Currencies.MICRO_BTC
-
- : Micro Bitcoin Futures (CME: MBT)
-
- Futures.Currencies.MicroCAD
-
-
- Futures.Currencies.MICRO_CAD
-
- : Micro USD/CAD Futures (CME: M6C)
-
- Futures.Currencies.MicroCADUSD
-
-
- Futures.Currencies.MICRO_CADUSD
-
- : Micro CAD/USD Futures (CME: MCD)
-
- Futures.Currencies.MicroCHF
-
-
- Futures.Currencies.MICRO_CHF
-
- : Micro CHF/USD Futures (CME: MSF)
-
- Futures.Currencies.MicroEther
-
-
- Futures.Currencies.MICRO_ETHER
-
- : Micro Ether Futures (CME: MET)
-
- Futures.Currencies.MicroEUR
-
-
- Futures.Currencies.MICRO_EUR
-
- : Micro EUR/USD Futures (CME: M6E)
-
- Futures.Currencies.MicroGBP
-
-
- Futures.Currencies.MICRO_GBP
-
- : Micro GBP/USD Futures (CME: M6B)
-
- Futures.Currencies.MicroINRUSD
-
-
- Futures.Currencies.MICRO_INRUSD
-
- : Micro INR/USD Futures (CME: MIR)
-
- Futures.Currencies.MicroJPY
-
-
- Futures.Currencies.MICRO_JPY
-
- : Micro JPY/USD Futures (CME: MJY)
-
- Futures.Currencies.MicroUSDCHF
-
-
- Futures.Currencies.MICRO_USDCHF
-
- : Micro USD/CHF Futures (CME: M6S)
-
- Futures.Currencies.MicroUSDCNH
-
-
- Futures.Currencies.MICRO_USDCNH
-
- : Micro USD/CNH Futures (CME: MNH)
-
- Futures.Currencies.MicroUSDJPY
-
-
- Futures.Currencies.MICRO_USDJPY
-
- : Micro USD/JPY Futures (CME: M6J)
-
- Futures.Currencies.MXN
-
- : Mexican Peso Futures (CME: 6M)
-
- Futures.Currencies.NZD
-
- : New Zealand Dollar Futures (CME: 6N)
-
- Futures.Currencies.RUB
-
- : Russian Ruble Futures (CME: 6R)
-
- Futures.Currencies.StandardSizeUSDOffshoreRMBCNH
-
-
- Futures.Currencies.STANDARD_SIZE_USD_OFFSHORE_RMBCNH
-
- : Standard-Size USD/Offshore RMB (CNH) Futures (CME: CNH)
-
- Futures.Currencies.ZAR
-
- : South African Rand Futures (CME: 6Z)
-
- Futures.Energy.ArgusLLSvsWTIArgusTradeMonth
-
-
- Futures.Energy.ARGUS_LL_SVS_WTI_ARGUS_TRADE_MONTH
-
- : Argus LLS vs. WTI (Argus) Trade Month Futures (NYMEX: AE5)
-
- Futures.Energy.ArgusPropaneFarEastIndex
-
-
- Futures.Energy.ARGUS_PROPANE_FAR_EAST_INDEX
-
- : Argus Propane Far East Index Futures (NYMEX: A7E)
-
- Futures.Energy.ArgusPropaneSaudiAramco
-
-
- Futures.Energy.ARGUS_PROPANE_SAUDI_ARAMCO
-
- : Argus Propane (Saudi Aramco) Futures (NYMEX: A9N)
-
- Futures.Energy.BrentCrudeOilVsDubaiCrudeOilPlatts
-
-
- Futures.Energy.BRENT_CRUDE_OIL_VS_DUBAI_CRUDE_OIL_PLATTS
-
- : Brent Crude Oil vs. Dubai Crude Oil (Platts) Futures (NYMEX: ADB)
-
- Futures.Energy.BrentLastDayFinancial
-
-
- Futures.Energy.BRENT_LAST_DAY_FINANCIAL
-
- : Brent Last Day Financial Futures (NYMEX: BZ)
-
- Futures.Energy.ChicagoEthanolPlatts
-
-
- Futures.Energy.CHICAGO_ETHANOL_PLATTS
-
- : Chicago Ethaanol (Platts) Futures (NYMEX: CU)
-
- Futures.Energy.ConwayPropaneOPIS
-
-
- Futures.Energy.CONWAY_PROPANE_OPIS
-
- : Conway Propane (OPIS) Futures (NYMEX: A8K)
-
- Futures.Energy.CrudeOilWTI
-
-
- Futures.Energy.CRUDE_OIL_WTI
-
- : Crude Oil WTI Futures (NYMEX: CL)
-
- Futures.Energy.DubaiCrudeOilPlattsFinancial
-
-
- Futures.Energy.DUBAI_CRUDE_OIL_PLATTS_FINANCIAL
-
- : Dubai Crude Oil (Platts) Financial Futures (NYMEX: DCB)
-
- Futures.Energy.EastWestGasolineSpreadPlattsArgus
-
-
- Futures.Energy.EAST_WEST_GASOLINE_SPREAD_PLATTS_ARGUS
-
- : East-West Gasoline Spread (Platts-Argus) Futures (NYMEX: EWG)
-
- Futures.Energy.EastWestNaphthaJapanCFvsCargoesCIFNWESpreadPlatts
-
-
- Futures.Energy.EAST_WEST_NAPHTHA_JAPAN_C_FVS_CARGOES_CIFNWE_SPREAD_PLATTS
-
- : East-West Naphtha: Japan C&F vs. Cargoes CIF NWE Spread (Platts) Futures (NYMEX: EWN)
-
- Futures.Energy.Ethanol
-
-
- Futures.Energy.ETHANOL
-
- : Ethanol Futures (CBOT: EH)
-
- Futures.Energy.EthanolT2FOBRdamIncludingDutyPlatts
-
-
- Futures.Energy.ETHANOL_T_2_FOB_RDAM_INCLUDING_DUTY_PLATTS
-
- : Ethanol T2 FOB Rdam Including Duty (Platts) Futures (NYMEX: AZ1)
-
- Futures.Energy.EuropeanNaphthaPlattsCrackSpread
-
-
- Futures.Energy.EUROPEAN_NAPHTHA_PLATTS_CRACK_SPREAD
-
- : European Naphtha (Platts) Crack Spread Futures (NYMEX: EN)
-
- Futures.Energy.EuropeanPropaneCIFARAArgus
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS
-
- : European Propane CIF ARA (Argus) Futures (NYMEX: APS)
-
- Futures.Energy.EuropeanPropaneCIFARAArgusVsNaphthaCargoesCIFNWEPlatts
-
-
- Futures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS_VS_NAPHTHA_CARGOES_CIFNWE_PLATTS
-
- : European Propane CIF ARA (Argus) vs. Naphtha Cargoes CIF NWE (Platts) Futures (NYMEX: EPN)
-
- Futures.Energy.FreightRouteTC14Baltic
-
-
- Futures.Energy.FREIGHT_ROUTE_TC_14_BALTIC
-
- : Freight Route TC14 (Baltic) Futures (NYMEX: FRC)
-
- Futures.Energy.Gasoline
-
-
- Futures.Energy.GASOLINE
-
- : Gasoline RBOB Futures (NYMEX: RB)
-
- Futures.Energy.GasolineEurobobOxyNWEBargesArgus
-
-
- Futures.Energy.GASOLINE_EUROBOB_OXY_NWE_BARGES_ARGUS
-
- : Gasoline Euro-bob Oxy NWE Barges (Argus) Futures (NYMEX: B7H)
-
- Futures.Energy.GroupThreeSuboctaneGasolinePlattsVsRBOB
-
-
- Futures.Energy.GROUP_THREE_SUBOCTANE_GASOLINE_PLATTS_VS_RBOB
-
- : Group Three Sub-octane Gasoliine (Platts) vs. RBOB Futures (NYMEX: AA8)
-
- Futures.Energy.GroupThreeULSDPlattsVsNYHarborULSD
-
-
- Futures.Energy.GROUP_THREE_ULSD_PLATTS_VS_NY_HARBOR_ULSD
-
- : Group Three ULSD (Platts) vs. NY Harbor ULSD Futures (NYMEX: AA6)
-
- Futures.Energy.GulfCoastCBOBGasolineA2PlattsVsRBOBGasoline
-
-
- Futures.Energy.GULF_COAST_CBOB_GASOLINE_A_2_PLATTS_VS_RBOB_GASOLINE
-
- : Gulf Coast CBOB Gasoline A2 (Platts) vs. RBOB Gasoline Futures (NYMEX: CRB)
-
- Futures.Energy.GulfCoastHSFOPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.GULF_COAST_HSFO_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Gulf Coast HSFO (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: GCU)
-
- Futures.Energy.HeatingOil
-
-
- Futures.Energy.HEATING_OIL
-
- : Heating Oil Futures (NYMEX: HO)
-
- Futures.Energy.LosAngelesCARBOBGasolineOPISvsRBOBGasoline
-
-
- Futures.Energy.LOS_ANGELES_CARBOB_GASOLINE_OPI_SVS_RBOB_GASOLINE
-
- : Los Angeles CARBOB Gasoline (OPIS) vs. RBOB Gasoline Futures (NYMEX: AJL)
-
- Futures.Energy.LosAngelesCARBDieselOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_CARB_DIESEL_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles CARB Diesel (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AKL)
-
- Futures.Energy.LosAngelesJetOPISvsNYHarborULSD
-
-
- Futures.Energy.LOS_ANGELES_JET_OPI_SVS_NY_HARBOR_ULSD
-
- : Los Angeles Jet (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AJS)
-
- Futures.Energy.MarsArgusVsWTIFinancial
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_FINANCIAL
-
- : Mars (Argus) vs. WTI Financial Futures (NYMEX: AYX)
-
- Futures.Energy.MarsArgusVsWTITradeMonth
-
-
- Futures.Energy.MARS_ARGUS_VS_WTI_TRADE_MONTH
-
- : Mars (Argus) vs. WTI Trade Month Futures (NYMEX: AYV)
-
- Futures.Energy.MicroCrudeOilWTI
-
-
- Futures.Energy.MICRO_CRUDE_OIL_WTI
-
- : Micro WTI Crude Oil Futures (NYMEX: MCL)
-
- Futures.Energy.MicroEuropeanFOBRdamMarineFuelZeroPointFivePercentBargesPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_FOB_RDAM_MARINE_FUEL_ZERO_POINT_FIVE_PERCENT_BARGES_PLATTS
-
- : Micro European FOB Rdam Marine Fuel 0.5% Barges (Platts) Futures (NYMEX: R5O)
-
- Futures.Energy.MicroEuropeanThreePointFivePercentOilBargesFOBRdamPlatts
-
-
- Futures.Energy.MICRO_EUROPEAN_THREE_POINT_FIVE_PERCENT_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Micro European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: MEF)
-
- Futures.Energy.MicroGasoilZeroPointOnePercentBargesFOBARAPlatts
-
-
- Futures.Energy.MICRO_GASOIL_ZERO_POINT_ONE_PERCENT_BARGES_FOBARA_PLATTS
-
- : Micro Gasoil 0.1% Barges FOB ARA (Platts) Futures (NYMEX: M1B)
-
- Futures.Energy.MicroSingaporeFOBMarineFuelZeroPointFivePercetPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FOB_MARINE_FUEL_ZERO_POINT_FIVE_PERCET_PLATTS
-
- : Micro Singapore FOB Marine Fuel 0.5% (Platts) Futures (NYMEX: S5O)
-
- Futures.Energy.MicroSingaporeFuelOil380CSTPlatts
-
-
- Futures.Energy.MICRO_SINGAPORE_FUEL_OIL_380_CST_PLATTS
-
- : Micro Singapore Fuel Oil 380CST (Platts) Futures (NYMEX: MAF)
-
- Futures.Energy.MiniEuropeanThreePointPercentFiveFuelOilBargesPlatts
-
-
- Futures.Energy.MINI_EUROPEAN_THREE_POINT_PERCENT_FIVE_FUEL_OIL_BARGES_PLATTS
-
- : Mini European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: A0D)
-
- Futures.Energy.MiniSingaporeFuelOil180CstPlatts
-
-
- Futures.Energy.MINI_SINGAPORE_FUEL_OIL_180_CST_PLATTS
-
- : Mini Singapore Fuel Oil 180 cst (Platts) Futures (NYMEX: A0F)
-
- Futures.Energy.MontBelvieuEthaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_ETHANE_OPIS
-
- : Mont Belvieu Ethane (OPIS) Futures (NYMEX: AC0)
-
- Futures.Energy.MontBelvieuLDHPropaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_LDH_PROPANE_OPIS
-
- : Mont Belvieu LDH Propane (OPIS) Futures (NYMEX: B0)
-
- Futures.Energy.MontBelvieuNaturalGasolineOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NATURAL_GASOLINE_OPIS
-
- : Mont Belvieu Natural Gasoline (OPIS) Futures (NYMEX: A7Q)
-
- Futures.Energy.MontBelvieuNormalButaneOPIS
-
-
- Futures.Energy.MONT_BELVIEU_NORMAL_BUTANE_OPIS
-
- : Mont Belvieu Normal Butane (OPIS) Futures (NYMEX: AD0)
-
- Futures.Energy.NaturalGas
-
-
- Futures.Energy.NATURAL_GAS
-
- : Natural Gas Futures (NYMEX: NG)
-
- Futures.Energy.NaturalGasHenryHubLastDayFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_LAST_DAY_FINANCIAL
-
- : Natural Gas (Henry Hub) Last-day Financial Futures (NYMEX: HH)
-
- Futures.Energy.NaturalGasHenryHubPenultimateFinancial
-
-
- Futures.Energy.NATURAL_GAS_HENRY_HUB_PENULTIMATE_FINANCIAL
-
- : Natural Gas (Henry Hub) Penultimate Financial Futures (NYMEX: HP)
-
- Futures.Energy.OnePercentFuelOilCargoesFOBNWEPlattsVsThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.ONE_PERCENT_FUEL_OIL_CARGOES_FOBNWE_PLATTS_VS_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : 1% Fuel Oil Cargoes FOB NWE (Platts) vs. 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: FSS)
-
- Futures.Energy.PremiumUnleadedGasoline10ppmFOBMEDPlatts
-
-
- Futures.Energy.PREMIUM_UNLEADED_GASOLINE_10_PPM_FOBMED_PLATTS
-
- : Premium Unleaded Gasoline 10 ppm FOB MED (Platts) Futures (NYMEX: A3G)
-
- Futures.Energy.PropaneNonLDHMontBelvieuOPIS
-
-
- Futures.Energy.PROPANE_NON_LDH_MONT_BELVIEU_OPIS
-
- : Propane Non-LDH Mont Belvieu (OPIS) Futures (NYMEX: A1R)
-
- Futures.Energy.RBOBGasolineCrackSpread
-
-
- Futures.Energy.RBOB_GASOLINE_CRACK_SPREAD
-
- : RBOB Gasoline Crack Spread Futures (NYMEX: ARE)
-
- Futures.Energy.RBOBGasolineVsEurobobOxyNWEBargesArgusThreeHundredFiftyThousandGallons
-
-
- Futures.Energy.RBOB_GASOLINE_VS_EUROBOB_OXY_NWE_BARGES_ARGUS_THREE_HUNDRED_FIFTY_THOUSAND_GALLONS
-
- : RBOB Gasoline vs. Euro-bob Oxy NWE Barges (Argus) (350,000 gallons) Futures (NYMEX: EXR)
-
- Futures.Energy.SingaporeFuelOil380cstPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlatts
-
-
- Futures.Energy.SINGAPORE_FUEL_OIL_380_CST_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS
-
- : Singapore Fuel Oil 380 cst (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: EVC)
-
- Futures.Energy.SingaporeGasoilPlattsVsLowSulphurGasoilFutures
-
-
- Futures.Energy.SINGAPORE_GASOIL_PLATTS_VS_LOW_SULPHUR_GASOIL_FUTURES
-
- : Singapore Gasoil (Platts) vs. Low Sulphur Gasoil Futures (NYMEX: AGA)
-
- Futures.Energy.SingaporeMogas92UnleadedPlattsBrentCrackSpread
-
-
- Futures.Energy.SINGAPORE_MOGAS_92_UNLEADED_PLATTS_BRENT_CRACK_SPREAD
-
- : Singapore Mogas 92 Unleaded (Platts) Brent Crack Spread Futures (NYMEX: D1N)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread Futures (NYMEX: FO)
-
- Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread1000mt
-
-
- Futures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD_1000_MT
-
- : 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread (1000mt) Futures (NYMEX: BOO)
-
- Futures.Energy.WTIBrentFinancial
-
-
- Futures.Energy.WTI_BRENT_FINANCIAL
-
- : WTI-Brent Financial Futures (NYMEX: BK)
-
- Futures.Energy.WTIFinancial
-
-
- Futures.Energy.WTI_FINANCIAL
-
- : WTI Financial Futures (NYMEX: CSX)
-
- Futures.Energy.WTIHoustonArgusVsWTITradeMonth
-
-
- Futures.Energy.WTI_HOUSTON_ARGUS_VS_WTI_TRADE_MONTH
-
- : WTI Houston (Argus) vs. WTI Trade Month Futures (NYMEX: HTT)
-
- Futures.Energy.WTIHoustonCrudeOil
-
-
- Futures.Energy.WTI_HOUSTON_CRUDE_OIL
-
- : WTI Houston Crude Oil Futures (NYMEX: HCL)
-
- Futures.Financials.EuroDollar
-
-
- Futures.Financials.EURO_DOLLAR
-
- : EuroDollar Futures (CME: GE)
-
- Futures.Financials.FiveYearUSDMACSwap
-
-
- Futures.Financials.FIVE_YEAR_USDMAC_SWAP
-
- : 5-Year USD MAC Swap Futures (CBOT: F1U)
-
- Futures.Financials.MicroY10TreasuryNote
-
-
- Futures.Financials.MICRO_Y_10_TREASURY_NOTE
-
- : Micro 10-Year Yield Futures (CBOT: 10Y)
-
- Futures.Financials.MicroY2TreasuryBond
-
-
- Futures.Financials.MICRO_Y_2_TREASURY_BOND
-
- : Micro 2-Year Yield Futures (CBOT: 2YY)
-
- Futures.Financials.MicroY30TreasuryBond
-
-
- Futures.Financials.MICRO_Y_30_TREASURY_BOND
-
- : Micro 30-Year Yield Futures (CBOT: 30Y)
-
- Futures.Financials.MicroY5TreasuryBond
-
-
- Futures.Financials.MICRO_Y_5_TREASURY_BOND
-
- : Micro 5-Year Yield Futures (CBOT: 5YY)
-
- Futures.Financials.UltraTenYearUSTreasuryNote
-
-
- Futures.Financials.ULTRA_TEN_YEAR_US_TREASURY_NOTE
-
- : Ultra 10-Year U.S. Treasury Note Futures (CBOT: TN)
-
- Futures.Financials.UltraUSTreasuryBond
-
-
- Futures.Financials.ULTRA_US_TREASURY_BOND
-
- : Ultra U.S. Treasury Bond Futures (CBOT: UB)
-
- Futures.Financials.Y10TreasuryNote
-
-
- Futures.Financials.Y_10_TREASURY_NOTE
-
- : 10Y U.S. Treasury Note Futures (CBOT: ZN)
-
- Futures.Financials.Y2TreasuryNote
-
-
- Futures.Financials.Y_2_TREASURY_NOTE
-
- : 2Y U.S. Treasury Note Futures (CBOT: ZT)
-
- Futures.Financials.Y30TreasuryBond
-
-
- Futures.Financials.Y_30_TREASURY_BOND
-
- : 30Y U.S. Treasury Bond Futures (CBOT: ZB)
-
- Futures.Financials.Y5TreasuryNote
-
-
- Futures.Financials.Y_5_TREASURY_NOTE
-
- : 5Y U.S. Treasury Note Futures (CBOT: ZF)
-
- Futures.Forestry.Lumber
-
-
- Futures.Forestry.LUMBER
-
- : Lumber Futures (CME: LBR)
-
- Futures.Forestry.RandomLengthLumber
-
-
- Futures.Forestry.RANDOM_LENGTH_LUMBER
-
- : Random Length Lumber Futures (CME: LBS)
-
- Futures.Grains.BlackSeaCornFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_CORN_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Corn Financially Settled (Platts) Futures (CBOT: BCF)
-
- Futures.Grains.BlackSeaWheatFinanciallySettledPlatts
-
-
- Futures.Grains.BLACK_SEA_WHEAT_FINANCIALLY_SETTLED_PLATTS
-
- : Black Sea Wheat Financially Settled (Platts) Futures (CBOT: BWF)
-
- Futures.Grains.Corn
-
-
- Futures.Grains.CORN
-
- : Corn Futures (CBOT: ZC)
-
- Futures.Grains.HRWWheat
-
-
- Futures.Grains.HRW_WHEAT
-
- : KC HRW Wheat Futures (CBOT: KE)
-
- Futures.Grains.Oats
-
-
- Futures.Grains.OATS
-
- : Oats Futures (CBOT: ZO)
-
- Futures.Grains.Soybeans
-
-
- Futures.Grains.SOYBEANS
-
- : Soybeans Futures (CBOT: ZS)
-
- Futures.Grains.SoybeanMeal
-
-
- Futures.Grains.SOYBEAN_MEAL
-
- : Soybean Meal Futures (CBOT: ZM)
-
- Futures.Grains.SoybeanOil
-
-
- Futures.Grains.SOYBEAN_OIL
-
- : Soybean Oil Futures (CBOT: ZL)
-
- Futures.Grains.Wheat
-
-
- Futures.Grains.WHEAT
-
- : Default wheat contract is SRWWheat (CBOT: ZW)
-
- Futures.Indices.BloombergCommodityIndex
-
-
- Futures.Indices.BLOOMBERG_COMMODITY_INDEX
-
- : Bloomberg Commodity Index Futures (CBOT: AW)
-
- Futures.Indices.Dow30EMini
-
-
- Futures.Indices.DOW_30_E_MINI
-
- : E-mini Dow Indu 30 Futures (CBOT: YM)
-
- Futures.Indices.DowJonesRealEstate
-
-
- Futures.Indices.DOW_JONES_REAL_ESTATE
-
- : Dow Jones Real Estate futures on CME (CME: RX)
-
- Futures.Indices.FTSEEmergingEmini
-
-
- Futures.Indices.FTSE_EMERGING_EMINI
-
- : E-mini FTSE Emerging Index Futures (CME: EI)
-
- Futures.Indices.MicroDow30EMini
-
-
- Futures.Indices.MICRO_DOW_30_E_MINI
-
- : Micro E-mini Dow Jones Industrial Average Index Futures (CBOT: MYM)
-
- Futures.Indices.MicroNASDAQ100EMini
-
-
- Futures.Indices.MICRO_NASDAQ_100_E_MINI
-
- : Micro E-mini Nasdaq-100 Index Futures (CME: MNQ)
-
- Futures.Indices.MicroRussell2000EMini
-
-
- Futures.Indices.MICRO_RUSSELL_2000_E_MINI
-
- : Micro E-mini Russell 2000 Index Futures (CME: M2K)
-
- Futures.Indices.MicroSP500EMini
-
-
- Futures.Indices.MICRO_SP_500_E_MINI
-
- : Micro E-mini S&P 500 Index Futures (CME: MES)
-
- Futures.Indices.NASDAQ100BiotechnologyEMini
-
-
- Futures.Indices.NASDAQ_100_BIOTECHNOLOGY_E_MINI
-
- : E-mini Nasdaq-100 Biotechnology Index Futures (CME: BIO)
-
- Futures.Indices.NASDAQ100EMini
-
-
- Futures.Indices.NASDAQ_100_E_MINI
-
- : E-mini NASDAQ 100 Futures (CME: NQ)
-
- Futures.Indices.Nikkei225Dollar
-
-
- Futures.Indices.NIKKEI_225_DOLLAR
-
- : Nikkei-225 Dollar Futures (CME: NKD)
-
- Futures.Indices.Nikkei225YenCME
-
-
- Futures.Indices.NIKKEI_225_YEN_CME
-
- : Nikkei-225 Yen denominated Futures on CME (CME: NIY)
-
- Futures.Indices.Russell1000EMini
-
-
- Futures.Indices.RUSSELL_1000_E_MINI
-
- : E-mini Russell 1000 futures on CME (CME: RS1)
-
- Futures.Indices.Russell2000EMini
-
-
- Futures.Indices.RUSSELL_2000_E_MINI
-
- : E-mini Russell 2000 Futures (CME: RTY)
-
- Futures.Indices.SPGSCICommodity
-
-
- Futures.Indices.SPGSCI_COMMODITY
-
- : S&P-GSCI Commodity Index Futures (CME: GD)
-
- Futures.Indices.SP400MidCapEmini
-
-
- Futures.Indices.SP_400_MID_CAP_EMINI
-
- : E-mini S&P MidCap 400 Futures (CME: EMD)
-
- Futures.Indices.SP500AnnualDividendIndex
-
-
- Futures.Indices.SP_500_ANNUAL_DIVIDEND_INDEX
-
- : (CME: SDA)
-
- Futures.Indices.SP500EMini
-
-
- Futures.Indices.SP_500_E_MINI
-
- : E-mini S&P 500 Futures (CME: ES)
-
- Futures.Indices.TOPIXYEN
-
- : YEN Denominated Topix Index Futures on CME (CME: TPY)
-
- Futures.Indices.USDDenominatedIbovespa
-
-
- Futures.Indices.USD_DENOMINATED_IBOVESPA
-
- : USD-Denominated Ibovespa Index Futures (CME: IBV)
-
- Futures.Indices.VIX
-
- : CBOE Volatility Index Futures (CFE: VX)
-
- Futures.Meats.FeederCattle
-
-
- Futures.Meats.FEEDER_CATTLE
-
- : Feeder Cattle Futures (CME: GF)
-
- Futures.Meats.LeanHogs
-
-
- Futures.Meats.LEAN_HOGS
-
- : Lean Hogs Futures (CME: HE)
-
- Futures.Meats.LiveCattle
-
-
- Futures.Meats.LIVE_CATTLE
-
- : Live Cattle Futures (CME: LE)
-
- Futures.Metals.AluminiumEuropeanPremiumDutyPaidMetalBulletin
-
-
- Futures.Metals.ALUMINIUM_EUROPEAN_PREMIUM_DUTY_PAID_METAL_BULLETIN
-
- : Aluminium European Premium Duty-Paid (Metal Bulletin) Futures (COMEX: EDP)
-
- Futures.Metals.AluminumMWUSTransactionPremiumPlatts25MT
-
-
- Futures.Metals.ALUMINUM_MWUS_TRANSACTION_PREMIUM_PLATTS_25_MT
-
- : Aluminum MW U.S. Transaction Premium Platts (25MT) Futures (COMEX: AUP)
-
- Futures.Metals.Copper
-
-
- Futures.Metals.COPPER
-
- : Copper Futures (COMEX: HG)
-
- Futures.Metals.Gold
-
-
- Futures.Metals.GOLD
-
- : Gold Futures (COMEX: GC)
-
- Futures.Metals.MicroGold
-
-
- Futures.Metals.MICRO_GOLD
-
- : Micro Gold Futures (COMEX: MGC)
-
- Futures.Metals.MicroGoldTAS
-
-
- Futures.Metals.MICRO_GOLD_TAS
-
- : Micro Gold TAS Futures (COMEX: MGT)
-
- Futures.Metals.MicroPalladium
-
-
- Futures.Metals.MICRO_PALLADIUM
-
- : Micro Palladium Futures (NYMEX: PAM)
-
- Futures.Metals.MicroSilver
-
-
- Futures.Metals.MICRO_SILVER
-
- : Micro Silver Futures (COMEX: SIL)
-
- Futures.Metals.Palladium
-
-
- Futures.Metals.PALLADIUM
-
- : Palladium Futures (NYMEX: PA)
-
- Futures.Metals.Platinum
-
-
- Futures.Metals.PLATINUM
-
- : Platinum Futures (NYMEX: PL)
-
- Futures.Metals.Silver
-
-
- Futures.Metals.SILVER
-
- : Silver Futures (COMEX: SI)
-
- Futures.Metals.USMidwestDomesticHotRolledCoilSteelCRUIndex
-
-
- Futures.Metals.US_MIDWEST_DOMESTIC_HOT_ROLLED_COIL_STEEL_CRU_INDEX
-
- : U.S. Midwest Domestic Hot-Rolled Coil Steel (CRU) Index Futures (NYMEX: HRC)
-
- Futures.Softs.Sugar11
-
-
- Futures.Softs.SUGAR_11
-
- : Sugar #11 Futures ICE (ICE: SB)
-
- Futures.Softs.Sugar11CME
-
-
- Futures.Softs.SUGAR_11_CME
-
- : Sugar #11 Futures CME (NYMEX: YO)
- - The US Futures dataset enables you to accurately design Futures strategies. Examples include the following strategies: -
-- The following example algorithm buys the Mini Gold Futures contract with the greatest open interest and sells the Micro Gold Futures contract with the greatest open interest. When the open interest of a different contract exceeds the open interest of a contract in the portfolio, the algorithm rebalances the portfolio. -
-from AlgorithmImports import *
-
-class USFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(1000000)
- # Setting the continuous contract mapping criteria for both Gold and Micro Gold contracts, since we want to order the highest liquidity contracts
- self.settings.seed_initial_prices = True
- self.gold = self.add_future(Futures.Metals.GOLD,
- extended_market_hours=True,
- data_mapping_mode=DataMappingMode.OPEN_INTEREST,
- data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
- contract_depth_offset=0)
- self.micro_gold = self.add_future(Futures.Metals.MICRO_GOLD,
- extended_market_hours=True,
- data_mapping_mode=DataMappingMode.OPEN_INTEREST,
- data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
- contract_depth_offset=0)
- # The contract multiplier is cached in the Security symbol_properties property from the symbol properties database
- self.gold_multiplier = self.gold.symbol_properties.contract_multiplier
- self.micro_gold_multiplier = self.micro_gold.symbol_properties.contract_multiplier
-
- def on_data(self, slice: Slice) -> None:
- # Make sure to calculate the order size by the most updated price data of both contracts
- if not self.portfolio.invested and self.gold.symbol in slice.bars and self.micro_gold.symbol in slice.bars:
- # Calculate the order size for $500k
- # Get the quotient after dividing the contract multiplier since the order size must be whole number
- gold_quantity = 500000 / slice.bars[self.gold.symbol].close // self.gold_multiplier
- micro_gold_quantity = 500000 / slice.bars[self.micro_gold.symbol].close // self.micro_gold_multiplier
-
- self.market_order(self.gold.mapped, gold_quantity)
- self.market_order(self.micro_gold.mapped, micro_gold_quantity)
-
- def on_securities_changed(self, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- # Historical data
- history = self.history(security.symbol, 10, Resolution.MINUTE)
- self.debug(f"We got {len(history)} from our history request for {security.symbol}")
- public class USFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _gold, _microGold;
- private decimal _goldMulitplier, _microGoldMulitplier;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
- // Setting the continuous contract mapping criteria for both Gold and Micro Gold contracts, since we want to order the highest liquidity contracts
- Settings.SeedInitialPrices = true;
- _gold = AddFuture(Futures.Metals.Gold,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- contractDepthOffset: 0);
- _microGold = AddFuture(Futures.Metals.MicroGold,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
- contractDepthOffset: 0);
- // The contract multiplier is cached in the Security SymbolProperties property from the symbol properties database
- _goldMulitplier = _gold.SymbolProperties.ContractMultiplier;
- _microGoldMulitplier = _microGold.SymbolProperties.ContractMultiplier;
- }
-
- public override void OnData(Slice slice)
- {
- // Make sure to calculate the order size by the most updated price data of both contracts
- if (!Portfolio.Invested && slice.Bars.ContainsKey(_gold.Symbol) && slice.Bars.ContainsKey(_microGold.Symbol))
- {
- // Calculate the order size for $500k
- // Get the quotient after dividing the contract multiplier since the order size must be whole number
- var goldQuantity = Math.Floor(500000m / slice.Bars[_gold.Symbol].Close / _goldMulitplier);
- var microGoldQuantity = Math.Floor(500000m / slice.Bars[_microGold.Symbol].Close / _microGoldMulitplier);
-
- MarketOrder(_gold.Mapped, goldQuantity);
- MarketOrder(_microGold.Mapped, microGoldQuantity);
- }
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- // Historical data
- var history = History(security.Symbol, 100, Resolution.Minute);
- Debug($"We got {history.Count()} from our history request for {security.Symbol}");
- }
- }
-}
- - The following example algorithm buys the front-month Mini Gold Futures contract and sells the front-month Micro Gold Futures contract. When the front-month contract changes, the algorithm rebalances the portfolio. -
-from AlgorithmImports import *
-
-class USFuturesDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
- # Set up an universe selection model that selects the front month contract
- self.set_universe_selection(FrontMonthFutureUniverseSelectionModel())
- self.add_alpha(ConstantFuturesAlphaModel())
- # A portfolio construction model that only order a single share per insight signal
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
- def __init__(self,) -> None:
- # Daily updating with select_future_chain_symbols function
- super().__init__(timedelta(1), self.select_future_chain_symbols)
-
- def select_future_chain_symbols(self, utcTime: datetime) -> List[Symbol]:
- # Select gold and micro gold contracts for the strategy need
- future_pairs = [
- (Futures.Metals.GOLD, Market.COMEX),
- (Futures.Metals.MICRO_GOLD, Market.COMEX)
- ]
- return [Symbol.create(pair[0], SecurityType.FUTURE, pair[1]) for pair in future_pairs]
-
- def filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
- # Filter only front month contract for liquidity and most informed information
- return filter.front_month().only_apply_filter_at_market_open()
-
-class ConstantFuturesAlphaModel(AlphaModel):
- # Long gold and short micro gold in this strategy
- long_symbol = Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
- short_symbol = Symbol.create(Futures.Metals.MICRO_GOLD, SecurityType.FUTURE, Market.COMEX)
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- if algorithm.portfolio.invested:
- return []
-
- insights = []
- # For both gold and micro gold, select the front month contract (only contract) in the chain
- for symbol, contracts in slice.future_chains.items():
- chain = [contract for contract in contracts]
- contract = chain[0]
-
- # Long gold and short micro gold as planned
- if symbol == self.long_symbol:
- insights.append(Insight.price(contract.symbol, contract.expiry + timedelta(days=1), InsightDirection.UP))
- elif symbol == self.short_symbol:
- insights.append(Insight.price(contract.symbol, contract.expiry + timedelta(days=1), InsightDirection.DOWN))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- # Historical data
- history = algorithm.history(security.symbol, 10, Resolution.MINUTE)
- algorithm.debug(f"We got {len(history)} from our history request for {security.symbol}")
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- targets = []
- for insight in insights:
- if algorithm.securities[insight.symbol].is_tradable:
- # Single share only using integer portfolio target
- targets.append(PortfolioTarget(insight.symbol, insight.direction))
- return targets
- public class USFuturesDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
- // Set up an universe selection model that selects the front month contract
- SetUniverseSelection(new FrontMonthFutureUniverseSelectionModel());
- SetAlpha(new ConstantFuturesAlphaModel());
- // A portfolio construction model that only order a single share per insight signal
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-class FrontMonthFutureUniverseSelectionModel : FutureUniverseSelectionModel
-{
- // Daily updating with select_future_chain_symbols function
- public FrontMonthFutureUniverseSelectionModel()
- : base(TimeSpan.FromDays(1), SelectFutureChainSymbols) {}
-
- private static IEnumerable<Symbol> SelectFutureChainSymbols(DateTime utcTime)
- {
- //Select gold and micro gold contracts for the strategy need
- return new List<Symbol> {
- QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX),
- QuantConnect.Symbol.Create(Futures.Metals.MicroGold, SecurityType.Future, Market.COMEX)
- };
- }
-
- protected override FutureFilterUniverse Filter(FutureFilterUniverse filter)
- {
- // Filter only front month contract for liquidity and most informed information
- return filter.FrontMonth().OnlyApplyFilterAtMarketOpen();
- }
-}
-
-
-class ConstantFuturesAlphaModel : AlphaModel
-{
- // Long gold and short micro gold in this strategy
- private Symbol
- _longSymbol = QuantConnect.Symbol.Create(Futures.Metals.Gold, SecurityType.Future, Market.COMEX),
- _shortSymbol = QuantConnect.Symbol.Create(Futures.Metals.MicroGold, SecurityType.Future, Market.COMEX);
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- if (algorithm.Portfolio.Invested)
- {
- return insights;
- }
-
- // For both gold and micro gold, select the front month contract (only contract) in the chain
- foreach (var kvp in slice.FutureChains)
- {
- var symbol = kvp.Key;
- var chain = kvp.Value;
- var contract = chain.First();
-
- // Long gold and short micro gold as planned
- if (symbol == _longSymbol)
- {
- insights.Add(Insight.Price(contract.Symbol, contract.Expiry + TimeSpan.FromDays(1), InsightDirection.Up));
- }
- else if (symbol == _shortSymbol)
- {
- insights.Add(Insight.Price(contract.Symbol, contract.Expiry + TimeSpan.FromDays(1), InsightDirection.Down));
- }
- }
-
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- // Historical data
- var history = algorithm.History(security.Symbol, 100, Resolution.Minute);
- algorithm.Debug($"We got {history.Count()} from our history request for {security.Symbol}");
- }
- }
-}
-
-
-class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- var targets = new List<PortfolioTarget>();
- foreach (var insight in insights)
- {
- if (algorithm.Securities[insight.Symbol].IsTradable)
- {
- // Single share only using integer portfolio target
- targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
- }
- }
- return targets;
- }
-}
-
- The US Futures dataset provides
-
- FuturesChain
-
- ,
-
- Future
-
- , and
-
- OpenInterest
-
- objects. To configure the continuous Future settings, use the
-
- DataNormalizationMode
-
- and
-
- DataMappingMode
-
- enumerations.
-
- The
-
- DataNormalizationMode
-
- enumeration has the following values:
-
- The
-
- DataMappingMode
-
- enumeration has the following values:
-
-
- Future
-
- objects have the following attributes:
-
-
- FuturesChain
-
- objects have the following attributes:
-
-
- OpenInterest
-
- objects have the following attributes:
-
- -
- The US Index Options dataset by AlgoSeek provides Option data, including prices, strikes, expires, and open interest. The data covers European Option contracts for 3 US Indices: SPX, VIX, and NDX. It starts from January 2012 and is delivered on minute resolution. This dataset is created by monitoring the Options Price Reporting Authority (OPRA) data feed, which consolidates last sale and quotation information originating from the national securities exchanges that have been approved by the Securities and Exchange Commission. -
-- The US Index Options dataset depends on the - - US Index Option Universe - - dataset because the US Index Options Universe dataset contains information on the available contracts, including their daily Greeks and implied volatility values. -
-- For more information about the US Index Options dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit - - algoseek.com - - . -
- - - -- The following snippet demonstrates how to request data from the US Index Options dataset: -
-self.index_symbol = self.add_index('VIX').symbol
-option = self.add_index_option(self.index_symbol)
-option.set_filter(-2, 2, 0, 90)
-self.option_symbol = option.symbol
- _indexSymbol = AddIndex("VIX").Symbol;
-var option = AddIndexOption(_indexSymbol);
-option.SetFilter(-2, 2, 0, 90);
-_optionSymbol = option.Symbol;
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 2012 - | -
| - Asset Coverage - | -- 7 Index Options - | -
| - Data Density - | -- Regular - | -
| - Resolution - | -- Minute, Hourly, & Daily - | -
| - Timezone - | -- New York - | -
| - Market Hours - | -- - Regular Only - - | -
- According to the SPX Options - - contract specification - - , some SPX contracts expire every month and SPXW contracts expires every day. Before 2021, you could only trade SPX contracts with the following expiration dates: -
-- During this time, SPXW didn't have 0DTE every day. -
-
-
- Sources
-
- :
-
- -
-
- Cboe Options Exchange to List Three Long-Dated SPX Options Expirations, Beginning November 1, 2021
-
-
- -
-
- S&P 500 Weekly Options Now Expire Five Days a Week
-
-
- To add US Index Options data to your algorithm, call the
-
- AddIndexOption
-
-
- add_index_option
-
- method. Save a reference to the Index Option
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class IndexOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2021, 1, 1);
- self.set_end_date(2021, 6, 1);
- self.set_cash(1000000);
- self.universe_settings.asynchronous = True
- self.index_symbol = self.add_index('VIX').symbol
-
- standard_option = self.add_index_option(self.index_symbol)
- standard_option.set_filter(-2, 2, 0, 90)
- self.standard_option_symbol = standard_option.symbol
-
- weekly_option = self.add_index_option(self.index_symbol, "VIXW")
- weekly_option.set_filter(-2, 2, 0, 90)
- self.weekly_option_symbol = weekly_option.symbol
- public class IndexOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _indexSymbol, _standardOptionSymbol, _weeklyOptionSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2021, 1, 1);
- SetEndDate(2021, 6, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
- _indexSymbol = AddIndex("VIX").Symbol;
-
- var standardOption = AddIndexOption(_indexSymbol);
- standardOption.SetFilter(-2, 2, 0, 90);
- _standardOptionSymbol = standardOption.Symbol;
-
- var weeklyOption = AddIndexOption(_indexSymbol, "VIXW");
- weeklyOption.SetFilter(-2, 2, 0, 90);
- _weeklyOptionSymbol = weeklyOption.Symbol;
- }
-}
- - The Index resolution must be less than or equal to the Index Option resolution. For example, if you set the Index resolution to minute, then you must set the Index Option resolution to minute, hour, or daily. -
-- For more information about creating US Index Option subscriptions, see - - Requesting Data - - or - - Index Options Universes - - . -
- - - -
- To get the current US Index Options data, index the
-
- OptionChains
-
-
- option_chains
-
- property of the current
-
-
- Slice
-
-
- with the canonical Index Option
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your Index Option at every time step.
-
def on_data(self, slice: Slice) -> None:
- standard_chain = slice.option_chains.get(self.standard_option_symbol)
- if standard_chain:
- for contract in standard_chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
-
- weekly_chain = slice.option_chains.get(self.weekly_option_symbol)
- if weekly_chain:
- for contract in weekly_chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
- public override void OnData(Slice slice)
-{
- if (slice.OptionChains.ContainsKey(_standardOptionSymbol))
- {
- var standardChain = slice.OptionChains[_standardOptionSymbol];
- foreach (var contract in standardChain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-
- if (slice.OptionChains.ContainsKey(_weeklyOptionSymbol))
- {
- var weeklyChain = slice.OptionChains[_weeklyOptionSymbol];
- foreach (var contract in weeklyChain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
-
- You can also iterate through all of the
-
- OptionChain
-
- objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- for canonical_symbol, chain in slice.option_chains.items():
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
-
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.OptionChains)
- {
- var canonicalSymbol = kvp.Key;
- var chain = kvp.Value;
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
- - For more information about accessing US Index Options data, see - - Handling Data - - . -
- - - -- You can get historical US Index Options data in an algorithm and the Research Environment. -
-
- To get historical US Index Options data in an algorithm, call the
-
- History
-
-
- history
-
- method with the Index Option contract
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame of trade and quote data -history_df = self.history(contract.symbol, 100, Resolution.MINUTE) - -# DataFrame of open interest data -history_oi_df = self.history(OpenInterest, contract.symbol, 100, Resolution.MINUTE) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE) - -# OpenInterest objects -history_oi = self.history[OpenInterest](contract.symbol, 100, Resolution.MINUTE)-
// TradeBar objects -var historyTradeBars = History(contract.Symbol, 100, Resolution.Minute); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(contract.Symbol, 100, Resolution.Minute); - -// OpenInterest objects -var historyOpenInterest = History<OpenInterest>(contract.Symbol, 100, Resolution.Minute);-
- For more information about historical data in algorithms, see - - History Requests - - . -
-
- To get historical US Index Options data in the Research Environment, call the
-
- History
-
-
- history
-
- or
-
- OptionHistory
-
-
- option_history
-
- method. The
-
- History
-
-
- history
-
- method returns the price, volume, and open interest history for some given Option contract(s). The
-
- OptionHistory
-
-
- option_history
-
- method returns the price and volume history for the contracts that pass your daily universe filter.
-
qb = QuantBook()
-index_symbol = qb.add_index('VIX').symbol
-option = qb.add_index_option(index_symbol) # or qb.add_index_option(index_symbol, "VIXW")
-option.set_filter(-2, 2, 0, 90)
-history = qb.option_history(option.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5))
-history_df = history.data_frame
-expiries = history.get_expiry_dates()
-strikes = history.get_strikes()
- var qb = new QuantBook();
-var indexSymbol = qb.AddIndex("VIX").Symbol;
-var option = qb.AddIndexOption(indexSymbol); // or qb.AddIndexOption(indexSymbol, "VIXW");
-option.SetFilter(-2, 2, 0, 90);
-var history = qb.OptionHistory(option.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 5));
-
-var contracts = history
- .SelectMany(x => x.OptionChains.SelectMany(y => y.Value.Contracts.Keys))
- .Distinct().ToList();
-var expiries = contracts.Select(x => x.ID.Date).Distinct().ToList();
-var strikes = contracts.Select(x => x.ID.StrikePrice).Distinct().ToList();
-
- To get historical data for arbitrary US Index Option contracts instead of just the that pass your universe filter, call the
-
- History
-
-
- history
-
- method like you would in an algorithm, but on the
-
- QuantBook
-
- object. For more information about historical data in the Research Environment, see
-
- Key Concepts
-
- .
-
- To get historical data for the Greeks and implied volatility of Index Options, see the - - US Index Option Universe - - dataset. -
- - - -- The following table shows the available Index Options: -
-| - Underlying Index - | -- Underlying Ticker - | -- Target Ticker - | -- Standard Contracts - | -- Weekly Contracts - | -- Tradable on Expiry Day - | -
|---|---|---|---|---|---|
| - NASDAQ-100 - | -- NDX - | -- | -
- |
- - | -- | -
| - NASDAQ-100 - | -- NDX - | -- NDXP - | -
- |
- - | -
- |
-
| - NASDAQ-100 - | -- NDX - | -- NQX - | -
- |
-
- |
-
- |
-
| - Russell 2000 - | -- RUT - | -- | -
- |
- - | -- | -
| - Russell 2000 - | -- RUT - | -- RUTW - | -- | -
- |
-
- |
-
| - S&P500 - | -- SPX - | -- | -
- |
- - | -- | -
| - S&P500 - | -- SPX - | -- SPXW - | -- | -
- |
-
- |
-
| - S&P500 - | -- VIX - | -- | -
- |
- - | -- | -
| - S&P500 - | -- VIX - | -- VIXW - | -- | -
- |
- - | -
- For more information about each underlying Index, see - - Supported Indices - - . -
- - - -- The US Index Options dataset enables you to accurately design strategies for Index Options. Examples include the following strategies: -
-- The following example algorithm buys the VIX Index Option Bull Call Spread with the furthest expiration: -
-from AlgorithmImports import *
-
-class IndexOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(200000)
- # Asynchronous can use computational resources efficiently
- self.universe_settings.asynchronous = True
- # Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
- option = self.add_index_option("SPX")
- option.set_filter(lambda u: u.calls_only().strikes(-2, +2).expiration(0, 180))
- self.option_symbol = option.symbol
-
- def on_data(self, slice: Slice) -> None:
- if not self.portfolio.invested and self.is_market_open(self.option_symbol):
- # Make sure getting the updated VIX option chain
- chain = slice.option_chains.get(self.option_symbol)
- if chain:
- expiry = max([c.expiry for c in chain])
- call_contracts = sorted([c for c in chain if c.expiry == expiry],
- key=lambda c: c.strike)
-
- # Need 2 contracts to form a call spread
- if len(call_contracts) < 2:
- return
-
- # Obtain 2 call contracts with different strike price to form the call spread
- longCall, shortCall = call_contracts[0:2]
-
- # Use all the buying power, but need to ensure the order size of the long and short call are the same
- quantity = min([
- abs(self.calculate_order_quantity(shortCall.symbol, -1)),
- abs(self.calculate_order_quantity(longCall.symbol, 1))])
- if not quantity:
- return
-
- # Bull call spread consists of long a lower-strike call and short a higher-strike call
- self.market_order(shortCall.symbol, -quantity)
- self.market_order(longCall.symbol, quantity)
-
- expected_margin_usage = max((longCall.strike - shortCall.strike) * self.securities[longCall.symbol].symbol_properties.contract_multiplier * quantity, 0)
- if expected_margin_usage != self.portfolio.total_margin_used:
- raise Exception("Unexpect margin used!")
-
-
- def on_securities_changed(self, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- if security.type == SecurityType.INDEX_OPTION:
- # Historical data
- history = self.history(security.symbol, 10, Resolution.MINUTE)
- public class IndexOptionsDataAlgorithm : QCAlgorithm
-{
- private Symbol _optionSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(200000);
- // Asynchronous can use computational resources efficiently
- UniverseSettings.Asynchronous = true;
- // Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
- var option = AddIndexOption("SPX");
- option.SetFilter((u) => u.CallsOnly().Strikes(-2, +2).Expiration(0, 180));
- _optionSymbol = option.Symbol;
- }
-
- public override void OnData(Slice slice)
- {
- if (!Portfolio.Invested && IsMarketOpen(_optionSymbol))
- {
- // Make sure getting the updated VIX option chain
- if (slice.OptionChains.TryGetValue(_optionSymbol, out var chain))
- {
- var expiry = chain.Max(x => x.Expiry);
- var callContracts = chain
- .Where(x => x.Expiry == expiry)
- .OrderBy(x => x.Strike)
- .ToList();
-
- // Need 2 contracts to form a call spread
- if (callContracts.Count < 2)
- {
- return;
- }
-
- // Obtain 2 call contracts with different strike price to form the call spread
- var longCall = callContracts.First();
- var shortCall = callContracts.First(contract => contract.Strike > longCall.Strike);
-
- // Use all the buying power, but need to ensure the order size of the long and short call are the same
- var quantity = new[] {
- CalculateOrderQuantity(shortCall.Symbol, -1m),
- CalculateOrderQuantity(longCall.Symbol, 1m) }
- .Min(x=> Math.Abs(x));
- if (quantity == 0) return;
-
- // Bull call spread consists of long a lower-strike call and short a higher-strike call
- MarketOrder(shortCall.Symbol, -quantity);
- MarketOrder(longCall.Symbol, quantity);
-
- var expectedMarginUsage = Math.Max((longCall.Strike - shortCall.Strike) * Securities[longCall.Symbol].SymbolProperties.ContractMultiplier * quantity, 0);
- if (expectedMarginUsage != Portfolio.TotalMarginUsed)
- {
- throw new Exception("Unexpect margin used!");
- }
- }
- }
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- if (security.Type == SecurityType.IndexOption)
- {
- // Historical data
- var history = History(security.Symbol, 10, Resolution.Minute);
- }
- }
- }
-}
- - The following example algorithm buys the VIX Index Option Bull Call Spread with the furthest expiration: -
-from AlgorithmImports import *
-
-class IndexOptionsDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(200000)
- self.universe_settings.asynchronous = True
- self.set_universe_selection(VIXIndexOptionUniverseSelectionModel())
-
- self.set_alpha(BullCallSpreadAlphaModel())
-
- self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
-
-
-class VIXIndexOptionUniverseSelectionModel(OptionUniverseSelectionModel):
-
- def __init__(self):
- super().__init__(timedelta(1), self.option_chain_symbol_selector)
-
- def option_chain_symbol_selector(self, utc_time: datetime) -> List[Symbol]:
- # Only interest in VIX options
- return [Symbol.create("VIX", SecurityType.INDEX_OPTION, Market.USA)]
-
- def filter(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
- # Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
- return option_filter_universe.calls_only().strikes(-2, +2).expiration(0, 180)
-
-
-class BullCallSpreadAlphaModel(AlphaModel):
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- if algorithm.portfolio.invested:
- return []
-
- for canonical_symbol, chain in slice.option_chains.items():
- if not chain:
- return []
- # Bull call spread legs are having the same expiry
- expiry = max([c.expiry for c in chain])
- call_contracts = sorted([c for c in chain if c.expiry == expiry],
- key=lambda c: c.strike)
-
- # Need 2 contracts to form a call spread
- if len(call_contracts) < 2:
- return []
-
- # Obtain 2 call contracts with different strike price to form the call spread
- long_call, short_call = call_contracts[0:2]
-
- # Bull call spread consists of long a lower-strike call and short a higher-strike call
- return Insight.group(
- [
- Insight.price(long_call.symbol, expiry + timedelta(1), InsightDirection.UP),
- Insight.price(short_call.symbol, expiry + timedelta(1), InsightDirection.DOWN)
- ])
- return []
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- if security.type == SecurityType.INDEX_OPTION:
- # Historical data
- history = algorithm.history(security.symbol, 10, Resolution.MINUTE)
-
-
-class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
-
- def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
- if not insights:
- return []
- # Only a single contract toi ensure both legs size is equal
- quantity = min([abs(algorithm.calculate_order_quantity(i.symbol, int(i.direction)))
- for i in insights])
-
- return [PortfolioTarget(i.symbol, quantity * int(i.direction))
- for i in insights]
- public class IndexOptionsDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(200000);
- UniverseSettings.Asynchronous = true;
- SetUniverseSelection(new VIXIndexOptionUniverseSelectionModel());
-
- SetAlpha(new BullCallSpreadAlphaModel());
-
- SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
- }
-}
-
-public class VIXIndexOptionUniverseSelectionModel : OptionUniverseSelectionModel
-{
- // Only interest in VIX options
- public VIXIndexOptionUniverseSelectionModel()
- : base(TimeSpan.FromDays(1),
- _ => new[] {QuantConnect.Symbol.Create("VIX", SecurityType.IndexOption, Market.USA)})
- {
- }
-
- protected override OptionFilterUniverse Filter(OptionFilterUniverse optionFilterUniverse)
- {
- // Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
- return optionFilterUniverse.CallsOnly().Strikes(-2, +2).Expiration(0, 180);
- }
-}
-
-public class BullCallSpreadAlphaModel : AlphaModel
-{
- public BullCallSpreadAlphaModel()
- {
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = Enumerable.Empty<Insight>();
- if (algorithm.Portfolio.Invested)
- {
- return insights;
- }
-
- foreach (var kvp in slice.OptionChains)
- {
- var canoncialSymbol = kvp.Key;
- var chain = kvp.Value;
- if (chain.IsNullOrEmpty())
- {
- return insights;
- }
- // Bull call spread legs are having the same expiry
- var expiry = chain.Max(contract => contract.Expiry);
- var callContracts = chain
- .Where(contract => contract.Expiry == expiry)
- .OrderBy(x => x.Strike)
- .ToList();
-
- // Need 2 contracts to form a call spread
- if (callContracts.Count < 2)
- {
- return insights;
- }
-
- // Obtain 2 call contracts with different strike price to form the call spread
- var longCall = callContracts.First();
- var shortCall = callContracts.First(contract => contract.Strike > longCall.Strike);
-
- // Bull call spread consists of long a lower-strike call and short a higher-strike call
- return Insight.Group(
- Insight.Price(longCall.Symbol, expiry.AddDays(1), InsightDirection.Up),
- Insight.Price(shortCall.Symbol, expiry.AddDays(1), InsightDirection.Down));
- }
- return insights;
- }
-}
-
-public class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
-{
- public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
- {
- if (insights.Count() == 0)
- {
- return Enumerable.Empty<PortfolioTarget>();
- }
- // Only a single contract toi ensure both legs size is equal
- var quantity = insights
- .Select(i => Math.Abs(algorithm.CalculateOrderQuantity(i.Symbol, (decimal)i.Direction)))
- .Min();
-
- return insights.Select(i => new PortfolioTarget(i.Symbol, quantity * (decimal)i.Direction));
- }
-}
-
- The US Index Options dataset provides
-
- TradeBar
-
- ,
-
- QuoteBar
-
- , and
-
- OpenInterest
-
- objects.
-
-
- TradeBar
-
- objects have the following attributes:
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- OpenInterest
-
- objects have the following attributes:
-
- -
- Morningstar was founded by Joe Mansueto in 1984 with the goal of empowering investors by connecting people to the investing information and tools they need. Morningstar provides access extensive line of products and services for individual investors, financial advisors, asset managers, and retirement plan providers. Morningstar provides data on approximately 525,000 investment offerings including stocks, mutual funds, and similar vehicles, along with real-time global market data on nearly 18 million equities, indexes, futures, options, commodities, and precious metals, in addition to foreign exchange and Treasury markets. Morningstar also offers investment management services through its investment advisory subsidiaries, with $244 billion in assets under advisement or management as of 2021. -
-- -
- The US Fundamental Data by Morningstar tracks US Equity fundamentals. The data covers 8,000 US Equities, starts in January 1998, and is delivered on a daily frequency. The data does not include ETFs, ADRs, or OTC equities. This dataset is created by using a combination of string matching, Regular Expressions, and Machine Learning to gather the fundamental data published by companies. -
-- For older symbols, the file date is approximated 45 days after the as of date. When a filing date is present on the Morningstar data, it is used. As we are a quant platform, all the data is loaded using "As Original Reported" figures. If there was a mistake reporting the figure, this will not be fixed later. The market typically responds quickly to these initially reported figures. Data is available for multiple periods depending on the property. Periods available include: 1 mo, 2 mo, 3 mo, 6 mo, 9 mo, 12 mo, 1 Yr, 2 Yr, 3 Yr, and 5 Yr. Morningstar symbols cover the NYSE, NASDAQ, AMEX, and BATS exchanges. -
-- In live trading, Morningstar data is delivered to your algorithm at approximately 6 am each day. The majority of the fundamental data update occurs once per month. This includes updates to all of the key information for each security Morningstar supports. On top of this monthly update, there are daily updates of the financial ratios. -
-- As Morningstar data arrives, it updates the master copy and is passed into your algorithm, similar to how TradeBars are fill-forwarded in your data feed. If there have been no updates for a day, you'll receive the same fundamental data. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- QuantConnect/LEAN combines the data of this dataset with - - US Coarse Universe - - data in runtime. -
-- For more information about the US Fundamental Data dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- Morningstar was founded by Joe Mansueto in 1984 with the goal of empowering investors by connecting people to the investing information and tools they need. Morningstar provides access extensive line of products and services for individual investors, financial advisors, asset managers, and retirement plan providers. Morningstar provides data on approximately 525,000 investment offerings including stocks, mutual funds, and similar vehicles, along with real-time global market data on nearly 18 million equities, indexes, futures, options, commodities, and precious metals, in addition to foreign exchange and Treasury markets. Morningstar also offers investment management services through its investment advisory subsidiaries, with $244 billion in assets under advisement or management as of 2021. -
- - - -- The following snippets demonstrate how to request data from the US Fundamental dataset: -
-equity = self.add_equity("IBM")
-ibm_fundamental = equity.fundamentals
- var equity = AddEquity("IBM");
-var ibmFundamental = equity.Fundamentals;
- ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-ibm_fundamental = self.fundamentals(ibm)
- var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-var ibmFundamental = Fundamentals(ibm);
- def initialize(self) -> None: - self._universe = self.add_universe(self.fundamental_filter_function) - -def fundamental_filter_function(self, fundamental: List[Fundamental]): - filtered = [f for f in fundamental if f.has_fundamental_data and f.price > 10 and not np.isnan(f.valuation_ratios.pe_ratio)] - sorted_by_pe_ratio = sorted(filtered, key=lambda f: f.valuation_ratios.pe_ratio) - return [f.symbol for f in sorted_by_pe_ratio[:10]]-
public override void Initialize()
-{
- _universe = AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
-}
-
-public override List<Symbol> FundamentalFilterFunction(List<Fundamental> fundamental)
-{
- return (from f in fundamental
- where f.HasFundamentalData && f.Price > 10 && !Double.IsNaN(f.ValuationRatios.PERatio)
- orderby f.ValuationRatios.PERatio
- select f.Symbol).Take(10);
-}
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- January 1998 - | -
| - Asset Coverage - | -- 8,000 US Equities - - * - - | -
| - Corporate Indicators / Tracked Fields - | -- 900 Fields - | -
| - Data Density - | -- Sparse - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- New York - | -
- You don't need any special code to request US Fundamental Data. You can access the current and historical fundamental data for any of the US Equities that this dataset includes. -
-class MorningStarDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2021, 1, 1)
- self.set_end_date(2021, 7, 1)
- self.set_cash(100000)
- self.universe_settings.asynchronous = True
-
- # Option 1: Subscribe to individual US Equity assets
- self.add_equity("IBM")
-
- # Option 2A: Create a fundamental universe (classic version)
- self._universe = self.add_universe(self.fundamental_function)
-
- # Option 2B: Create a fundamental universe (framework version)
- self.add_universe_selection(FundamentalUniverseSelectionModel(self.fundamental_function))
- public class MorningStarDataAlgorithm : QCAlgorithm
-{
- private Universe _universe;
-
- public override void Initialize()
- {
- SetStartDate(2021, 1, 1);
- SetEndDate(2021, 7, 1);
- SetCash(100000);
- UniverseSettings.Asynchronous = true;
-
- // Option 1: Subscribe to individual US Equity assets
- AddEquity("IBM");
-
- // Option 2A: Create a fundamental universe (classic version)
- _universe = AddUniverse(FundamentalFilterFunction);
-
- // Option 2B: Create a fundamental universe (framework version)
- AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
- }
-}
- - For more information about universe settings, see - - Settings - - . -
- - - -- If you add a - - fundamental universe - - to your algorithm, you can access fundamental data in the universe selection function. -
-def fundamental_function(self, fundamental: List[Fundamental]) -> List[Symbol]: - return [f.symbol for f in fundamental if f.price > 10 and f.valuation_ratios.pe_ratio > 30]-
public IEnumerable<Symbol> FundamentalFunction(IEnumerable<Fundamental> fundamental)
-{
- return fundamental.Where(f => f.Price > 10 && f.ValuationRatios.PERatios > 30).Select(f => f.Symbol);
-}
-
- To get fundamental data for Equities in your algorithm, use the
-
- Fundamentals
-
-
- fundamentals
-
- property of the
-
- Equity
-
- objects. The fundamental data represent the corporate fundamentals for the current algorithm time.
-
fundamentals = self.securities[symbol].fundamentals-
var fundamentals = Securities[symbol].Fundamentals;-
- To get fundamental data for Equities, regardless of whether or not you have subscribed to them in your algorithm, call the
-
- Fundamentals
-
-
- fundamentals
-
- method. If you pass one
-
- Symbol
-
- , the method returns a
-
- Fundamental
-
- object. If you pass a list of
-
- Symbol
-
- objects, the method returns a list of
-
- Fundamental
-
- objects.
-
// Single asset
-var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-var ibmFundamental = Fundamentals(ibm);
-
-// Multiple assets
-var nb = QuantConnect.Symbol.Create("NB", SecurityType.Equity, Market.USA);
-var fundamentals = Fundamentals(new List<Symbol>{ nb, ibm }).ToList();
- # Single asset
-ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-ibm_fundamental = self.fundamentals(ibm)
-
-# Multiple assets
-nb = Symbol.create("NB", SecurityType.EQUITY, Market.USA)
-fundamentals = self.fundamentals([ nb, ibm ])
- - You can get historical fundamental data in an algorithm and in the Research Environment. -
-
- To get historical fundamental data in an algorithm, call the
-
- History
-
-
- history
-
- method with
-
- Fundamental
-
- type and the Equity
-
- Symbol
-
- or the
-
- Universe
-
- object. If there is no data in the period you request, the history result is empty.
-
var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
-
-// Fundamental objects
-var fundamentalHistory = History<Fundamental>(ibm, TimeSpan.FromDays(30));
-
-// Fundamentals objects for all US Equities (including delisted companies)
-var fundamentalsHistory = History<Fundamentals>(TimeSpan.FromDays(30));
-
-// Collection of Fundamental objects for all US Equities (including delisted companies)
-var collectionHistory = History(_universe, 30, Resolution.Daily);
-foreach (var fundamental in collectionHistory)
-{
- // Cast to Fundamental is required
- var highestMarketCap = fundamental.OfType<Fundamental>().OrderByDescending(x => x.MarketCap).Take(5);
-}
- ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
-
-# DataFrame object where the columns are the Fundamental attributes
-asset_df_history = self.history(Fundamental, ibm, timedelta(30), flatten=True)
-
-# Fundamental objects
-fundamental_history= self.history[Fundamental](ibm, timedelta(30))
-
-# Fundamentals objects for all US Equities (including delisted companies)
-fundamentals_history = self.history[Fundamentals](timedelta(30))
-
-# Multi-index Series objects where the values are lists of Fundamental objects
-series_history = self.history(self.universe, 30, Resolution.DAILY)
-for (universe_symbol, time), fundamentals in series_history.items():
- highest_market_cap = sorted(fundamentals, key=lambda x: x.market_cap)[-5:]
-
- To get historical data in the Research Environment, call any of the preceding methods or call the
-
- UniverseHistory
-
-
- universe_history
-
- method with the
-
- Universe
-
- object, a start date, and an end date. This method returns the filtered universe. Alternatively, call the
-
- GetFundamental
-
-
- get_fundamental
-
- method with the Equity
-
- Symbol
-
- , a
-
- Fundamental
-
- property, a start date, and an end date. If there is no data in the period you request, the history result is empty.
-
# DataFrame object where the columns are the Fundamental attributes
-universe_history_df = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
-
-# Multi-index Series objects where the values are lists of Fundamental objects
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), fundamentals in universe_history.items():
- for fundamental in fundamentals:
- print(f"{fundamental.symbol} market cap at {fundamental.end_time}: {fundamental.market_cap}")
-
-# DataFrame of a single Fundamental attribute
-history = qb.get_fundamental(symbol, "ValuationRatios.pe_ratios", datetime(2021, 1, 1), datetime(2021, 7, 1))
- var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var fundamentals in universeHistory)
-{
- foreach (Fundamental fundamental in fundamentals)
- {
- Console.WriteLine($"{fundamental.Symbol} market cap at {fundamental.EndTime}: {fundamental.MarketCap}");
- }
-}
-
-var history = qb.GetFundamental(symbol, "ValuationRatios.PERatios", new DateTime(2021, 1, 1), new DateTime(2021, 7, 1));
- - For more information about historical US Equity fundamental data, see - - Equity Fundamental Data - - . -
- - - -- The US Fundamentals dataset enables you to design strategies harnessing fundamental data points. Examples include the following strategies: -
-- The following example algorithm creates a dynamic universe of US Equities. The first stage filter selects the 100 most liquid US Equities and the second stage filter selects the 10 assets with the greatest PE ratio. The algorithm then forms an equal-weighted portfolio with the 10 assets in the universe. -
-from AlgorithmImports import * - -class MorningStarDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - self.set_cash(100000) - # Seed the price of each asset with its last known price to avoid trading errors. - self.settings.seed_initial_prices = True - self.universe_settings.resolution = Resolution.DAILY - self.universe_size = 10 - # Add universe selection to filter with fundamental data - self.add_universe(self.fundamental_selection_function) - - def fundamental_selection_function(self, fundamental: List[Fundamental]) -> List[Symbol]: - # Make sure fundamental data and PE ratio available - # To avoid penny stocks with high volatility, set price above $1 - selected = [f for f in fundamental if f.has_fundamental_data and f.price > 1 and not np.isnan(f.valuation_ratios.pe_ratio)] - # Filter the top 100 high dollar volume equities to ensure liquidity - sorted_by_dollar_volume = sorted(selected, key=lambda f: f.dollar_volume, reverse=True)[:100] - # Get the top 10 PE Ratio stocks to follow speculations of a large number of capital - sorted_by_pe_ratio = sorted(sorted_by_dollar_volume, key=lambda f: f.valuation_ratios.pe_ratio, reverse=True)[:self.universe_size] - return [ f.symbol for f in sorted_by_pe_ratio ] - - - def on_data(self, slice: Slice) -> None: - # if we have no changes, do nothing - if self._changes is None or not slice.bars: return - - # liquidate removed securities, as not being the most popular stocks anymore - for security in self._changes.removed_securities: - if security.invested: - self.liquidate(security.symbol) - - # we want 1/N allocation in each security in our universe to evenly dissipate risk - for security in self._changes.added_securities: - self.set_holdings(security.symbol, 1 / self.universe_size) - - self._changes = None - - def on_securities_changed(self, changes: SecurityChanges) -> None: - self._changes = changes --
public class MorningStarDataAlgorithm : QCAlgorithm
-{
- private int _universeSize = 10;
- private SecurityChanges _changes = SecurityChanges.None;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Seed the price of each asset with its last known price to avoid trading errors.
- Settings.SeedInitialPrices = true;
- // Requesting data
- UniverseSettings.Resolution = Resolution.Daily;
- // Add universe selection to filter with fundamental data
- AddUniverse(FundamentalSelectionFunction);
- }
-
- public IEnumerable<Symbol> FundamentalSelectionFunction(IEnumerable<Fundamental> fundamental)
- {
- // Make sure fundamental data and PE ratio available
- // To avoid penny stocks with high volatility, set price above $1
- // Filter the top 100 high dollar volume equities to ensure liquidity
- // Get the top 10 PE Ratio stocks to follow speculations of a large number of capital
- return fundamental
- .Where(x => x.HasFundamentalData && x.Price > 1 && !Double.IsNaN(x.ValuationRatios.PERatio))
- .OrderByDescending(x => x.DollarVolume)
- .Take(100)
- .OrderByDescending(x => x.ValuationRatios.PERatio)
- .Take(_universeSize)
- .Select(x => x.Symbol);
- }
-
- public override void OnData(Slice slice)
- {
- // if we have no changes, do nothing
- if (_changes == SecurityChanges.None || slice.Bars.Count == 0) return;
-
- // liquidate removed securities, as not being the most popular stocks anymore
- foreach (var security in _changes.RemovedSecurities)
- {
- if (security.Invested)
- {
- Liquidate(security.Symbol);
- }
- }
-
- // we want 1/N allocation in each security in our universe to evenly dissipate risk
- foreach (var security in _changes.AddedSecurities)
- {
- SetHoldings(security.Symbol, 1m / _universeSize);
- }
-
- _changes = SecurityChanges.None;
- }
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- _changes = changes;
- }
-}
- - The following example algorithm creates a dynamic universe of US Equities. The first stage filter selects the 100 most liquid US Equities and the second stage filter selects the 10 assets with the greatest PE ratio. The algorithm then forms an equal-weighted portfolio with the 10 assets in the universe. -
-from AlgorithmImports import * - -class MorningStarDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2024, 9, 1) - self.set_end_date(2024, 12, 31) - self.set_cash(100000) - - # Add universe selection to filter with fundamental data - self.universe_settings.resolution = Resolution.DAILY - self.set_universe_selection(CustomFundamentalUniverseSelectionModel()) - - self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1))) - - # we want 1/N allocation in each security in our universe to evenly dissipate risk - self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel()) - - self.add_risk_management(NullRiskManagementModel()) - - self.set_execution(ImmediateExecutionModel()) - - -class CustomFundamentalUniverseSelectionModel(FundamentalUniverseSelectionModel): - - def select(self, algorithm: QCAlgorithm, fundamental: List[Fundamental]) -> List[Symbol]: - # Make sure fundamental data and PE ratio available - # To avoid penny stocks with high volatility, set price above $1 - # Filter the top 100 high dollar volume equities to ensure liquidity - sorted_by_dollar_volume = sorted([x for x in fundamental if x.price > 1 and not np.isnan(x.valuation_ratios.pe_ratio)], - key=lambda x: x.dollar_volume, reverse=True)[:100] - # Get the top 10 PE Ratio stocks to follow speculations of a large number of capital - sorted_by_pe_ratio = sorted(sorted_by_dollar_volume, key=lambda x: x.valuation_ratios.pe_ratio, reverse=True)[:10] - - # Take the top entries from our sorted collection - return [ x.symbol for x in sorted_by_pe_ratio ]-
public class MorningStarDataAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
-
- // Add universe selection to filter with fundamental data
- UniverseSettings.Resolution = Resolution.Daily;
- AddUniverseSelection(new CustomFundamentalUniverseSelectionModel());
-
- SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(1)));
-
- // we want 1/N allocation in each security in our universe to evenly dissipate risk
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
-
- AddRiskManagement(new NullRiskManagementModel());
-
- SetExecution(new ImmediateExecutionModel());
- }
-}
-
-public class CustomFundamentalUniverseSelectionModel : FundamentalUniverseSelectionModel
-{
- public override IEnumerable<Symbol> Select(QCAlgorithm algorithm, IEnumerable<Fundamental> fundamental)
- {
- return fundamental
- // Make sure fundamental data and PE ratio available
- // To avoid penny stocks with high volatility, set price above $1
- .Where(x => x.HasFundamentalData && x.Price > 1 && !Double.IsNaN(x.ValuationRatios.PERatio))
- // Filter the top 100 high dollar volume equities to ensure liquidity
- .OrderByDescending(x => x.DollarVolume)
- .Take(100)
- // Get the top 10 PE Ratio stocks to follow speculations of a large number of capital
- .OrderByDescending(x => x.ValuationRatios.PERatio)
- .Take(10)
- .Select(x => x.Symbol);
- }
-}
- - The following example selects the 100 most liquid US Equities and lists the 10 assets with the greatest PE ratio.: -
-var qb = new QuantBook();
-
-// Add Fundamental Universe Selection
-IEnumerable<Symbol> FundamentalSelectionFunction(IEnumerable<Fundamental> fundamentals)
-{
- return fundamentals
- .Where(x => !Double.IsNaN(x.ValuationRatios.PERatio))
- .OrderByDescending(x => x.DollarVolume).Take(100)
- .OrderByDescending(x => x.ValuationRatios.PERatio).Take(10)
- .Select(x => x.Symbol);
-}
-
-var universe = qb.AddUniverse(FundamentalSelectionFunction);
-
-// Historical Universe data
-var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var fundamentals in universeHistory)
-{
- foreach (Fundamental fundamental in fundamentals)
- {
- Console.WriteLine($"{fundamental.Symbol} PE ratio at {fundamental.EndTime}: {fundamental.ValuationRatios.PERatio}");
- }
-}
- qb = QuantBook()
-
-# Add Fundamental Universe Selection
-def fundamental_selection_function(fundamentals):
- selected = [f for f in fundamentals if not np.isnan(f.valuation_ratios.pe_ratio)]
- sorted_by_dollar_volume = sorted(selected, key=lambda f: f.dollar_volume, reverse=True)[:100]
-
- sorted_by_pe_ratio = sorted(sorted_by_dollar_volume,
- key=lambda f: f.valuation_ratios.pe_ratio, reverse=True)[:10]
- return [ f.symbol for f in sorted_by_pe_ratio ]
-
-universe = qb.add_universe(fundamental_selection_function)
-
-# Historical Universe data
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (universe_symbol, time), fundamentals in universe_history.items():
- for fundamental in fundamentals:
- print(f"{fundamental.symbol} PE ratio volume at {fundamental.end_time}: {fundamental.valuation_ratios.pe_ratio}")
-
- The US Fundamentals dataset provides
-
- Fundamental
-
- objects. To filter
-
- Fundamental
-
- objects, you can use the
-
- MorningstarSectorCode
-
- ,
-
- MorningstarIndustryGroupCode
-
- , and
-
- MorningstarIndustryCode
-
- enumeration values.
-
-
- Fundamental
-
- objects have the following attributes:
-
- Sectors are large super categories of data. To access the sector of an Equity, use the
-
- MorningstarSectorCode
-
- property.
-
filteredFundamentals = fundamental.Where(x => - x.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology);-
filtered_fundamentals = [x for x in fundamental - if x.asset_classification.morningstar_sector_code == MorningstarSectorCode.TECHNOLOGY]-
- The
-
- MorningstarSectorCode
-
- enumeration has the following members:
-
- Industry groups are clusters of related industries that tie together. To access the industry group of an Equity, use the
-
- MorningstarIndustryGroupCode
-
- property.
-
filteredFundamentals = fundamental.Where(x => - x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.Software);-
filtered_fundamentals = [x for x in fundamental - if x.asset_classification.morningstar_industry_group_code == MorningstarIndustryGroupCode.SOFTWARE]-
- The
-
- MorningstarIndustryGroupCode
-
- enumeration has the following members:
-
- Industries are the finest classification level available and are the individual industries according to the Morningstar classification system. To access the industry group of an Equity, use the
-
- MorningstarIndustryCode
-
- property.
-
filteredFundamentals = fundamental.Where(x => - x.AssetClassification.MorningstarIndustryCode == MorningstarIndustryCode.SoftwareApplication);-
filtered_fundamentals = [x for x in fundamental - if x.asset_classification.morningstar_industry_code == MorningstarIndustryCode.SOFTWARE_APPLICATION]-
- The
-
- MorningstarIndustryCode
-
- enumeration has the following members:
-
- The exchange ID represents the exchange that lists the Equity. To access the exchange ID of an Equity, use the
-
- PrimaryExchangeID
-
- property.
-
filteredFundamentals = fundamental.Where(x => - x.CompanyReference.PrimaryExchangeID == "NAS");-
filtered_fundamentals = [x for x in fundamental - if x.company_reference.primary_exchange_id == "NAS"]-
- The exchanges are represented by the following string values: -
-| - String Representation - | -- Exchange - | -
|---|---|
| - NYS - | -- New York Stock Exchange (NYSE) - | -
| - NAS - | -- NASDAQ - | -
| - ASE - | -- American Stock Exchange (AMEX) - | -
| - TSE - | -- Tokyo Stock Exchange - | -
| - AMS - | -- Amsterdam Internet Exchange - | -
| - SGO - | -- Santiago Stock Exchange - | -
| - XMAD - | -- Madrid Stock Exchange - | -
| - ASX - | -- Australian Securities Exchange - | -
| - BVMF - | -- B3 (stock exchange) - | -
| - LON - | -- London Stock Exchange - | -
| - TKS - | -- Istanbul Stock Exchange Settlement and Custody Bank - | -
| - SHG - | -- Shanghai Exchange - | -
| - LIM - | -- Lima Stock Exchange - | -
| - FRA - | -- Frankfurt Stock Exchange - | -
| - JSE - | -- Johannesburg Stock Exchange - | -
| - MIL - | -- Milan Stock Exchange - | -
| - TAE - | -- Tel Aviv Stock Exchange - | -
| - STO - | -- Stockholm Stock Exchange - | -
| - ETR - | -- Deutsche Boerse Xetra Core - | -
| - PAR - | -- Paris Stock Exchange - | -
| - BUE - | -- Buenos Aires Stock Exchange - | -
| - KRX - | -- Korea Exchange - | -
| - SWX - | -- SIX Swiss Exchange - | -
| - PINX - | -- Pink Sheets (OTC) - | -
| - CSE - | -- Canadian Securities Exchange - | -
| - PHS - | -- Philippine Stock Exchange - | -
| - MEX - | -- Mexican Stock Exchange - | -
| - TAI - | -- Taiwan Stock Exchange - | -
| - IDX - | -- Indonesia Stock Exchange - | -
| - OSL - | -- Oslo Stock Exchange - | -
| - BOG - | -- Colombia Stock Exchange - | -
| - NSE - | -- National Stock Exchange of India - | -
| - HEL - | -- Nasdaq Helsinki - | -
| - MISX - | -- Moscow Exchange - | -
| - HKG - | -- Hong Kong Stock Exchange - | -
| - IST - | -- Istanbul Stock Exchange - | -
| - BOM - | -- Bombay Stock Exchange - | -
| - TSX - | -- Toronto Stock Exchange - | -
| - BRU - | -- Brussels Stock Exchange - | -
| - BATS - | -- BATS Global Markets - | -
| - ARCX - | -- NYSE Arca - | -
| - GREY - | -- Grey Market (OTC) - | -
| - DUS - | -- Dusseldorf Stock Exchange - | -
| - BER - | -- Berlin Stock Exchange - | -
| - ROCO - | -- Taipei Exchange - | -
| - CNQ - | -- Canadian Trading and Quotation System Inc. - | -
| - BSP - | -- Bangko Sentral ng Pilipinas - | -
| - NEOE - | -- NEO Exchange - | -
- -
- - TickData - - was founded by a futures broker and a programmer in 1984 as the first company in the world to offer historical tick-by-tick prices on the futures and index markets. TickData provides access to comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cash Indices. -
-- -
- The International Futures dataset by TickData provides Futures data, including price, volume, open interest, and expiry. The data covers the 4 contracts, DAX, FESX, HSI, and NKD, starting in July 1998 and is delivered on any frequency from tick to daily. This dataset is created by TickData, which negotiates directly with exchanges for their official archive and partners with real-time data providers with direct exchange connections and multiple redundant ticker plants. -
-- This dataset also depends on the - - US Futures Security Master - - because the US Futures Security Master dataset contains information to construct continuous Futures. -
-- For more information about the International Futures dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- - TickData - - was founded by a futures broker and a programmer in 1984 as the first company in the world to offer historical tick-by-tick prices on the futures and index markets. TickData provides access to comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cash Indices. -
- - - -- The following snippet demonstrates how to request data from the International Futures dataset: -
-hsi = self.add_future(Futures.Indices.HANG_SENG, Resolution.MINUTE).symbol # "HSI" -dax = self.add_future(Futures.Indices.DAX, Resolution.MINUTE).symbol # "DAX" -fesx = self.add_future(Futures.Indices.EURO_STOXX_50, Resolution.MINUTE).symbol # "FESX" -nkd = self.add_future(Futures.Indices.NIKKEI_225_DOLLAR, Resolution.MINUTE).symbol # "NKD"-
var hsi= AddFuture(Futures.Indices.HangSeng, Resolution.Minute).Symbol // "HSI"; -var dax = AddFuture(Futures.Indices.Dax, Resolution.Minute).Symbol // "DAX"; -var fesx = AddFuture(Futures.Indices.EuroStoxx50, Resolution.Minute).Symbol // "FESX"; -var nkd = AddFuture(Futures.Indices.Nikkei225Dollar, Resolution.Minute).Symbol // "NKD";-
- The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -
- July 1998, see
-
- Supported Assets
-
- below for details
- |
-
| - Coverage - | -- 4 Contracts - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Minute, Hour, & Daily - | -
| - Timezone - | -
- Various, refer to
-
- Supported Assets
-
- below
- |
-
| - Market Hours - | -- - Regular and Extended - - | -
- To add International Futures data to your algorithm, call the
-
- AddFuture
-
-
- add_future
-
- method. Save a reference to the Future so you can access the data later in your algorithm.
-
class InternationalFuturesDataAlgorithm(QCAlgorithm): - - def initialize(self) -> None: - self.set_start_date(2013, 12, 20) - self.set_end_date(2014, 2, 20) - self.set_cash(1000000) - self.universe_settings.asynchronous = True - # Request Hang Seng Index Futures data - future = self.add_future(Futures.Indices.HANG_SENG) - # Set filter to obtain the contracts expire within 90 days - future.set_filter(0, 90) - self.future_symbol = future.symbol-
public class InternationalFuturesDataAlgorithm : QCAlgorithm
-{
- private Symbol _futureSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2013, 12, 20);
- SetEndDate(2014, 2, 20);
- SetCash(1000000);
- UniverseSettings.Asynchronous = true;
- // Request Hang Seng Index Futures data
- var future = AddFuture(Futures.Indices.HangSeng);
- // Set filter to obtain the contracts expire within 90 days
- future.SetFilter(0, 90);
- _futureSymbol = future.Symbol;
- }
-}
- - For more information about creating Future subscriptions, see - - Requesting Data - - or - - Futures Universes - - . -
- - - -
- To get the current International Futures data, index the
-
- FuturesChains
-
-
- futures_chains
-
- property of the current
-
-
- Slice
-
-
- with the canonical Futures
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your Future at every time step.
-
def on_data(self, slice: Slice) -> None:
- # Get future chain of the canonical symbol
- chain = slice.futures_chains.get(self.future_symbol)
- if chain:
- # Iterate each contract in the future chain
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
-
- public override void OnData(Slice slice)
-{
- // Get future chain of the canonical symbol
- if (slice.FuturesChains.TryGetValue(_futureSymbol, out var chain))
- {
- // Iterate each contract in the future chain
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
-
- You can also iterate through all of the
-
- FuturesChain
-
- objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- # Iterate all future chains
- for canonical_symbol, chain in slice.futures_chains.items():
- # Iterate each contract in the future chain
- for contract in chain:
- self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
- public override void OnData(Slice slice)
-{
- // Iterate all future chains
- foreach (var kvp in slice.FuturesChains)
- {
- var canonicalSymbol = kvp.Key;
- var chain = kvp.Value;
- // Iterate each contract in the future chain
- foreach (var contract in chain)
- {
- Log($"{contract.Symbol} price at {slice.Time}: {contract.LastPrice}");
- }
- }
-}
- - For more information about accessing Futures data, see - - Handling Data - - . -
- - - -- You can get historical International Futures data in an algorithm and the Research Environment. -
-
- To get historical International Futures data in an algorithm, call the
-
- History
-
-
- history
-
- method with the canonical Futures
-
- Symbol
-
- or a Futures contract
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame objects -contract_history_df = self.history(contract.symbol, 100, Resolution.MINUTE) -continuous_history_df = self.history(self.future_symbol, - start=self.time - timedelta(days=15), - end=self.time, - resolution=Resolution.MINUTE, - fill_forward=False, - extended_market_hours=False, - data_mapping_mode=DataMappingMode.OPEN_INTEREST, - data_normalization_mode=DataNormalizationMode.RAW, - contract_depth_offset=0) - -# TradeBar objects -contract_history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE) -continous_history_trade_bars = self.history[TradeBar](self.future_symbol, 100, Resolution.MINUTE) - -# QuoteBar objects -contract_history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE) -continous_history_quote_bars = self.history[QuoteBar](self.future_symbol, 100, Resolution.MINUTE) - -# Tick objects -contract_history_ticks = self.history[Tick](contract.symbol, timedelta(seconds=10), Resolution.TICK) -continous_history_ticks = self.history[Tick](self.future_symbol, timedelta(seconds=10), Resolution.TICK)-
// TradeBar objects
-var contractHistoryTradeBars = History(contract.Symbol, 100, Resolution.Minute);
-var continuousHistoryTradeBars = History(
- symbols: new[] {_futureSymbol},
- start: Time - TimeSpan.FromDays(15),
- end: Time,
- resolution: Resolution.Minute,
- fillForward: false,
- extendedMarketHours: false,
- dataMappingMode: DataMappingMode.OpenInterest,
- dataNormalizationMode: DataNormalizationMode.Raw,
- contractDepthOffset: 0);
-
-// QuoteBar objects
-var contractHistoryQuoteBars = History<QuoteBar>(contract.Symbol, 100, Resolution.Minute);
-var continuousHistoryQuoteBars = History<QuoteBar>(_futureSymbol, 100, Resolution.Minute);
-
-// Tick objects
-var contractHistoryTicks = History<Tick>(contract.Symbol, TimeSpan.FromSeconds(10), Resolution.Tick);
-var continuousHistoryTicks = History<Tick>(_futureSymbol, TimeSpan.FromSeconds(10), Resolution.Tick);
- - For more information about historical data in algorithms, see - - History Requests - - . For more information about the price adjustments for continuous contracts, see - - Continous Contracts - - . -
-
- To get historical International Futures data in the Research Environment for an entire Futures chain, call the
-
- FutureHistory
-
-
- future_history
-
- method with the canonical Future
-
- Symbol
-
- .
-
qb = QuantBook() -future = qb.add_future(Futures.Indices.HANG_SENG) -future.set_filter(0, 90) -history = qb.future_history(future.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5)) -history_df = history.data_frame -all_history = history.get_all_data() -expiries = history.get_expiry_dates()-
var qb = new QuantBook(); -var future = qb.AddFuture(Futures.Indices.HangSeng); -future.SetFilter(0, 90); -var history = qb.FutureHistory(future.Symbol, new DateTime(2020, 6, 1), new DateTime(2020, 6, 5)); - -var contracts = history.SelectMany(x => x.OptionChains.SelectMany(y => y.Value.Contracts.Keys)).Distinct().ToList(); -var expiries = contracts.Select(x => x.ID.Date).Distinct().ToList();-
- To get historical data for a single International Futures contract or the continuous Futures contract, call the
-
- History
-
-
- history
-
- method like you would in an algorithm but on the
-
- QuantBook
-
- object. For more information about historical data in the Research Environment, see
-
- Futures
-
- .
-
- The following table shows the available Futures: -
-| - Ticker - | -- Future - | -- Start Date - | -- Time Zone - | -- Currency - | -
|---|---|---|---|---|
| - HSI - | -- Hang Seng Index Futures - | -- Jan 2010 - | -- Asia/Hong Kong - | -- HKD - | -
| - DAX - | -- German Index Futures - | -- Jan 2010 - | -- Europe/Berlin - | -- EUR - | -
| - FESX - | -- EURO STOXX 50 Index Futures - | -- Jul 1998 - | -- Europe/Berlin - | -- EUR - | -
| - NKD - | -- Nikkei 225 Index Futures - | -- Jan 2007 - | -- America/Chicago - | -- USD - | -
- The International Futures dataset enables you to design Futures strategies accurately. Examples include the following strategies: -
-- The following example algorithm uses - - ZigZag - - to determine the trend of Hang Seng Index. To trade the Indices, we make use of the HSI Futures. -
-from AlgorithmImports import *
-
-
-class InternationalFuturesDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Set the time zone to HKT to make it more comparable with the exchange.
- self.set_time_zone(TimeZones.HONG_KONG)
- # Set the account currency as HKD to trade HSI Futures.
- self.set_account_currency("HKD", 1000000)
- # Seed the last price of the contracts for filling.
- self.settings.seed_initial_prices = True
-
- # Request HSI Futures to trade.
- # Note that we will trade the contract with the highest open interest for liquidity.
- self.hsi_future = self.add_future(
- Futures.Indices.HANG_SENG,
- extended_market_hours=True,
- data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
- contract_depth_offset=0
- )
- # Request the corresponding underlying Index for feeding indicator for trade signal generation.
- hsi_index = self.add_index("HSI").symbol
-
- # Create a ZigZag indicator to trade Hang Seng Index price pivot points.
- self._zz = self.zz(hsi_index, 0.15, 5, Resolution.DAILY)
- # Warm up indicator for immediate readiness to trade.
- self.warm_up_indicator(hsi_index, self._zz, Resolution.DAILY)
-
- def on_data(self, slice: Slice) -> None:
- # Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if self.is_market_open(self.hsi_future.symbol) and self._zz.is_ready:
- pivot = self._zz.pivot_type
- # If the last pivot point is a low point, the current trend is increasing after this low point.
- if pivot == PivotPointType.LOW and not self.portfolio[self.hsi_future.symbol].is_long:
- self.set_holdings(self.hsi_future.mapped, 0.2)
- # If the last pivot point is a high point, the current trend is decreasing after this high point.
- elif pivot == PivotPointType.HIGH and not self.portfolio[self.hsi_future.symbol].is_short:
- self.set_holdings(self.hsi_future.mapped, -0.2)
-
- # Handle rollover in case the current mapped contract changes.
- for _, changed_event in slice.symbol_changed_events.items():
- old_symbol = changed_event.old_symbol
- new_symbol = self.add_future_contract(changed_event.new_symbol).symbol
- quantity = self.portfolio[old_symbol].quantity
- # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- self.liquidate(old_symbol)
- if quantity != 0:
- self.market_order(new_symbol, quantity)
- public class InternationalFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _hsiFuture;
- private ZigZag _zz;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Set the time zone to HKT to make it more comparable with the exchange.
- SetTimeZone(TimeZones.HongKong);
- // Set the account currency as HKD to trade HSI Futures.
- SetAccountCurrency("HKD", 1000000);
-
- // Seed the last price of the contracts for filling.
- Settings.SeedInitialPrices = true;
-
- // Request HSI Futures to trade.
- // Note that we will trade the contract with the highest open interest for liquidity.
- _hsiFuture = AddFuture(
- Futures.Indices.HangSeng,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.LastTradingDay,
- contractDepthOffset: 0
- );
- // Request the corresponding underlying index for feeding indicators for trade signal generation.
- var hsiIndex = AddIndex("HSI").Symbol;
-
- // Create a ZigZag indicator to trade Hang Seng Index price pivot points.
- _zz = ZZ(hsiIndex, 0.15m, 5, Resolution.Daily);
- // Warm up indicator for immediate readiness to trade.
- WarmUpIndicator(hsiIndex, _zz, Resolution.Daily);
- }
-
- public override void OnData(Slice slice)
- {
- // Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if (IsMarketOpen(_hsiFuture.Symbol) && _zz.IsReady)
- {
- var pivot = _zz.PivotType;
- // If the last pivot point is low, the current trend is increasing after this low point.
- if (pivot == PivotPointType.Low && !Portfolio[_hsiFuture.Symbol].IsLong)
- {
- SetHoldings(_hsiFuture.Mapped, 0.2m);
- }
- // If the last pivot point is high, the current trend decreases after this high point.
- else if (pivot == PivotPointType.High && !Portfolio[_hsiFuture.Symbol].IsShort)
- {
- SetHoldings(_hsiFuture.Mapped, -0.2m);
- }
- }
-
- // Handle rollover in case the current mapped contract changes.
- foreach (var (_, changedEvent) in slice.SymbolChangedEvents)
- {
- var oldSymbol = changedEvent.OldSymbol;
- var newSymbol = AddFutureContract(changedEvent.NewSymbol).Symbol;
- var quantity = Portfolio[oldSymbol].Quantity;
- // Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- Liquidate(oldSymbol);
- if (quantity != 0)
- {
- MarketOrder(newSymbol, quantity);
- }
- }
- }
-}
- - The following example algorithm uses the - - MACD - - indicator to determine the trend of the EuroStoxx50 Index. To trade the Index, we make use of the FESX Futures. -
-from AlgorithmImports import *
-
-
-class InternationalFuturesDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Set the time zone to Berlin to make it more comparable with the exchange.
- self.set_time_zone(TimeZones.BERLIN)
- # Set the account currency as EUR to trade FSX Futures.
- self.set_account_currency("EUR", 1000000)
- # Seed the last price of the contracts for filling.
- self.settings.seed_initial_prices = True
-
- # Request FESX Futures to trade.
- # Note that we will trade the contract with the highest open interest for liquidity.
- self.fesx_future = self.add_future(
- Futures.Indices.EURO_STOXX_50,
- extended_market_hours=True,
- data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
- contract_depth_offset=0
- )
- # Request the corresponding underlying Index for feeding indicator for trade signal generation.
- fesx_index = self.add_index("SX5E").symbol
-
- # Create a MACD indicator to trade EuroStoxx trend changes on the fast-slow term trend convergence.
- self._macd = self.macd(fesx_index, 12, 26, 9, resolution=Resolution.DAILY)
- # Warm up indicator for immediate readiness to trade.
- self.warm_up_indicator(fesx_index, self._macd, Resolution.DAILY)
-
- def on_data(self, slice: Slice) -> None:
- # Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if self.is_market_open(self.fesx_future.symbol) and self._macd.is_ready:
- # To identify a sensitive change in trend, use the change in the histogram value of the MACD.
- histogram = self._macd.histogram
- histogram_chg = histogram.current.value - histogram.previous.value
- # Positive histogram value increasing means the fast trend is rising faster than the slow trend, indicating a strong uptrend.
- if histogram_chg > 0 and histogram.current.value > 0 and not self.portfolio[self.fesx_future.symbol].is_long:
- self.set_holdings(self.fesx_future.mapped, 0.2)
- # Negative histogram value decreasing means the slow trend is dropping faster than the fast trend, indicating a strong downtrend.
- elif histogram_chg < 0 and histogram.current.value < 0 and not self.portfolio[self.fesx_future.symbol].is_short:
- self.set_holdings(self.fesx_future.mapped, -0.2)
-
- # Handle rollover in case the current mapped contract changes.
- for _, changed_event in slice.symbol_changed_events.items():
- old_symbol = changed_event.old_symbol
- new_symbol = self.add_future_contract(changed_event.new_symbol).symbol
- quantity = self.portfolio[old_symbol].quantity
- # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- self.liquidate(old_symbol)
- if quantity != 0:
- self.market_order(new_symbol, quantity)
- public class InternationalFuturesDataAlgorithm : QCAlgorithm
-{
- private Future _fesxFuture;
- private MovingAverageConvergenceDivergence _macd;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Set the time zone to Berlin to make it more comparable with the exchange.
- SetTimeZone(TimeZones.Berlin);
- // Set the account currency as EUR to trade FSX Futures.
- SetAccountCurrency("EUR", 1000000);
- // Seed the last price of the contracts for filling.
- Settings.SeedInitialPrices = true;
-
- // Request FESX Futures to trade.
- // Note that we will trade the contract with the highest open interest for liquidity.
- _fesxFuture = AddFuture(
- Futures.Indices.EuroStoxx50,
- extendedMarketHours: true,
- dataMappingMode: DataMappingMode.LastTradingDay,
- contractDepthOffset: 0
- );
- // Request the corresponding underlying Index for feeding indicator for trade signal generation.
- var fesxIndex = AddIndex("SX5E").Symbol;
-
- // Create a MACD indicator to trade EuroStoxx trend changes on the fast-slow term trend convergence.
- _macd = MACD(fesxIndex, 12, 26, 9, resolution: Resolution.Daily);
- // Warm up indicator for immediate readiness to trade.
- WarmUpIndicator(fesxIndex, _macd, Resolution.Daily);
- }
-
- public override void OnData(Slice slice)
- {
- // Only place trade if the Future contracts is in market opening hours to avoid stale fills.
- if (IsMarketOpen(_fesxFuture.Symbol) && _macd.IsReady)
- {
- // To identify a sensitive change in trend, use the change in the histogram value of the MACD.
- var histogram = _macd.Histogram;
- var histogramChg = histogram - histogram.Previous;
- // Positive histogram value increasing means the fast trend is rising faster than the slow trend, indicating a strong uptrend.
- if (histogramChg > 0 && histogram > 0 && !Portfolio[_fesxFuture.Symbol].IsLong)
- {
- SetHoldings(_fesxFuture.Mapped, 0.2m);
- }
- // Negative histogram value decreasing means the slow trend is dropping faster than the fast trend, indicating a strong downtrend.
- else if (histogramChg < 0 && histogram < 0 && !Portfolio[_fesxFuture.Symbol].IsShort)
- {
- SetHoldings(_fesxFuture.Mapped, -0.2m);
- }
- }
-
- // Handle rollover in case the current mapped contract changes.
- foreach (var (_, changedEvent) in slice.SymbolChangedEvents)
- {
- var oldSymbol = changedEvent.OldSymbol;
- var newSymbol = AddFutureContract(changedEvent.NewSymbol).Symbol;
- var quantity = Portfolio[oldSymbol].Quantity;
- // Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
- Liquidate(oldSymbol);
- if (quantity != 0)
- {
- MarketOrder(newSymbol, quantity);
- }
- }
- }
-}
-
- The International Futures dataset provides
-
- Future
-
- ,
-
- FuturesChain
-
- , and
-
- OpenInterest
-
- objects. To configure the continuous Future settings, use the
-
- DataNormalizationMode
-
- and
-
- DataMappingMode
-
- enumerations.
-
-
- Future
-
- objects have the following attributes:
-
-
- FuturesChain
-
- objects have the following attributes:
-
-
- OpenInterest
-
- objects have the following attributes:
-
- The
-
- DataNormalizationMode
-
- enumeration has the following values:
-
- The
-
- DataMappingMode
-
- enumeration has the following values:
-
- -
- - CoinAPI - - was founded by Artur Pietrzyk in 2016 with the goal of providing real-time and historical cryptocurrency market data, collected from hundreds of exchanges. CoinAPI provides access to Cryptocurrencies for traders, market makers, and developers building third-party applications. -
-- -
- The Binance Crypto Future Price Data by CoinAPI is for Crypto-currency futures price and volume data points. The data covers 718 Cryptocurrency pairs, starts in August 2020, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on Binance. -
-- The - - Binance Crypto Future Margin Rate Data - - dataset provides margin interest data to model margin costs. -
-- For more information about the Binance Crypto Future Price Data dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- - CoinAPI - - was founded by Artur Pietrzyk in 2016 with the goal of providing real-time and historical cryptocurrency market data, collected from hundreds of exchanges. CoinAPI provides access to Cryptocurrencies for traders, market makers, and developers building third-party applications. -
- - - -- The following snippet demonstrates how to request data from the Binance Crypto Future Price dataset: -
-def initialize(self) -> None:
- self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN)
- #self.set_brokerage_model(BrokerageName.BINANCE_COIN_FUTURES, AccountType.MARGIN)
-
- self.crypto_future_symbol = self.add_crypto_future("BTCBUSD", Resolution.MINUTE).symbol
-
- private Symbol _cryptoFutureSymbol;
-
-public override void Initialize
-{
- SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
- //SetBrokerageModel(BrokerageName.BinanceCoinFutures, AccountType.Margin);
-
- // perpetual futures does not have a filter function
- _cryptoFutureSymbol = AddCryptoFuture("BTCBUSD", Resolution.Minute).Symbol;
-}
-
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- August 2020 - | -
| - Asset Coverage - | -- 718 Crypto Futures Pairs - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Tick, Second, Minute, Hourly, & Daily - | -
| - Timezone - | -- UTC - | -
| - Market Hours - | -- - Always Open - - | -
- To add Binance Crypto Future Price data to your algorithm, call the
-
- AddCryptoFuture
-
-
- add_crypto_future
-
- method. Save a reference to the Crypto Future
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class CoinAPIDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2020, 6, 1)
- self.set_end_date(2021, 6, 1)
-
- # Set Account Currency to Binance Stable Coin for USD
- self.set_account_currency("BUSD")
- self.set_cash(100000)
-
- self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN)
- self.set_brokerage_model(BrokerageName.BINANCE_COIN_FUTURES, AccountType.MARGIN)
-
- crypto_future = self.add_crypto_future("BTCBUSD", Resolution.MINUTE)
- # perpetual futures does not have a filter function
- self.btcbusd = crypto_future.symbol
- public class CoinAPIDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol ;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
-
- // Set Account Currency to Binance Stable Coin for USD
- SetAccountCurrency("BUSD");
- SetCash(100000);
-
- SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
- SetBrokerageModel(BrokerageName.BinanceCoinFutures, AccountType.Margin);
-
- var cryptoFuture = AddCryptoFuture("BTCBUSD", Resolution.Minute);
- // perpetual futures does not have a filter function
- _symbol = cryptoFuture.Symbol;
- }
-}
- - For more information about creating Crypto Future subscriptions, see - - Requesting Data - - . -
- - - -
- To get the current Binance Crypto Future Price data, index the
-
- Bars
-
-
- bars
-
- ,
-
- QuoteBars
-
-
- quote_bars
-
- , or
-
- Ticks
-
-
- ticks
-
- properties of the current
-
-
- Slice
-
-
- with the Crypto Future
-
- Symbol
-
- .
-
- Slice
-
- objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if self.btcbusd in slice.bars:
- trade_bar = slice.bars[self.btcbusd]
- self.log(f"{self.btcbusd} close at {slice.time}: {trade_bar.close}")
-
- if self.btcbusd in slice.quote_bars:
- quote_bar = slice.quote_bars[self.btcbusd]
- self.log(f"{self.btcbusd} bid at {slice.time}: {quote_bar.bid.close}")
-
- if self.btcbusd in slice.ticks:
- ticks = slice.ticks[self.btcbusd]
- for tick in ticks:
- self.log(f"{self.btcbusd} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- if (slice.Bars.ContainsKey(_symbol))
- {
- var tradeBar = slice.Bars[_symbol];
- Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- if (slice.QuoteBars.ContainsKey(_symbol))
- {
- var quoteBar = slice.QuoteBars[_symbol];
- Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- if (slice.Ticks.ContainsKey(_symbol))
- {
- var ticks = slice.Ticks[_symbol];
- foreach (var tick in ticks)
- {
- Log($"{_symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- for symbol, trade_bar in slice.bars.items():
- self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
-
- for symbol, quote_bar in slice.quote_bars.items():
- self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- for symbol, ticks in slice.ticks.items():
- for tick in ticks:
- self.log(f"{symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.Bars)
- {
- var symbol = kvp.Key;
- var tradeBar = kvp.Value;
- Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- foreach (var kvp in slice.QuoteBars)
- {
- var symbol = kvp.Key;
- var quoteBar = kvp.Value;
- Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- foreach (var kvp in slice.Ticks)
- {
- var symbol = kvp.Key;
- var ticks = kvp.Value;
- foreach (var tick in ticks)
- {
- Log($"{symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
- - For more information about accessing Crypto Future data, see - - Handling Data - - . -
- - - -
- To get historical Binance Crypto Future Price data, call the
-
- History
-
-
- history
-
- method with the Crypto Future
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.btcbusd, 100, Resolution.DAILY) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](self.btcbusd, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](self.btcbusd, 100, Resolution.MINUTE) - -# Tick objects -history_ticks = self.history[Tick](self.btcbusd, timedelta(seconds=10), Resolution.TICK)-
// TradeBar objects -var historyTradeBars = History(_symbol, 100, Resolution.Daily); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); - -// Tick objects -var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To unsubscribe from a Crypto Future contract that you added with the
-
- AddCryptoFuture
-
-
- add_crypto_future
-
- method, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.btcbusd)-
RemoveSecurity(_symbol);-
- The
-
- RemoveSecurity
-
-
- remove_security
-
- method cancels your open orders for the security and liquidates your Crypto Future holdings.
-
- The following table shows the available Crypto Future pairs: -
-- The Binance Crypto Future Price dataset enables you to accurately design strategies for Cryptocurrencies with term structure. Examples include the following strategies: -
-- The following example algorithm buys BTCUSDT perpetual future contract if the last day's close price was close to ask close price than bid close price, sells short of that in opposite, through the Binance exchange: -
-from AlgorithmImports import *
-
-
-class BinanceCryptoFutureDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Set the account currency to USDT, since you can't trade with
- # USD and the algorithm doesn't automatically convert USD & USDT
- # holdings.
- self.set_account_currency("USDT", 100000)
- # Binance Futures Exchange accepts both Cash and Margin account
- # types. Select the one you need for the best reality modeling.
- self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN)
- # Add BTCUSDT data from the Binance Future exchange.
- # Perpetual futures does not have a filter function.
- self._btc = self.add_crypto_future("BTCUSDT", Resolution.DAILY)
- # Historical data
- history = self.history(self._btc, 10, Resolution.DAILY)
-
- def on_data(self, slice: Slice) -> None:
- # Trade only based on updated price data.
- if self._btc.symbol not in slice.bars or self._btc.symbol not in slice.quote_bars:
- return
- # Scalp-trade the bid-ask spread based on the supply-demand strength
- if self._btc.price - self._btc.bid_price > self._btc.ask_price - self._btc.price:
- self.set_holdings(self._btc, -0.5)
- else:
- self.set_holdings(self._btc, 1)
- public class BinanceCryptoFutureDataAlgorithm : QCAlgorithm
-{
- public CryptoFuture _btc;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Set the account currency to USDT, since you can't trade with
- // USD and the algorithm doesn't automatically convert USD & USDT
- // holdings.
- SetAccountCurrency("USDT", 100000);
- // Binance Futures Exchange accepts both Cash and Margin account
- // types. Select the one you need for the best reality modeling.
- SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
- // Add BTCUSDT data from the Binance Future exchange.
- // Perpetual futures does not have a filter function.
- _btc = AddCryptoFuture("BTCUSDT", Resolution.Daily);
- // Historical data
- var history = History(_btc, 10, Resolution.Daily);
- }
-
- public override void OnData(Slice slice)
- {
- // Trade only based on updated price data.
- if (!slice.Bars.ContainsKey(_btc) || !slice.QuoteBars.ContainsKey(_btc))
- {
- return;
- }
- // Scalp-trade the bid-ask spread based on the supply-demand strength
- if (_btc.Price - _btc.BidPrice > _btc.AskPrice - _btc.Price)
- {
- SetHoldings(_btc, -0.5m);
- }
- else
- {
- SetHoldings(_btc, 1m);
- }
- }
-}
- - The following example algorithm hold a long BTCUSDT Future portfolio if the last day's close price was close to ask close price than bid close price, while hold short of that in opposite, through the Binance exchange using the - - algorithm framework - - implementation: -
-from AlgorithmImports import *
-
-
-class BinanceCryptoFutureDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- # Set the account currency to USDT, since you can't trade with
- # USD and the algorithm doesn't automatically convert USD & USDT
- # holdings.
- self.set_account_currency("USDT", 100000)
- # Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling.
- self.set_brokerage_model(BrokerageName.BINANCE_FUTURES, AccountType.MARGIN)
- self.universe_settings.resolution = Resolution.DAILY
- self.universe_settings.leverage = 2
- # We only trade on BTCUSDT Future in Binance Future exchange
- symbols = Symbol.create("BTCUSDT", SecurityType.CRYPTO_FUTURE, Market.BINANCE)
- self.add_universe_selection(ManualUniverseSelectionModel(symbols))
- # Custom alpha model to emit insights based on the Crypto Future price data
- self.add_alpha(CryptoFutureAlphaModel())
- # Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
- self.set_execution(ImmediateExecutionModel())
-
-class CryptoFutureAlphaModel(AlphaModel):
-
- def __init__(self) -> None:
- self.symbols = []
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
-
- for symbol in self.symbols:
- # Trade only based on updated price data
- if not slice.bars.contains_key(symbol) or not slice.quote_bars.contains_key(symbol):
- continue
-
- quote = slice.quote_bars[symbol]
- price = slice.bars[symbol].price
-
- # Scalp-trade the bid-ask spread based on the supply-demand strength
- if price - quote.bid.close > quote.ask.close - price:
- direction = InsightDirection.DOWN
- else:
- direction = InsightDirection.UP
- insights.append(Insight.price(symbol, timedelta(1), direction))
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- symbol = security.symbol
- self.symbols.append(symbol)
-
- # Historical data
- history = algorithm.history(symbol, 10, Resolution.DAILY)
-
- for security in changes.removed_securities:
- symbol = security.symbol
- if symbol in self.symbols:
- self.symbols.remove(symbol)
-
- public class BinanceCryptoFutureDataAlgorithm : QCAlgorithm
-{
- public Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- // Set the account currency to USDT, since you can't trade with
- // USD and the algorithm doesn't automatically convert USD & USDT
- // holdings.
- SetAccountCurrency("USDT", 100000);
- // Binance Futures Exchange accepts both Cash and Margin account types, select the one you need for the best reality modeling.
- SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
- UniverseSettings.Resolution = Resolution.Daily;
- UniverseSettings.Leverage = 2;
- // We only trade on BTCUSDT Future in Binance Future exchange
- var symbols = new List<Symbol> {
- QuantConnect.Symbol.Create("BTCUSDT", SecurityType.CryptoFuture, Market.Binance)
- };
- AddUniverseSelection(new ManualUniverseSelectionModel(symbols));
- // Custom alpha model to emit insights based on the Crypto Future price data
- AddAlpha(new CryptoFutureAlphaModel());
- // Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- SetExecution(new ImmediateExecutionModel());
- }
-}
-
-public class CryptoFutureAlphaModel : AlphaModel
-{
- private List<Symbol> _symbols = new();
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- var insights = new List<Insight>();
-
- foreach (var symbol in _symbols)
- {
- // Trade only based on updated price data
- if (!slice.Bars.ContainsKey(symbol) || !slice.QuoteBars.TryGetValue(symbol, out var quote))
- {
- continue;
- }
- var price = slice.Bars[symbol].Price;
-
- // Scalp-trade the bid-ask spread based on the supply-demand strength
- InsightDirection direction;
- if (price - quote.Bid.Close > quote.Ask.Close - price)
- {
- direction = InsightDirection.Down;
- }
- else
- {
- direction = InsightDirection.Up;
- }
- insights.Add(Insight.Price(symbol, TimeSpan.FromDays(1), direction));
- }
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- var symbol = security.Symbol;
- _symbols.Add(symbol);
-
- // Historical data
- var history = algorithm.History(symbol, 10, Resolution.Daily);
- }
-
- foreach (var security in changes.RemovedSecurities)
- {
- _symbols.Remove(security.Symbol);
- }
- }
-}
-
- The Binance Crypto Future Price dataset provides
-
- TradeBar
-
- ,
-
- QuoteBar
-
- , and
-
- Tick
-
- objects.
-
-
- TradeBar
-
- objects have the following attributes:
-
-
- QuoteBar
-
- objects have the following attributes:
-
-
- Tick
-
- objects have the following attributes:
-
- -
- The Binance Crypto Price Data by CoinAPI is for Cryptocurrency price and volume data points. The data covers 3,320 Cryptocurrency pairs, starts in July 2017, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on Binance. -
-- For more information about the Binance Crypto Price Data dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- - CoinAPI - - was founded by Artur Pietrzyk in 2016 with the goal of providing real-time and historical cryptocurrency market data, collected from hundreds of exchanges. CoinAPI provides access to Cryptocurrencies for traders, market makers, and developers building third-party applications. -
- - - -- The following snippet demonstrates how to request data from the Binance Crypto Price dataset: -
-# Binance accepts both Cash and Margin account types only.
-self.set_brokerage_model(BrokerageName.BINANCE, AccountType.CASH)
-#self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
-
-self.btcbusd = self.add_crypto("BTCBUSD", Resolution.MINUTE, Market.BINANCE).symbol
-
-self._universe = self.add_universe(CryptoUniverse.binance(self.universe_selection_filter))
-
- // Binance accepts both Cash and Margin account types only.
-SetBrokerageModel(BrokerageName.Binance, AccountType.Cash);
-//SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
-
-_symbol = AddCrypto("BTCBUSD", Resolution.Minute, Market.Binance).Symbol;
-
-_universe = AddUniverse(CryptoUniverse.Binance(UniverseSelectionFilter));
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- July 2017 - | -
| - Asset Coverage - | -- 3,320 Currency Pairs - | -
| - Data Density - | -- Dense - | -
| - Resolution - | -- Tick, Second, Minute, Hourly, & Daily - | -
| - Timezone - | -- UTC - | -
| - Market Hours - | -- - Always Open - - | -
- To add Binance Crypto Price data to your algorithm, call the
-
- AddCrypto
-
-
- add_crypto
-
- method. Save a reference to the Crypto
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class CoinAPIDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2020, 6, 1)
- self.set_end_date(2021, 6, 1)
-
- # Set Account Currency to Binance Stable Coin for USD
- self.set_account_currency("BUSD")
- self.set_cash(100000)
-
- # Binance accepts both Cash and Margin account types.
- self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
-
- self.btcbusd = self.add_crypto("BTCBUSD", Resolution.MINUTE, Market.BINANCE).symbol
- public class CoinAPIDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol;
-
- public override void Initialize()
- {
- SetStartDate(2020, 6, 1);
- SetEndDate(2021, 6, 1);
-
- // Set Account Currency to Binance Stable Coin for USD
- SetAccountCurrency("BUSD");
- SetCash(100000);
-
- // Binance accepts both Cash and Margin account types.
- SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
-
- _symbol = AddCrypto("BTCBUSD", Resolution.Minute, Market.Binance).Symbol;
- }
-}
- - For more information about creating Crypto subscriptions, see - - Requesting Data - - . -
- - - -
- To get the current Binance Crypto Price data, index the
-
- Bars
-
-
- bars
-
- ,
-
- QuoteBars
-
-
- quote_bars
-
- , or
-
- Ticks
-
-
- ticks
-
- properties of the current
-
-
- Slice
-
-
- with the Crypto
-
- Symbol
-
- .
-
- Slice
-
- objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your security at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if self.btcbusd in slice.bars:
- trade_bar = slice.bars[self.btcbusd]
- self.log(f"{self.btcbusd} close at {slice.time}: {trade_bar.close}")
-
- if self.btcbusd in slice.quote_bars:
- quote_bar = slice.quote_bars[self.btcbusd]
- self.log(f"{self.btcbusd} bid at {slice.time}: {quote_bar.bid.close}")
-
- if self.btcbusd in slice.ticks:
- ticks = slice.ticks[self.btcbusd]
- for tick in ticks:
- self.log(f"{self.btcbusd} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- if (slice.Bars.ContainsKey(_symbol))
- {
- var tradeBar = slice.Bars[_symbol];
- Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- if (slice.QuoteBars.ContainsKey(_symbol))
- {
- var quoteBar = slice.QuoteBars[_symbol];
- Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- if (slice.Ticks.ContainsKey(_symbol))
- {
- var ticks = slice.Ticks[_symbol];
- foreach (var tick in ticks)
- {
- Log($"{_symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
-
- You can also iterate through all of the data objects in the current
-
- Slice
-
- .
-
def on_data(self, slice: Slice) -> None:
- for symbol, trade_bar in slice.bars.items():
- self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
-
- for symbol, quote_bar in slice.quote_bars.items():
- self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
-
- for symbol, ticks in slice.ticks.items():
- for tick in ticks:
- self.log(f"{symbol} price at {slice.time}: {tick.price}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.Bars)
- {
- var symbol = kvp.Key;
- var tradeBar = kvp.Value;
- Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
- }
-
- foreach (var kvp in slice.QuoteBars)
- {
- var symbol = kvp.Key;
- var quoteBar = kvp.Value;
- Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
- }
-
- foreach (var kvp in slice.Ticks)
- {
- var symbol = kvp.Key;
- var ticks = kvp.Value;
- foreach (var tick in ticks)
- {
- Log($"{symbol} price at {slice.Time}: {tick.Price}");
- }
- }
-}
-
- - For more information about accessing Crypto data, see - - Handling Data - - . -
- - - -
- To get historical Binance Crypto Price data, call the
-
- History
-
-
- history
-
- method with the Crypto
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.btcbusd, 100, Resolution.DAILY) - -# TradeBar objects -history_trade_bars = self.history[TradeBar](self.btcbusd, 100, Resolution.MINUTE) - -# QuoteBar objects -history_quote_bars = self.history[QuoteBar](self.btcbusd, 100, Resolution.MINUTE) - -# Tick objects -history_ticks = self.history[Tick](self.btcbusd, timedelta(seconds=10), Resolution.TICK)-
// TradeBar objects -var historyTradeBars = History(_symbol, 100, Resolution.Daily); - -// QuoteBar objects -var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); - -// Tick objects -var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To select a dynamic universe of Binance Crypto pairs, call the
-
- AddUniverse
-
-
- add_universe
-
- method with a
-
- CryptoUniverse
-
- object. A
-
- Crypto universe
-
- uses a selection function to select Crypto pairs based on their OHLCV and dollar volume of the previous day as of midnight Coordinated Universal Time (UTC).
-
def initialize(self) -> None: - self.universe_settings.asynchronous = True - self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN) - self._universe = self.add_universe(CryptoUniverse.binance(self.universe_selection_filter)) - -def universe_selection_filter(self, universe_day): - return [c.symbol for c in universe_day if c.volume >= 100 and c.volume_in_usd > 10000]-
using QuantConnect.Data.UniverseSelection;
-
-public override void Initialize()
-{
- UniverseSettings.Asynchronous = true;
- SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
- _universe = AddUniverse(CryptoUniverse.Binance(UniverseSelectionFilter));
-}
-
-private IEnumerable<Symbol> UniverseSelectionFilter(IEnumerable<CryptoUniverse> universeDay)
-{
- return from c in universeDay
- where c.Volume >= 100m && c.VolumeInUsd > 10000m
- select c.Symbol;
-}
- - For more information about universe settings, see - - Settings - - . -
- - - -- You can get historical universe data in an algorithm and in the Research Environment. -
-
- To get historical universe data in an algorithm, call the
-
- History
-
-
- history
-
- method with the
-
- Universe
-
- object, and the lookback period. If there is no data in the period you request, the history result is empty.
-
var history = History(_universe, 30, Resolution.Daily);
-foreach (var universeDay in history)
-{
- foreach (CryptoUniverse universeItem in universeDay)
- {
- Log($"{universeItem.Symbol} price at {universeItem.EndTime}: {universeItem.Close}");
- }
-}
- # DataFrame example where the columns are the CryptoUniverse attributes:
-history_df = self.history(self._universe, 30, Resolution.DAILY, flatten=True)
-
-# Series example where the values are lists of CryptoUniverse objects:
-history = self.history(self._universe, 30, Resolution.DAILY)
-for (univere_symbol, time), universe_day in history.items():
- for universe_item in universe_day:
- self.log(f"{universe_item.symbol} price at {universe_item.end_time}: {universe_item.close}")
-
- To get historical universe data in research, call the
-
- UniverseHistory
-
-
- universe_history
-
- method with the
-
- Universe
-
- object, and the lookback period. The
-
- UniverseHistory
-
-
- universe_history
-
- returns the filtered universe. If there is no data in the period you request, the history result is empty.
-
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-foreach (var universeDay in universeHistory)
-{
- foreach (CryptoUniverse universeItem in universeDay)
- {
- Console.WriteLine($"{universeItem.Symbol} price at {universeItem.EndTime}: {universeItem.Close}");
- }
-}
- # DataFrame example where the columns are the CryptoUniverse attributes:
-history_df = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
-
-# Series example where the values are lists of CryptoUniverse objects:
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (univere_symbol, time), universe_day in universe_history.items():
- for universe_item in universe_day:
- print(f"{universe_item.symbol} price at {universe_item.end_time}: {universe_item.close}")
-
- You can call the
-
- History
-
-
- history
-
- method in Research.
-
- To unsubscribe from a Crypto pair that you added with the
-
- AddCrypto
-
-
- add_crypto
-
- method, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.btcbusd)-
RemoveSecurity(_symbol);-
- The
-
- RemoveSecurity
-
-
- remove_security
-
- method cancels your open orders for the security and liquidates your holdings in the
-
- virtual pair
-
- .
-
+ The Binance Crypto Price dataset enables you to accurately design strategies for Cryptocurrencies. Examples include the following strategies: +
++ The following example algorithm buys and holds Bitcoin through the Binance exchange: +
+from AlgorithmImports import *
+
+
+class CoinAPIDataAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ # Set the account currency to USDT, since you can't trade with
+ # USD and the algorithm doesn't automatically convert USD & USDT
+ # holdings.
+ self.set_account_currency("USDT", 100000)
+ self.universe_settings.asynchronous = True
+ # Binance accepts both Cash and Margin account types. Select the
+ # one you need for the best reality modeling.
+ self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
+ # Add BTCUSDT data.
+ self._btc = self.add_crypto("BTCUSDT", Resolution.MINUTE, Market.BINANCE)
+ # Historical data
+ history = self.history(self._btc.symbol, 30, Resolution.DAILY)
+ # Add a Crypto universe that selects trading pairs on Binance.
+ universe = self.add_universe(CryptoUniverse.binance(self._select_assets))
+ # Historical Universe data
+ universe_history = self.history(universe, 30, Resolution.DAILY)
+ for (universe_symbol, time), universe_day in universe_history.items():
+ for universe_item in universe_day:
+ symbol = universe_item.symbol
+ price = universe_item.close
+
+ def _select_assets(self, universe_day):
+ # Filter for materially traded Crypto pairs with significant
+ # size and dollar volume, assuming higher capital flow in for
+ # higher return.
+ return [universe_item.symbol for universe_item in universe_day
+ if universe_item.volume >= 100
+ and universe_item.volume_in_usd > 10_000_000]
+
+ def on_data(self, slice: Slice) -> None:
+ # Speculate-invest all available free cash on BTCUSDT, repecting
+ # the order quantity restrictions to avoid invalid orders.
+ if self.portfolio.cash_book['BTC'].amount != 0:
+ return
+ # Define a buffer so that we can scale down the order size,
+ # avoiding trading errors.
+ buffer = max(
+ BinanceFeeModel.TAKER_TIER_1_FEE,
+ self.settings.free_portfolio_value_percentage
+ )
+ quantity = (
+ self.portfolio.cash_book['USDT'].amount
+ / self._btc.ask_price
+ * (1-buffer)
+ )
+ # Check if the quantity exceeds the minimum order size. On
+ # Binance, the minimum order size is measured in the quote
+ # currency (USDT in this case).
+ minimum_order_size = (
+ self._btc.symbol_properties.minimum_order_size
+ / self._btc.ask_price
+ )
+ if abs(quantity) < minimum_order_size:
+ return
+ self.market_order(self._btc, quantity)
+ public class CoinAPIDataAlgorithm : QCAlgorithm
+{
+ private Crypto _btc;
+
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ // Set the account currency to USDT, since you can't trade with
+ // USD and the algorithm doesn't automatically convert USD & USDT
+ // holdings.
+ SetAccountCurrency("USDT", 100000);
+ UniverseSettings.Asynchronous = true;
+ // Binance accepts both Cash and Margin account types. Select the
+ // one you need for the best reality modeling.
+ SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
+ // Add BTCUSDT data.
+ _btc = AddCrypto("BTCUSDT", Resolution.Minute, Market.Binance);
+ // Historical data
+ var history = History(_btc.Symbol, 30, Resolution.Daily);
+ // Add a Crypto universe that selects trading pairs on Binance.
+ var universe = AddUniverse(CryptoUniverse.Binance(SelectAssets));
+ // Historical Universe data
+ var universeHistory = History(universe, 30, Resolution.Daily);
+ foreach (var universeDay in universeHistory)
+ {
+ foreach (CryptoUniverse universeItem in universeDay)
+ {
+ var symbol = universeItem.Symbol;
+ var price = universeItem.Close;
+ }
+ }
+ }
+
+ private IEnumerable<Symbol> SelectAssets(IEnumerable<CryptoUniverse> universeDay)
+ {
+ // Filter for materially traded Crypto pairs with significant
+ // size and dollar volume, assuming higher capital flow in for
+ // higher return.
+ return from universeItem in universeDay
+ where universeItem.Volume >= 100m
+ && universeItem.VolumeInUsd > 10000000m
+ select universeItem.Symbol;
+ }
+
+ public override void OnData(Slice slice)
+ {
+ // Speculate-invest all available free cash on BTCUSDT, repecting
+ // the order quantity restrictions to avoid invalid orders.
+ if (Portfolio.CashBook["BTC"].Amount != 0)
+ {
+ return;
+ }
+ // Define a buffer so that we can scale down the order size,
+ // avoiding trading errors.
+ var buffer = Math.Max(BinanceFeeModel.TakerTier1Fee, Settings.FreePortfolioValuePercentage);
+ var quantity = Portfolio.CashBook["USDT"].Amount / _btc.AskPrice * (1-buffer);
+ // Check if the quantity exceeds the minimum order size. On
+ // Binance, the minimum order size is measured in the quote
+ // currency (USDT in this case).
+ var minimumOrderSize = _btc.SymbolProperties.MinimumOrderSize / _btc.AskPrice;
+ if (Math.Abs(quantity) < minimumOrderSize)
+ {
+ return;
+ }
+ MarketOrder(_btc, quantity);
+ }
+}
+ + The following example algorithm creates a dynamic universe of Crypto pairs on the Binance exchange and then forms a equal-weighted portfolio of all the pairs in the universe: +
+from AlgorithmImports import *
+
+
+class CoinAPIDataAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ # Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
+ self.set_account_currency("USDT", 100000)
+ self.settings.free_portfolio_value_percentage = 0.05
+
+ # Binance accepts both Cash and Margin account types, select the one you need for the best reality modeling.
+ self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
+
+ # Warm up the security with the last known price to avoid conversion error
+ self.settings.seed_initial_prices = True
+ self.universe_settings.asynchronous = True
+ self.universe_settings.resolution = Resolution.MINUTE
+ # Add Crypto Universe Selection that select crypto pairs in Binance exchange
+ self.add_universe(CryptoUniverse.binance(self.universe_selection_filter))
+ # Get the pairs on Binance that have USDT as the quote currency.
+ self._market_pairs = [
+ x.key.symbol
+ for x in self.symbol_properties_database.get_symbol_properties_list(Market.BINANCE)
+ if x.value.quote_currency == self.account_currency
+ ]
+
+ self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(minutes = 20), 0.025, None))
+ # Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
+ self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
+
+ def universe_selection_filter(self, universe_day: List[CryptoUniverse]) -> List[Symbol]:
+ # Select pairs where the quote currency is USDT.
+ pairs = [c for c in universe_day if c.symbol.value in self._market_pairs]
+ # Filter for materially traded crypto pairs with significant dollar volume, assuming higher capital flow in for higher return.
+ pairs = sorted(pairs, key=lambda c: c.volume_in_usd)[-3:]
+ return [c.symbol for c in pairs]
+
+ def on_securities_changed(self, changes: SecurityChanges) -> None:
+ for security in changes.added_securities:
+ # Historical data
+ history = self.history(security.symbol, 30, Resolution.DAILY)
+ public class CoinAPIDataAlgorithm : QCAlgorithm
+{
+ private List<string> _marketPairs;
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ Settings.FreePortfolioValuePercentage = 0.05m;
+
+ // Set Account Currency to Tether, since USD and USDT will not auto-convert and USD cannot be used to trade
+ SetAccountCurrency("USDT", 100000);
+ // Binance accepts both Cash and Margin account types, select the one you need for the best reality modeling.
+ SetBrokerageModel(BrokerageName.Binance, AccountType.Margin);
+
+ // Warm up the security with the last known price to avoid conversion error
+ Settings.SeedInitialPrices = true;
+ UniverseSettings.Asynchronous = true;
+ UniverseSettings.Resolution = Resolution.Minute;
+ // Add Crypto Universe Selection that select crypto pairs in Binance exchange
+ AddUniverse(CryptoUniverse.Binance(UniverseSelectionFilter));
+ // Get the pairs on Binance that have USDT as the quote currency.
+ _marketPairs = SymbolPropertiesDatabase.GetSymbolPropertiesList(Market.Binance)
+ .Where(x => x.Value.QuoteCurrency == AccountCurrency)
+ .Select(x => x.Key.Symbol)
+ .ToList();
+
+ AddAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromMinutes(20), 0.025, null));
+ // Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
+ SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
+ }
+
+ private IEnumerable<Symbol> UniverseSelectionFilter(IEnumerable<CryptoUniverse> universeDay)
+ {
+ // Select pairs where the quote currency is USDT.
+ return universeDay.Where(c => _marketPairs.Contains(c.Symbol.Value))
+ // Filter for materially traded crypto pairs with significant size and dollar volume, assuming higher capital flow in for higher return
+ .OrderBy(c => c.VolumeInUsd)
+ .TakeLast(3)
+ .Select(c => c.Symbol);
+ }
+
+ public override void OnSecuritiesChanged(SecurityChanges changes)
+ {
+ foreach(var security in changes.AddedSecurities)
+ {
+ // Historical data
+ var history = History(security.Symbol, 30, Resolution.Daily);
+ }
+ }
+}
+ + The following example lists crypto-currency pairs with the greatest dollar volume in the Binance exchange: +
+var qb = new QuantBook();
+
+// Add Cryptocurrency pair
+var symbol = qb.AddCrypto("BTCUSDT", market:Market.Binance).Symbol;
+
+// Historical data
+var history = qb.History(symbol, 30, Resolution.Daily);
+foreach (var bar in history)
+{
+ Console.WriteLine($"{bar.EndTime} {bar}");
+}
+
+// Add Crypto Universe Selection
+IEnumerable<Symbol> UniverseSelectionFilter(IEnumerable<CryptoUniverse> universeDay)
+{
+ return universeDay
+ .Where(x => x.VolumeInUsd != null && x.VolumeInUsd > 10000m)
+ .OrderByDescending(x => x.VolumeInUsd)
+ .Take(5)
+ .Select(x => x.Symbol);
+}
+var universe = qb.AddUniverse(CryptoUniverse.Binance(UniverseSelectionFilter));
+
+// Historical Universe data
+var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
+foreach (var universeDay in universeHistory)
+{
+ Console.WriteLine($"=== {universeDay.First().EndTime} ===");
+ foreach (CryptoUniverse universeItem in universeDay.OrderByDescending(x => x.VolumeInUsd))
+ {
+ Console.WriteLine($"{universeItem.Symbol}: {universeItem.VolumeInUsd}");
+ }
+}
+ qb = QuantBook()
+
+# Add Cryptocurrency pair
+symbol = qb.add_crypto("BTCUSDT", market=Market.BINANCE).symbol
+
+# Historical data
+history = qb.history(symbol, 30, Resolution.DAILY)
+for (symbol, time), row in history.iterrows():
+ print(f'{time} {symbol} {row.close}')
+
+# Add Crypto Universe Selection
+def universe_selection_filter(universe_day):
+ selected = sorted([x for x in universe_day
+ if x.volume_in_usd and x.volume_in_usd > 10000],
+ key=lambda x: x.volume_in_usd, reverse=True)[:5]
+ return [x.symbol for x in selected]
+
+universe = qb.add_universe(CryptoUniverse.binance(universe_selection_filter))
+
+# Historical Universe data
+history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
+for (univere_symbol, time), universe_day in history.items():
+ print(f'=== {time} ===')
+ for universe_item in sorted(universe_day, key=lambda x: x.volume_in_usd, reverse=True):
+ print(f"{universe_item.symbol}: {universe_item.volume_in_usd}")
+
+ The Binance Crypto Price dataset provides
+
+ TradeBar
+
+ ,
+
+ QuoteBar
+
+ ,
+
+ Tick
+
+ , and
+
+ CryptoUniverse
+
+ objects.
+
+
+ TradeBar
+
+ objects have the following attributes:
+
+
+ QuoteBar
+
+ objects have the following attributes:
+
+
+ Tick
+
+ objects have the following attributes:
+
+
+ CryptoUniverse
+
+ objects have the following attributes:
+
+ +
+ The Binance US Crypto Price Data is for Cryptocurrency price and volume data points. The data covers 604 Cryptocurrency pairs, starts in October 2019, and is delivered on any frequency from tick to daily. This dataset is created by monitoring the trading activity on Binance US. +
++ For more information about the Binance US Crypto Price Data dataset, including CLI commands and pricing, see the + + dataset listing + + . +
++
+ + + ++ Binance was founded by Changpeng Zhao in 2017 with the goal to "increase the freedom of money globally". Binance provides access to trading Crypto through spot markets and perpetual Futures. They serve clients with no minimum deposit when depositing Crypto. Binance also provides an NFT marketplace, a mining pool, and services to deposit Crypto coins in liquidity pools to earn rewards. +
+ + + ++ The following snippets demonstrates how to set the brokerage model, request data, and perform universe selection with the Binance US dataset: +
+# Binance US only accepts cash accounts
+self.set_brokerage_model(BrokerageName.BINANCE_US, AccountType.CASH)
+
+self.btcbusd = self.add_crypto("BTCUSD", Resolution.MINUTE, Market.BINANCE_US).symbol
+
+self._universe = AddUniverse(CryptoUniverse.binance_us(self.universe_selection_filter));
+ // Binance US only accepts cash accounts
+SetBrokerageModel(BrokerageName.BinanceUS, AccountType.Cash);
+
+_symbol = AddCrypto("BTCUSD", Resolution.Minute, Market.BinanceUS).Symbol;
+
+_universe = AddUniverse(CryptoUniverse.BinanceUS(UniverseSelectionFilter));
+ + The following table describes the dataset properties: +
+| + Property + | ++ Value + | +
|---|---|
| + Start Date + | ++ October 2019 + | +
| + Asset Coverage + | ++ 604 Cryptocurrency Pairs + | +
| + Data Density + | ++ Dense + | +
| + Resolution + | ++ Tick, Second, Minute, Hourly, & Daily + | +
| + Timezone + | ++ UTC + | +
| + Market Hours + | ++ + Always Open + + | +
+ To add Binance US Crypto Price data to your algorithm, call the
+
+ AddCrypto
+
+
+ add_crypto
+
+ method. Save a reference to the Crypto
+
+ Symbol
+
+ so you can access the data later in your algorithm.
+
class CoinAPIDataAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2020, 6, 1)
+ self.set_end_date(2021, 6, 1)
+ self.set_cash(100000)
+
+ # BinanceUS accepts Cash account type only, AccountType.MARGIN will result in an exception.
+ self.set_brokerage_model(BrokerageName.BINANCE_US, AccountType.CASH)
+
+ self.btcbusd = self.add_crypto("BTCUSD", Resolution.MINUTE, Market.BINANCE_US).symbol
+ public class CoinAPIDataAlgorithm : QCAlgorithm
+{
+ private Symbol _symbol;
+
+ public override void Initialize()
+ {
+ SetStartDate(2020, 6, 1);
+ SetEndDate(2021, 6, 1);
+ SetCash(100000);
+
+ // BinanceUS accepts Cash account type only, AccountType.Margin will result in an exception.
+ SetBrokerageModel(BrokerageName.BinanceUS, AccountType.Cash);
+
+ _symbol = AddCrypto("BTCUSD", Resolution.Minute, Market.BinanceUS).Symbol;
+ }
+}
+ + For more information about creating Crypto subscriptions, see + + Requesting Data + + . +
+ + + +
+ To get the current Binance US Crypto Price data, index the
+
+ Bars
+
+
+ bars
+
+ ,
+
+ QuoteBars
+
+
+ quote_bars
+
+ , or
+
+ Ticks
+
+
+ ticks
+
+ properties of the current
+
+
+ Slice
+
+
+ with the Crypto
+
+ Symbol
+
+ .
+
+ Slice
+
+ objects deliver unique events to your algorithm as they happen, but the
+
+ Slice
+
+ may not contain data for your security at every time step. To avoid issues, check if the
+
+ Slice
+
+ contains the data you want before you index it.
+
def on_data(self, slice: Slice) -> None:
+ if self.btcbusd in slice.bars:
+ trade_bar = slice.bars[self.btcbusd]
+ self.log(f"{self.btcbusd} close at {slice.time}: {trade_bar.close}")
+
+ if self.btcbusd in slice.quote_bars:
+ quote_bar = slice.quote_bars[self.btcbusd]
+ self.log(f"{self.btcbusd} bid at {slice.time}: {quote_bar.bid.close}")
+
+ if self.btcbusd in slice.ticks:
+ ticks = slice.ticks[self.btcbusd]
+ for tick in ticks:
+ self.log(f"{self.btcbusd} price at {slice.time}: {tick.price}")
+ public override void OnData(Slice slice)
+{
+ if (slice.Bars.ContainsKey(_symbol))
+ {
+ var tradeBar = slice.Bars[_symbol];
+ Log($"{_symbol} price at {slice.Time}: {tradeBar.Close}");
+ }
+
+ if (slice.QuoteBars.ContainsKey(_symbol))
+ {
+ var quoteBar = slice.QuoteBars[_symbol];
+ Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
+ }
+
+ if (slice.Ticks.ContainsKey(_symbol))
+ {
+ var ticks = slice.Ticks[_symbol];
+ foreach (var tick in ticks)
+ {
+ Log($"{_symbol} price at {slice.Time}: {tick.Price}");
+ }
+ }
+}
+
+
+ You can also iterate through all of the data objects in the current
+
+ Slice
+
+ .
+
def on_data(self, slice: Slice) -> None:
+ for symbol, trade_bar in slice.bars.items():
+ self.log(f"{symbol} close at {slice.time}: {trade_bar.close}")
+
+ for symbol, quote_bar in slice.quote_bars.items():
+ self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
+
+ for symbol, ticks in slice.ticks.items():
+ for tick in ticks:
+ self.log(f"{symbol} price at {slice.time}: {tick.price}")
+ public override void OnData(Slice slice)
+{
+ foreach (var kvp in slice.Bars)
+ {
+ var symbol = kvp.Key;
+ var tradeBar = kvp.Value;
+ Log($"{symbol} price at {slice.Time}: {tradeBar.Close}");
+ }
+
+ foreach (var kvp in slice.QuoteBars)
+ {
+ var symbol = kvp.Key;
+ var quoteBar = kvp.Value;
+ Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
+ }
+
+ foreach (var kvp in slice.Ticks)
+ {
+ var symbol = kvp.Key;
+ var ticks = kvp.Value;
+ foreach (var tick in ticks)
+ {
+ Log($"{symbol} price at {slice.Time}: {tick.Price}");
+ }
+ }
+}
+
+ + For more information about accessing Crypto data, see + + Handling Data + + . +
+ + + +
+ To get historical Binance US Crypto Price data, call the
+
+ History
+
+
+ history
+
+ method with the Crypto
+
+ Symbol
+
+ . If there is no data in the period you request, the history result is empty.
+
# DataFrame +history_df = self.history(self.btcbusd, 100, Resolution.DAILY) + +# TradeBar objects +history_trade_bars = self.history[TradeBar](self.btcbusd, 100, Resolution.MINUTE) + +# QuoteBar objects +history_quote_bars = self.history[QuoteBar](self.btcbusd, 100, Resolution.MINUTE) + +# Tick objects +history_ticks = self.history[Tick](self.btcbusd, timedelta(seconds=10), Resolution.TICK)+
// TradeBar objects +var historyTradeBars = History(_symbol, 100, Resolution.Daily); + +// QuoteBar objects +var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); + +// Tick objects +var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);+
+ For more information about historical data, see + + History Requests + + . +
+ + + +
+ To select a dynamic universe of Binance US Crypto pairs, call the
+
+ AddUniverse
+
+
+ add_universe
+
+ method with a
+
+ CryptoUniverse
+
+ object. A
+
+ Crypto universe
+
+ uses a selection function to select Crypto pairs based on their OHLCV and dollar volume of the previous day as of midnight Coordinated Universal Time (UTC).
+
def initialize(self) -> None: + self.universe_settings.asynchronous = True + self.set_brokerage_model(BrokerageName.BINANCE_US, AccountType.CASH) + self._universe = self.add_universe(CryptoUniverse.binance_us(self.universe_selection_filter)) + +def universe_selection_filter(self, universe_day): + return [c.symbol for c in universe_day if c.volume >= 100 and c.volume_in_usd > 10000]+
public override void Initialize()
+{
+ UniverseSettings.Asynchronous = true;
+ SetBrokerageModel(BrokerageName.BinanceUS, AccountType.Cash);
+ _universe = AddUniverse(CryptoUniverse.BinanceUS(UniverseSelectionFilter));
+}
+
+private IEnumerable<Symol> UniverseSelectionFilter(IEnumerable<CryptoUniverse> universeDay)
+{
+ return from c in universeDay
+ where c.Volume >= 100m && c.VolumeInUsd > 10000m
+ select c.Symbol;
+}
+ + For more information about universe settings, see + + Settings + + . +
+ + + ++ You can get historical universe data in an algorithm and in the Research Environment. +
+
+ To get historical universe data in an algorithm, call the
+
+ History
+
+
+ history
+
+ method with the
+
+ Universe
+
+ object, and the lookback period. If there is no data in the period you request, the history result is empty.
+
var history = History(_universe, 30, Resolution.Daily);
+foreach (var universeDay in history)
+{
+ foreach (CryptoUniverse universeItem in universeDay)
+ {
+ Log($"{universeItem.Symbol} price at {universeItem.EndTime}: {universeItem.Close}");
+ }
+}
+ # DataFrame example where the columns are the CryptoUniverse attributes:
+history_df = self.history(self._universe, 30, Resolution.DAILY, flatten=True)
+
+# Series example where the values are lists of CryptoUniverse objects:
+history = self.history(self._universe, 30, Resolution.DAILY)
+for (univere_symbol, time), universe_day in history.items():
+ for universe_item in universe_day:
+ self.log(f"{universe_item.symbol} price at {universe_item.end_time}: {universe_item.close}")
+
+ To get historical universe data in research, call the
+
+ UniverseHistory
+
+
+ universe_history
+
+ method with the
+
+ Universe
+
+ object, and the lookback period. The
+
+ UniverseHistory
+
+
+ universe_history
+
+ returns the filtered universe. If there is no data in the period you request, the history result is empty.
+
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
+foreach (var universeDay in universeHistory)
+{
+ foreach (CryptoUniverse universeItem in universeDay)
+ {
+ Console.WriteLine($"{universeItem.Symbol} price at {universeItem.EndTime}: {universeItem.Close}");
+ }
+}
+ # DataFrame example where the columns are the CryptoUniverse attributes:
+history_df = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
+
+# Series example where the values are lists of CryptoUniverse objects:
+universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
+for (univere_symbol, time), universe_day in universe_history.items():
+ for universe_item in universe_day:
+ print(f"{universe_item.symbol} price at {universe_item.end_time}: {universe_item.close}")
+
+ You can call the
+
+ History
+
+
+ history
+
+ method in Research.
+
+ To unsubscribe from a Crypto pair that you added with the
+
+ AddCrypto
+
+
+ add_crypto
+
+ method, call the
+
+ RemoveSecurity
+
+
+ remove_security
+
+ method.
+
self.remove_security(self.btcbusd)+
RemoveSecurity(_symbol);+
+ The
+
+ RemoveSecurity
+
+
+ remove_security
+
+ method cancels your open orders for the security and liquidates your holdings in the
+
+ virtual pair
+
+ .
+
+ The following table shows the available Cryptocurrency pairs: +
++ The Coinbase Crypto Price dataset enables you to accurately design strategies for Cryptocurrencies. Examples include the following strategies: +
++ The following example algorithm buys and holds Bitcoin through the Coinbase exchange: +
+from AlgorithmImports import *
+
+
+class CoinAPIDataAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ self.universe_settings.asynchronous = True
+ self.set_cash(100_000)
+ # Coinbase accepts Cash account type only. AccountType.MARGIN
+ # results in an exception.
+ self.set_brokerage_model(BrokerageName.COINBASE, AccountType.CASH)
+ # Add BTCUSD data.
+ self._btc = self.add_crypto("BTCUSD", Resolution.MINUTE, Market.COINBASE)
+ # Historical data
+ history = self.history(self._btc.symbol, 30, Resolution.DAILY)
+ # Add a Crypto universe that selects Crypto pairs on Coinbase.
+ universe = self.add_universe(CryptoUniverse.coinbase(self._select_assets))
+ # Historical Universe data
+ universe_history = self.history(universe, 30, Resolution.DAILY)
+ for (universe_symbol, time), universe_day in universe_history.items():
+ for universe_item in universe_day:
+ symbol = universe_item.symbol
+ price = universe_item.close
+
+ def _select_assets(self, universe_day):
+ # Filter for materially traded Crypto pairs with significant
+ # size and dollar volume, assuming higher capital flow in for
+ # higher return.
+ return [universe_item.symbol for universe_item in universe_day
+ if universe_item.volume >= 100
+ and universe_item.volume_in_usd > 10_000_000]
+
+ def on_data(self, slice: Slice) -> None:
+ # Speculate-invest all available free cash on BTCUSD, repecting
+ # the order quantity restrictions to avoid invalid orders.
+ if self.portfolio.cash_book['BTC'].amount != 0:
+ return
+ # Define a buffer so that we can scale down the order size,
+ # avoiding trading errors.
+ buffer = max(
+ CoinbaseFeeModel.TAKER_ADVANCED_1,
+ self.settings.free_portfolio_value_percentage
+ )
+ quantity = (
+ self.portfolio.cash_book['USD'].amount
+ / self._btc.ask_price
+ * (1-buffer)
+ )
+ # Check if the quantity exceeds the minimum order size. On
+ # Coinbase, the minimum order size is measured in the base
+ # currency (BTC in this case).
+ if abs(quantity) < self._btc.symbol_properties.minimum_order_size:
+ return
+ self.market_order(self._btc, quantity)
+ public class CoinAPIDataAlgorithm : QCAlgorithm
+{
+ private Crypto _btc;
+
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ UniverseSettings.Asynchronous = true;
+ SetCash(100000);
+ // Coinbase accepts Cash account type only. AccountType.Margin
+ // results in an exception.
+ SetBrokerageModel(BrokerageName.Coinbase, AccountType.Cash);
+ // Add BTCUSD data.
+ _btc = AddCrypto("BTCUSD", Resolution.Minute, Market.Coinbase);
+ // Historical data
+ var history = History(_btc.Symbol, 30, Resolution.Daily);
+ // Add a Crypto universe that selects trading pairs on Coinbase.
+ var universe = AddUniverse(CryptoUniverse.Coinbase(SelectAssets));
+ // Historical Universe data
+ var universeHistory = History(universe, 30, Resolution.Daily);
+ foreach (var universeDay in universeHistory)
+ {
+ foreach (CryptoUniverse universeItem in universeDay)
+ {
+ var symbol = universeItem.Symbol;
+ var price = universeItem.Close;
+ }
+ }
+ }
+
+ private IEnumerable<Symbol> SelectAssets(IEnumerable<CryptoUniverse> universeDay)
+ {
+ // Filter for materially traded Crypto pairs with significant
+ // size and dollar volume, assuming higher capital flow in for
+ // higher return.
+ return from universeItem in universeDay
+ where universeItem.Volume >= 100m
+ && universeItem.VolumeInUsd > 10000000m
+ select universeItem.Symbol;
+ }
+
+ public override void OnData(Slice slice)
+ {
+ // Speculate-invest all available free cash on BTCUSD, repecting
+ // the order quantity restrictions to avoid invalid orders.
+ if (Portfolio.CashBook["BTC"].Amount != 0)
+ {
+ return;
+ }
+ // Define a buffer so that we can scale down the order size,
+ // avoiding trading errors.
+ var buffer = Math.Max(CoinbaseFeeModel.TakerAdvanced1, Settings.FreePortfolioValuePercentage);
+ var quantity = Portfolio.CashBook["USD"].Amount / _btc.AskPrice * (1-buffer);
+ // Check if the quantity exceeds the minimum order size. On
+ // Coinbase, the minimum order size is measured in the base
+ // currency (BTC in this case).
+ if (Math.Abs(quantity) < _btc.SymbolProperties.MinimumOrderSize)
+ {
+ return;
+ }
+ MarketOrder(_btc, quantity);
+ }
+}
+ + The following example algorithm creates a dynamic universe of Crypto pairs on the Coinbase exchange and then forms a equal-weighted portfolio of all the pairs in the universe: +
+from AlgorithmImports import *
+
+
+class CoinAPIDataAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2020, 6, 1)
+ self.set_end_date(2021, 2, 1)
+ self.set_cash(100000)
+ self.settings.free_portfolio_value_percentage = 0.05
+ # Warm up the security with the last known price to avoid conversion error
+ self.settings.seed_initial_prices = True
+ self.universe_settings.asynchronous = True
+ self.universe_settings.resolution = Resolution.MINUTE
+ # Add Crypto Universe Selection that select crypto pairs in Coinbase exchange
+ self.add_universe(CryptoUniverse.coinbase(self._select_assets))
+ # Get the pairs on Coinbase that have USD as the quote currency.
+ self._market_pairs = [
+ x.key.symbol
+ for x in self.symbol_properties_database.get_symbol_properties_list(Market.COINBASE)
+ if x.value.quote_currency == self.account_currency
+ ]
+ self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(hours=4), 0.025, None))
+ # Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
+ self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
+
+ def _select_assets(self, universe_day: List[CryptoUniverse]) -> List[Symbol]:
+ # Select pairs where the quote currency is USD.
+ pairs = [c for c in universe_day if c.symbol.value in self._market_pairs]
+ # Filter for materially traded crypto pairs with significant dollar volume, assuming higher capital flow in for higher return.
+ pairs = sorted(pairs, key=lambda c: c.volume_in_usd)[-3:]
+ return [c.symbol for c in pairs]
+
+ def on_securities_changed(self, changes: SecurityChanges) -> None:
+ for security in changes.added_securities:
+ # Historical data
+ history = self.history(security.symbol, 30, Resolution.DAILY)
+ self.debug(f"We got {len(history)} items from our history request")
+ public class CoinAPIDataAlgorithm : QCAlgorithm
+{
+ private List<string> _marketPairs;
+
+ public override void Initialize()
+ {
+ SetStartDate(2020, 6, 1);
+ SetEndDate(2021, 2, 1);
+ SetCash(100000);
+ Settings.FreePortfolioValuePercentage = 0.05m;
+ // Warm up the security with the last known price to avoid conversion error
+ Settings.SeedInitialPrices = true;
+ UniverseSettings.Asynchronous = true;
+ UniverseSettings.Resolution = Resolution.Minute;
+ // Add Crypto Universe Selection that select crypto pairs in Coinbase exchange
+ AddUniverse(CryptoUniverse.Coinbase(SelectAssets));
+ // Get the pairs on Coinbase that have USD as the quote currency.
+ _marketPairs = SymbolPropertiesDatabase.GetSymbolPropertiesList(Market.Coinbase)
+ .Where(x => x.Value.QuoteCurrency == AccountCurrency)
+ .Select(x => x.Key.Symbol)
+ .ToList();
+ AddAlpha( new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromHours(4), 0.025, null) );
+ // Equally invest to evenly dissipate the capital concentration risk of inidividual crypto pair
+ SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
+ }
+
+ private IEnumerable<Symbol> SelectAssets(IEnumerable<CryptoUniverse> universeDay)
+ {
+ // Select pairs where the quote currency is USD.
+ return universeDay.Where(c => _marketPairs.Contains(c.Symbol.Value))
+ // Filter for materially traded crypto pairs with significant size and dollar volume, assuming higher capital flow in for higher return
+ .OrderBy(c => c.VolumeInUsd)
+ .TakeLast(3)
+ .Select(c => c.Symbol);
+ }
+
+ public override void OnSecuritiesChanged(SecurityChanges changes)
+ {
+ foreach(var security in changes.AddedSecurities)
+ {
+ // Historical data
+ var history = History(security.Symbol, 30, Resolution.Daily);
+ Debug($"We got {history.Count()} items from our history request");
+ }
+ }
+}
+ + The following example lists crypto-currency pairs with the greatest dollar volume in the Coinbase exchange: +
+var qb = new QuantBook();
+
+// Add Cryptocurrency pair
+var symbol = qb.AddCrypto("BTCUSDT", market:Market.Coinbase).Symbol;
+
+// Historical data
+var history = qb.History(symbol, 30, Resolution.Daily);
+foreach (var bar in history)
+{
+ Console.WriteLine($"{bar.EndTime} {bar}");
+}
+
+// Add Crypto Universe Selection
+IEnumerable<Symbol> UniverseSelectionFilter(IEnumerable<CryptoUniverse> universeDay)
+{
+ return universeDay
+ .Where(x => x.VolumeInUsd != null && x.VolumeInUsd > 10000m)
+ .OrderByDescending(x => x.VolumeInUsd)
+ .Take(5)
+ .Select(x => x.Symbol);
+}
+var universe = qb.AddUniverse(CryptoUniverse.Coinbase(UniverseSelectionFilter));
+
+// Historical Universe data
+var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
+foreach (var universeDay in universeHistory)
+{
+ Console.WriteLine($"=== {universeDay.First().EndTime} ===");
+ foreach (CryptoUniverse universeItem in universeDay.OrderByDescending(x => x.VolumeInUsd))
+ {
+ Console.WriteLine($"{universeItem.Symbol}: {universeItem.VolumeInUsd}");
+ }
+}
+ qb = QuantBook()
+
+# Add Cryptocurrency pair
+symbol = qb.add_crypto("BTCUSDT", market=Market.COINBASE).symbol
+
+# Historical data
+history = qb.history(symbol, 30, Resolution.DAILY)
+for (symbol, time), row in history.iterrows():
+ print(f'{time} {symbol} {row.close}')
+
+# Add Crypto Universe Selection
+def universe_selection_filter(universe_day):
+ selected = sorted([x for x in universe_day
+ if x.volume_in_usd and x.volume_in_usd > 10000],
+ key=lambda x: x.volume_in_usd, reverse=True)[:5]
+ return [x.symbol for x in selected]
+
+universe = qb.add_universe(CryptoUniverse.coinbase(universe_selection_filter))
+
+# Historical Universe data
+history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
+for (univere_symbol, time), universe_day in history.items():
+ print(f'=== {time} ===')
+ for universe_item in sorted(universe_day, key=lambda x: x.volume_in_usd, reverse=True):
+ print(f"{universe_item.symbol}: {universe_item.volume_in_usd}")
+
+ The Coinbase Crypto Price dataset provides
+
+ TradeBar
+
+ ,
+
+ QuoteBar
+
+ ,
+
+ Tick
+
+ , and
+
+ CryptoUniverse
+
+ objects.
+
+
+ TradeBar
+
+ objects have the following attributes:
+
+
+ QuoteBar
+
+ objects have the following attributes:
+
+
+ Tick
+
+ objects have the following attributes:
+
+
+ CryptoUniverse
+
+ objects have the following attributes:
+
+ +
+ The FOREX Data by QuantConnect serves 71 + + foreign exchange + + (FOREX) pairs, starts on various dates from January 2007, and is delivered on any frequency from tick to daily. This dataset is created by QuantConnect processing raw tick data from OANDA. +
++ FOREX data does not include ask and bid sizes. +
++ For more information about the FOREX Data dataset, including CLI commands and pricing, see the + + dataset listing + + . +
++
+ + + ++ QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month. +
+ + + ++ The following snippet demonstrates how to request data from the FOREX dataset: +
+self.eurusd = self.add_forex("EURUSD", Resolution.DAILY).symbol
+ _symbol = AddForex("EURUSD", Resolution.Daily).Symbol;
+ + The following table describes the dataset properties: +
+| + Property + | ++ Value + | +
|---|---|
| + Start Date + | ++ January 2007 + | +
| + Asset Coverage + | ++ 71 Currency pairs + | +
| + Data Density + | ++ Dense + | +
| + Resolution + | ++ Tick, Second, Minute, Hour, & Daily + | +
| + Timezone + | ++ UTC + | +
| + Market Hours + | ++ + Always Open + + , except from Friday 5 PM EST to Sunday 5 PM EST + | +
+ To add FOREX data to your algorithm, call the
+
+ AddForex
+
+
+ add_forex
+
+ method. Save a reference to the Forex
+
+ Symbol
+
+ so you can access the data later in your algorithm.
+
+class ForexAlgorithm (QCAlgorithm):
+ def initialize(self) -> None:
+ self.set_start_date(2019, 2, 20)
+ self.set_end_date(2019, 2, 21)
+ self.set_cash(100000)
+
+ self.eurusd = self.add_forex('EURUSD', Resolution.MINUTE).symbol
+
+ self.set_benchmark(self.eurusd)
+
+ public class ForexAlgorithm : QCAlgorithm
+{
+ private Symbol _symbol;
+
+ public override void Initialize()
+ {
+ SetStartDate(2019, 2, 20);
+ SetEndDate(2019, 2, 21);
+ SetCash(100000);
+
+ _symbol = AddForex("EURUSD", Resolution.Minute).Symbol;
+
+ SetBenchmark(_symbol);
+ }
+}
+ + For more information about creating Forex subscriptions, see + + Requesting Data + + . +
+ + + +
+ To get the current Forex data, index the
+
+ QuoteBars
+
+
+ quote_bars
+
+ , or
+
+ Ticks
+
+
+ ticks
+
+ properties of the current
+
+
+ Slice
+
+
+ with the Forex
+
+ Symbol
+
+ . Slice objects deliver unique events to your algorithm as they happen, but the
+
+ Slice
+
+ may not contain data for your security at every time step. To avoid issues, check if the
+
+ Slice
+
+ contains the data you want before you index it.
+
def on_data(self, slice: Slice) -> None:
+ if self.eurusd in slice.quote_bars:
+ quote_bar = slice.quote_bars[self.eurusd]
+ self.log(f"{self.eurusd} bid at {slice.time}: {quote_bar.bid.close}")
+
+ if self.eurusd in slice.ticks:
+ ticks = slice.ticks[self.eurusd]
+ for tick in ticks:
+ self.log(f"{self.eurusd} price at {slice.time}: {tick.price}")
+ public override void OnData(Slice slice)
+{
+ if (slice.QuoteBars.ContainsKey(_symbol))
+ {
+ var quoteBar = slice.QuoteBars[_symbol];
+ Log($"{_symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
+ }
+
+ if (slice.Ticks.ContainsKey(_symbol))
+ {
+ var ticks = slice.Ticks[_symbol];
+ foreach (var tick in ticks)
+ {
+ Log($"{_symbol} price at {slice.Time}: {tick.Price}");
+ }
+ }
+}
+
+
+ You can also iterate through all of the data objects in the current
+
+ Slice
+
+ .
+
def on_data(self, slice: Slice) -> None:
+ for symbol, quote_bar in slice.quote_bars.items():
+ self.log(f"{symbol} bid at {slice.time}: {quote_bar.bid.close}")
+
+ for symbol, ticks in slice.ticks.items():
+ for tick in ticks:
+ self.log(f"{symbol} price at {slice.time}: {tick.price}")
+ public override void OnData(Slice slice)
+{
+ foreach (var kvp in slice.QuoteBars)
+ {
+ var symbol = kvp.Key;
+ var quoteBar = kvp.Value;
+ Log($"{symbol} bid at {slice.Time}: {quoteBar.Bid.Close}");
+ }
+
+ foreach (var kvp in slice.Ticks)
+ {
+ var symbol = kvp.Key;
+ var ticks = kvp.Value;
+ foreach (var tick in ticks)
+ {
+ Log($"{symbol} price at {slice.Time}: {tick.Price}");
+ }
+ }
+}
+
+ + For more information about accessing Forex data, see + + Handling Data + + . +
+ + + +
+ To get historical Forex data, call the
+
+ History
+
+
+ history
+
+ method with the Forex
+
+ Symbol
+
+ . If there is no data in the period you request, the history result is empty.
+
# DataFrame +history_df = self.history(self.eurusd, 100, Resolution.MINUTE) + +# QuoteBar objects +history_quote_bars = self.history[QuoteBar](self.eurusd, 100, Resolution.MINUTE) + +# Tick objects +history_ticks = self.history[Tick](self.eurusd, timedelta(seconds=10), Resolution.TICK)+
// QuoteBar objects +var historyQuoteBars = History<QuoteBar>(_symbol, 100, Resolution.Minute); + +// Tick objects +var historyTicks = History<Tick>(_symbol, TimeSpan.FromSeconds(10), Resolution.Tick);+
+ For more information about historical data, see + + History Requests + + . +
+ + + +
+ To remove a Forex pair subscription, call the
+
+ RemoveSecurity
+
+
+ remove_security
+
+ method.
+
self.remove_security(self.eurusd)+
RemoveSecurity(_symbol);+
+ The
+
+ RemoveSecurity
+
+
+ remove_security
+
+ method cancels your open orders for the security and liquidates your holdings.
+
+ The following table shows the available Forex pairs: +
++ Before May 14 2021, this dataset included legacy data without all the information. Only the following are valid: + + price_per_share, shares, and shares_owned_following + + + PricePerShare, Shares, and SharesOwnedFollowing + + . +
@@ -266011,61 +268306,60 @@public class QuiverInsiderTradingAlgorithm : QCAlgorithm
{
- private Symbol _symbol, _datasetSymbol;
+ private Equity _equity;
+ private Symbol _datasetSymbol;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
- _symbol = AddEquity("AAPL").Symbol;
- // Subscribe to insider trade data for AAPL to generate trade signal
- _datasetSymbol = AddData<QuiverInsiderTrading>(_symbol).Symbol;
-
- // history request
- var history = History<QuiverInsiderTrading>(new[] {_datasetSymbol}, 10, Resolution.Daily);
+ _equity = AddEquity("AAPL", Resolution.Daily);
+ // Subscribe to insider trade data for AAPL to generate trade signals.
+ _datasetSymbol = AddData<QuiverInsiderTrading>(_equity.Symbol).Symbol;
+ // Warm up the custom data subscription with recent history.
+ var history = History<QuiverInsiderTrading>([_datasetSymbol], 10, Resolution.Daily);
Debug($"We got {history.Count()} items from historical data request of {_datasetSymbol}.");
}
- public override void OnData(Slice slice)
+ public override void OnData(Slice data)
{
- // Trade only base on insider trade data
- foreach (var kvp in slice.Get<QuiverInsiderTrading>())
+ // Trade only from insider trade data.
+ foreach (var kvp in data.Get<QuiverInsiderTrading>())
{
foreach (QuiverInsiderTrading insiderTrade in kvp.Value)
{
- // Any buy insider trade will result in buying, assuming insider have confidence in stock price with more informed information and projection
+ // Buy when insiders purchase shares because it may signal confidence in future prices.
if (insiderTrade.Shares > 0)
{
- SetHoldings(_symbol, 1);
+ SetHoldings(_equity.Symbol, 1);
}
- // Any sell insider trade will result in liquidation, assuming insiders believe the stock price has reached maximum or poor future confidence
+ // Liquidate when insiders sell shares because it may signal weaker future confidence.
else
{
- Liquidate(_symbol);
+ Liquidate(_equity.Symbol);
}
}
}
@@ -266766,57 +269060,50 @@
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
-
- # Requesting data per underlying data to subscribe to updated congress members' trade information
- aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
- quiver_congress_symbol = self.add_data(QuiverCongress, aapl).symbol
-
- # Historical data
+ # Subscribe to Congress trading updates for the underlying equity.
+ equity = self.add_equity("AAPL", Resolution.DAILY)
+ quiver_congress_symbol = self.add_data(QuiverCongress, equity).symbol
+ # Warm up the custom dataset with recent Congress trading history.
history = self.history(QuiverCongress, quiver_congress_symbol, 60, Resolution.DAILY)
- self.debug(f"We got {len(history)} items from our history request");
-
- def on_data(self, slice: Slice) -> None:
- congress_by_symbol = slice.Get(QuiverCongress)
+ self.debug(f"We got {len(history)} items from our history request")
- # Determine net direction of Congress trades for each security to estimate the sentiment direction due to political factor
+ def on_data(self, data: Slice) -> None:
+ congress_by_symbol = data.get(QuiverCongress)
+ # Estimate sentiment for each security from the net direction of Congress trades.
net_quantity_by_symbol = {}
for symbol, points in congress_by_symbol.items():
symbol = symbol.underlying
if symbol not in net_quantity_by_symbol:
net_quantity_by_symbol[symbol] = 0
- # Voting weight is by order size
+ # Weight each vote by order size.
for point in points:
net_quantity_by_symbol[symbol] += (1 if point.transaction == OrderDirection.BUY else -1) * point.amount
-
for symbol, net_quantity in net_quantity_by_symbol.items():
if net_quantity == 0:
self.liquidate(symbol)
continue
- # Buy when Congress members have bought, short otherwise
+ # Follow net Congress buying direction and short net selling direction.
self.set_holdings(symbol, 1 if net_quantity > 0 else -1)
public class QuiverCongressDataAlgorithm : QCAlgorithm
{
+
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
-
- // Requesting data per underlying data to subscribe to updated congress members' trade information
- var aapl = AddEquity("AAPL", Resolution.Daily).Symbol;
- var quiverCongressSymbol = AddData<QuiverCongress>(aapl).Symbol;
-
- // Historical data
+ // Subscribe to Congress trading updates for the underlying equity.
+ var equity = AddEquity("AAPL", Resolution.Daily);
+ var quiverCongressSymbol = AddData<QuiverCongress>(equity).Symbol;
+ // Warm up the custom dataset with recent Congress trading history.
var history = History<QuiverCongress>(quiverCongressSymbol, 60, Resolution.Daily);
Debug($"We got {history.Count()} items from our history request");
}
-
- public override void OnData(Slice slice)
+ public override void OnData(Slice data)
{
- var congressBySymbol = slice.Get<QuiverCongress>();
-
- // Determine net direction of Congress trades for each security to estimate the sentiment direction due to political factor
+ var congressBySymbol = data.Get<QuiverCongress>();
+ // Estimate sentiment for each security from the net direction of Congress trades.
var netQuantityBySymbol = new Dictionary<Symbol, decimal>();
foreach (var (s, points) in congressBySymbol)
{
@@ -266825,13 +269112,12 @@
{
netQuantityBySymbol[symbol] = 0m;
}
- // Voting weight is by order size
- foreach(QuiverCongressDataPoint point in points)
+ // Weight each vote by order size.
+ foreach (QuiverCongressDataPoint point in points)
{
netQuantityBySymbol[symbol] += (point.Transaction == OrderDirection.Buy ? 1 : -1) * (point.Amount ?? 0m);
}
}
-
foreach (var (symbol, netQuantity) in netQuantityBySymbol)
{
if (netQuantity == 0)
@@ -266839,7 +269125,7 @@
Liquidate(symbol);
continue;
}
- // Buy when Congress members have bought, short otherwise
+ // Follow net Congress buying direction and short net selling direction.
SetHoldings(symbol, netQuantity > 0 ? 1 : -1);
}
}
@@ -266861,7 +269147,9 @@
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
- # Filter according to QuiverCongress data
+ self.settings.seed_initial_prices = True
+ self.universe_settings.minimum_time_in_universe = timedelta(days=7)
+ # Add the Quiver Congress universe.
self.add_universe(QuiverQuantCongressUniverse, "QuiverQuantCongresssUniverse", Resolution.DAILY, self.universe_selection)
self.add_alpha(CongressAlphaModel())
self.set_portfolio_construction(InsightWeightingPortfolioConstructionModel(lambda time: None))
@@ -266869,71 +269157,56 @@
self.set_execution(ImmediateExecutionModel())
def universe_selection(self, alt_coarse: List[QuiverQuantCongressUniverse]) -> List[Symbol]:
- # Only include the ones with large size buy, since they are estimated to be materially confident to go up
- return [d.symbol for d in alt_coarse if d.amount > 10_000 and d.transaction == OrderDirection.BUY]
-
+ # Return all symbols from the Quiver Congress universe.
+ return [d.symbol for d in alt_coarse]
+
class CongressAlphaModel(AlphaModel):
-
- symbol_data_by_symbol = {}
- insight_by_symbol = {}
+ _securities = []
+ _insight_by_asset = {}
def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- congress_by_symbol = slice.get(QuiverCongress)
- if congress_by_symbol:
- self.insight_by_symbol.clear()
- # Determine net direction of Congress trades for each security to estimate the sentiment direction due to political factor
- net_quantity_by_symbol = {}
- for symbol, points in congress_by_symbol.items():
- symbol = symbol.underlying
- if symbol not in net_quantity_by_symbol:
- net_quantity_by_symbol[symbol] = 0
- # Voting weight is by order size
- for point in points:
- net_quantity_by_symbol[symbol] += (1 if point.transaction == OrderDirection.BUY else -1) * point.amount
-
- for symbol, net_quantity in net_quantity_by_symbol.items():
- # Buy when Congress members have bought, as they may have advance information to be confident to the return direction
- if net_quantity > 0 and not algorithm.portfolio[symbol].is_long:
+ congress_data_by_asset = slice.get(QuiverCongress)
+ if congress_data_by_asset:
+ self._insight_by_asset.clear()
+ net_quantity_by_asset = {}
+ for congress_data_symbol, congress_data in congress_data_by_asset.items():
+ security = algorithm.securities[congress_data_symbol.underlying]
+ if security not in net_quantity_by_asset:
+ net_quantity_by_asset[security] = 0
+ for point in congress_data:
+ net_quantity_by_asset[security] += (1 if point.transaction == OrderDirection.BUY else -1) * point.amount
+ for security, net_quantity in net_quantity_by_asset.items():
+ # Emit an up insight when Congress members are net buyers.
+ if net_quantity > 0 and not security.holdings.is_long:
direction = InsightDirection.UP
- # Short sell when Congress members have sold
- elif net_quantity < 0 and not algorithm.portfolio[symbol].is_short:
+ # Emit a down insight when Congress members are net sellers.
+ elif net_quantity < 0 and not security.holdings.is_short:
direction = InsightDirection.DOWN
else:
continue
- self.insight_by_symbol[symbol] = Insight.price(symbol, timedelta(7), direction, weight=0.5)
+ self._insight_by_asset[security] = Insight.price(security, timedelta(7), direction, weight=0.5)
# To avoid error messages, emit the insights when the algorithm has a price for the asset.
return [
- self.insight_by_symbol.pop(symbol)
- for symbol, i in list(self.insight_by_symbol.items())
- if algorithm.securities[symbol].price
+ self._insight_by_asset.pop(security)
+ for security in list(self._insight_by_asset.keys())
+ if security.price
]
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for security in changes.added_securities:
- symbol = security.symbol
- self.symbol_data_by_symbol[symbol] = SymbolData(algorithm, symbol)
-
+ self._securities.append(security)
+ # Add the Quiver Congress subscription for the security.
+ security.congress_data = algorithm.add_data(QuiverCongress, security, Resolution.DAILY)
+ history = algorithm.history(QuiverCongress, security.congress_data, 14, Resolution.DAILY)
+ algorithm.debug(f"We got {len(history)} items from our history request for {security}")
for security in changes.removed_securities:
- symbol_data = self.symbol_data_by_symbol.pop(security.symbol, None)
- if symbol_data:
- symbol_data.dispose()
-
-
-class SymbolData:
-
- def __init__(self, algorithm: QCAlgorithm, symbol: Symbol):
- self.algorithm = algorithm
-
- # Requesting data per underlying data to subscribe to updated congress members' trade information
- self.quiver_congress_symbol = algorithm.add_data(QuiverCongress, symbol).symbol
-
- # Historical data
- history = algorithm.history(self.quiver_congress_symbol, 14, Resolution.DAILY)
-
- def dispose(self) -> None:
- # Unsubscribe from Quiver Congress feed for this security to release computational resources
- self.algorithm.remove_security(self.quiver_congress_symbol)
+ if security in self._securities:
+ if security in self._insight_by_asset:
+ self._insight_by_asset.pop(security)
+ # Remove the Quiver Congress subscription for the security.
+ algorithm.remove_security(security.congress_data)
+ self._securities.remove(security)
public class QuiverCongressDataAlgorithm : QCAlgorithm
{
public override void Initialize()
@@ -266941,14 +269214,10 @@
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
- // Filter according to QuiverCongress data
- AddUniverse<QuiverQuantCongressUniverse>("QuiverQuantCongresssUniverse", Resolution.Daily, altCoarse =>
- {
- // Only include the ones with large size buy, since they are estimated to be materially confident to go up
- return from d in altCoarse.OfType<QuiverCongressDataPoint>()
- where d.Amount > 10000 && d.Transaction == OrderDirection.Buy
- select d.Symbol;
- });
+ Settings.SeedInitialPrices = true;
+ UniverseSettings.MinimumTimeInUniverse = TimeSpan.FromDays(7);
+ // Add the Quiver Congress universe.
+ AddUniverse<QuiverQuantCongressUniverse>(altCoarse => altCoarse.Select(d => d.Symbol));
AddAlpha(new CongressAlphaModel());
SetPortfolioConstruction(new InsightWeightingPortfolioConstructionModel(time => null));
AddRiskManagement(new NullRiskManagementModel());
@@ -266958,41 +269227,41 @@
public class CongressAlphaModel : AlphaModel
{
- private Dictionary<Symbol, SymbolData> _symbolDataBySymbol = new ();
- private Dictionary<Symbol, Insight> _insightBySymbol = new ();
+ private readonly List<Security> _securities = [];
+ private readonly Dictionary<Security, Insight> _insightByAsset = [];
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
{
- var congressBySymbol = slice.Get<QuiverCongress>();
- if (congressBySymbol.Count > 0)
+ var congressDataByAsset = slice.Get<QuiverCongress>();
+ if (congressDataByAsset.Count > 0)
{
- _insightBySymbol.Clear();
- // Determine net direction of Congress trades for each security to estimate the sentiment direction due to political factor
- var netQuantityBySymbol = new Dictionary<Symbol, decimal>();
- foreach (var (s, points) in congressBySymbol)
+ _insightByAsset.Clear();
+ // Aggregate the net Congress trade quantity for each security.
+ var netQuantityByAsset = new Dictionary<Security, decimal>();
+ foreach (var (congressDataSymbol, congressData) in congressDataByAsset)
{
- var symbol = s.Underlying;
- if (!netQuantityBySymbol.ContainsKey(symbol))
+ var security = algorithm.Securities[congressDataSymbol.Underlying];
+ if (!netQuantityByAsset.ContainsKey(security))
{
- netQuantityBySymbol[symbol] = 0m;
+ netQuantityByAsset[security] = 0m;
}
- // Voting weight is by order size
- foreach(QuiverCongressDataPoint point in points)
+ // Weight each transaction by its reported amount.
+ foreach (QuiverCongressDataPoint point in congressData)
{
- netQuantityBySymbol[symbol] += (point.Transaction == OrderDirection.Buy ? 1 : -1) * (point.Amount ?? 0m);
+ netQuantityByAsset[security] += (point.Transaction == OrderDirection.Buy ? 1 : -1) * (point.Amount ?? 0m);
}
}
- foreach (var (symbol, netQuantity) in netQuantityBySymbol)
+ foreach (var (security, netQuantity) in netQuantityByAsset)
{
- // Buy when Congress members have bought, as they may have advance information to be confident to the return direction
+ // Emit an up insight when Congress members are net buyers.
InsightDirection direction;
- if (netQuantity > 0 && !algorithm.Portfolio[symbol].IsLong)
+ if (netQuantity > 0 && !security.Holdings.IsLong)
{
direction = InsightDirection.Up;
}
- // Short sell when Congress members have sold
- else if (netQuantity < 0 && !algorithm.Portfolio[symbol].IsShort)
+ // Emit a down insight when Congress members are net sellers.
+ else if (netQuantity < 0 && !security.Holdings.IsShort)
{
direction = InsightDirection.Down;
}
@@ -267000,16 +269269,17 @@
{
continue;
}
- _insightBySymbol[symbol] = Insight.Price(symbol, TimeSpan.FromDays(7), direction, weight: 0.5);
+ _insightByAsset[security] = Insight.Price(security.Symbol, TimeSpan.FromDays(7), direction, weight: 0.5);
}
}
- return _insightBySymbol.Keys
- .ToList() // snapshot keys
- .Where(symbol => algorithm.Securities[symbol].Price != 0m)
- .Select(symbol => {
- var val = _insightBySymbol[symbol]; // capture value
- _insightBySymbol.Remove(symbol); // remove
- return val;
+ // To avoid error messages, emit the insights when the algorithm has a price for the asset.
+ return _insightByAsset.Keys
+ .ToList() // snapshot keys
+ .Where(security => security.Price != 0m)
+ .Select(security => {
+ var insight = _insightByAsset[security]; // capture value
+ _insightByAsset.Remove(security); // remove
+ return insight;
})
.ToList();
}
@@ -267018,44 +269288,26 @@
{
foreach (var security in changes.AddedSecurities)
{
- var symbol = security.Symbol;
- _symbolDataBySymbol.Add(symbol, new SymbolData(algorithm, symbol));
+ _securities.Add(security);
+ // Add the Quiver Congress subscription for the security.
+ var congressData = algorithm.AddData<QuiverCongress>(security.Symbol, Resolution.Daily);
+ security.Set("CongressData", congressData);
+ var history = algorithm.History<QuiverCongress>(congressData.Symbol, 14, Resolution.Daily);
+ algorithm.Debug($"We got {history.Count()} items from our history request for {security}");
}
foreach (var security in changes.RemovedSecurities)
{
- var symbol = security.Symbol;
- if (_symbolDataBySymbol.ContainsKey(symbol))
+ if (_securities.Contains(security))
{
- _symbolDataBySymbol[symbol].dispose();
- _symbolDataBySymbol.Remove(symbol);
+ _insightByAsset.Remove(security);
+ // Remove the Quiver Congress subscription for the security.
+ var congressData = security.Get<Security>("CongressData");
+ algorithm.RemoveSecurity(congressData.Symbol);
+ _securities.Remove(security);
}
}
}
-}
-
-public class SymbolData
-{
- private Symbol _quiverCongressSymbol;
- private QCAlgorithm _algorithm;
-
- public SymbolData(QCAlgorithm algorithm, Symbol symbol)
- {
- _algorithm = algorithm;
-
- // Requesting data per underlying data to subscribe to updated congress members' trade information
- _quiverCongressSymbol = algorithm.AddData<QuiverCongress>(symbol).Symbol;
-
- // Historical data
- var history = algorithm.History<QuiverCongress>(_quiverCongressSymbol, 60, Resolution.Daily);
- algorithm.Debug($"We got {history.Count()} items from our history request for {symbol} Quiver Congress data");
- }
-
- public void dispose()
- {
- // Unsubscribe from Quiver Congress feed for this security to release computational resources
- _algorithm.RemoveSecurity(_quiverCongressSymbol);
- }
}
RemoveSecurity(_datasetSymbol);
- If you subscribe to US Government Contracts data for assets in a dynamic universe, remove the dataset subscription when the asset leaves your universe. To view a common design pattern, see - - Track Security Changes - - . -
- - - -- The Quiver Quantitative US Government Contracts dataset enables you to create strategies using the latest information on government contracts activity. Examples include the following strategies: -
-- The following example algorithm buys Apple stock when they receive a new government contract worth over $50K. If they receive a new contract worth under $10K, the algorithm short sells Apple. -
-from AlgorithmImports import *
-
-
-class QuiverGovernmentContractAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
- # Subscribe to government contract data for AAPL to generate trade signal
- self.dataset_symbol = self.add_data(QuiverGovernmentContract, self.aapl).symbol
-
- # history request
- history = self.history(self.dataset_symbol, 10, Resolution.DAILY)
- self.debug(f"We got {len(history)} items from historical data request of {self.dataset_symbol}.")
-
- def on_data(self, slice: Slice) -> None:
- # Trade only base on government contract data
- for gov_contracts in slice.Get(QuiverGovernmentContract).values():
- # Buy if over 50000 government contract amount, suggesting a large income
- if any([gov_contract.amount > 50000 for gov_contract in gov_contracts]):
- self.set_holdings(self.aapl, 1)
- # Sell if below 10000 government contract amount, suggesting a smaller than usual income
- elif any([gov_contract.amount < 10000 for gov_contract in gov_contracts]):
- self.set_holdings(self.aapl, -1)
- public class QuiverGovernmentContractAlgorithm : QCAlgorithm
-{
- private Symbol _symbol, _datasetSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- _symbol = AddEquity("AAPL").Symbol;
- // Subscribe to government contract data for AAPL to generate trade signal
- _datasetSymbol = AddData<QuiverGovernmentContract>(_symbol).Symbol;
-
- // history request
- var history = History<QuiverGovernmentContract>(new[] {_datasetSymbol}, 10, Resolution.Daily);
- Debug($"We got {history.Count()} items from historical data request of {_datasetSymbol}.");
- }
-
- public override void OnData(Slice slice)
- {
- // Trade only base on government contract data
- foreach (var kvp in slice.Get<QuiverGovernmentContract>())
- {
- // Buy if over 50000 government contract amount, suggesting a large income
- if (kvp.Value.Any(x => (int) (x as QuiverGovernmentContract).Amount > 50000m))
- {
- SetHoldings(_symbol, 1);
- }
- // Sell if below 10000 government contract amount, suggesting a smaller than usual income
- else if (kvp.Value.Any(x => (int) (x as QuiverGovernmentContract).Amount < 10000m))
- {
- SetHoldings(_symbol, -1);
- }
- }
- }
-}
- - The following example algorithm creates a dynamic universe of US Equities that have just received a government contract worth at least $5K. Each day, it then forms an equal-weighted dollar-neutral portfolio with the 10 companies that received the largest contracts and the 10 companies that received the smallest contracts. -
-from AlgorithmImports import *
-
-
-class QuiverGovernmentContractDataAlgorithm(QCAlgorithm):
-
- def initialize(self) -> None:
- self.set_start_date(2024, 9, 1)
- self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- # Seed the price of each asset with its last known price to avoid trading errors.
- self.settings.seed_initial_prices = True
- # Filter universe using government contract data
- self.add_universe(QuiverGovernmentContractUniverse, self.universe_selection)
-
- # Custom alpha model that emit insights based on updated government contract data
- self.add_alpha(QuiverGovernmentContractAlphaModel())
-
- # Invest equally to evenly dissipate the capital concentration risk
- self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
-
- self.set_execution(ImmediateExecutionModel())
-
- def universe_selection(self, data: List[QuiverGovernmentContractUniverse]) -> List[Symbol]:
- gov_contract_data_by_symbol = {}
-
- for datum in data:
- symbol = datum.symbol
-
- if symbol not in gov_contract_data_by_symbol:
- gov_contract_data_by_symbol[symbol] = []
- gov_contract_data_by_symbol[symbol].append(datum)
-
- # Only select the stocks with over 5000 government contracts, which is considered material information
- return [symbol for symbol, d in gov_contract_data_by_symbol.items()
- if sum([x.amount for x in d]) > 5000]
-
-class QuiverGovernmentContractAlphaModel(AlphaModel):
-
- def __init__(self) -> None:
- # A variable to control the rebalancing time
- self.last_time = datetime.min
- # To hold the government contract dataset symbol for managing subscription
- self.dataset_symbol_by_symbol = {}
-
- def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- if self.last_time > algorithm.time: return []
-
- # Trade signal only based on government contract data
- data_points = slice.Get(QuiverGovernmentContract)
-
- if not data_points: return []
-
- gov_contracts = {}
- # To aggregate all data per symbol for analysis
- for data_point in data_points:
- if not algorithm.securities[data_point.key.underlying].price:
- continue
- if data_point.Key not in gov_contracts:
- gov_contracts[data_point.Key] = 0
-
- for gov_contract in data_point.Value:
- gov_contracts[data_point.Key] += gov_contract.amount
-
- # Long the top 10 highest government contract amount, predicting a higher expected income and return
- # Short the lowest 10 government contract amount, predicting a lower expected income and return
- sorted_by_gov_contracts = sorted(gov_contracts.items(), key=lambda x: x[1])
- long_symbols = [x[0].underlying for x in sorted_by_gov_contracts[-10:]]
- short_symbols = [x[0].underlying for x in sorted_by_gov_contracts[:10]]
-
- insights = []
- for symbol in long_symbols:
- insights.append(Insight.price(symbol, Expiry.END_OF_DAY, InsightDirection.UP))
- for symbol in short_symbols:
- insights.append(Insight.price(symbol, Expiry.END_OF_DAY, InsightDirection.DOWN))
-
- self.last_time = Expiry.END_OF_DAY(algorithm.Time)
-
- return insights
-
- def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for security in changes.added_securities:
- # Requesting government contract data for trade signal generation
- symbol = security.symbol
- dataset_symbol = algorithm.add_data(QuiverGovernmentContract, symbol).symbol
- self.dataset_symbol_by_symbol[symbol] = dataset_symbol
- # Historical Data
- history = algorithm.history(dataset_symbol, 10, Resolution.DAILY)
-
- for security in changes.removed_securities:
- dataset_symbol = self.dataset_symbol_by_symbol.pop(security.symbol, None)
- if dataset_symbol:
- # Remove government contract data subscription to release computation resources
- algorithm.remove_security(dataset_symbol)
- public class QuiverGovernmentContractFrameworkAlgorithm : QCAlgorithm
-{
- public override void Initialize()
- {
- SetStartDate(2024, 9, 1);
- SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Seed the price of each asset with its last known price to avoid trading errors.
- Settings.SeedInitialPrices = true;
- // Filter universe using government contract data
- AddUniverse<QuiverGovernmentContractUniverse>(data =>
- {
- var govContractDataBySymbol = new Dictionary<Symbol, List<QuiverGovernmentContractUniverse>>();
-
- foreach (var datum in data.OfType<QuiverGovernmentContractUniverse>())
- {
- var symbol = datum.Symbol;
-
- if (!govContractDataBySymbol.ContainsKey(symbol))
- {
- govContractDataBySymbol.Add(symbol, new List<QuiverGovernmentContractUniverse>());
- }
- govContractDataBySymbol[symbol].Add(datum);
- }
-
- // Only select the stocks with over 5000 government contracts, which is considered material information
- return from kvp in govContractDataBySymbol
- where kvp.Value.Sum(x => x.Amount) > 5000m
- select kvp.Key;
- });
-
- // Custom alpha model that emit insights based on updated government contract data
- AddAlpha(new QuiverGovernmentContractAlphaModel());
-
- // Invest equally to evenly dissipate the capital concentration risk
- SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
-
- SetExecution(new ImmediateExecutionModel());
- }
-}
-
-public class QuiverGovernmentContractAlphaModel: AlphaModel
-{
- // A variable to control the rebalancing time
- private DateTime _time;
- // To hold the government contract dataset symbol for managing subscription
- private Dictionary<Symbol, Symbol> _datasetSymbolBySymbol = new();
-
- public QuiverGovernmentContractAlphaModel()
- {
- _time = DateTime.MinValue;
- }
-
- public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
- {
- if (_time > algorithm.Time) return new List<Insight>();
-
- // Trade signal only based on government contract data
- var dataPoints = slice.Get<QuiverGovernmentContract>();
-
- if (dataPoints.IsNullOrEmpty()) return new List<Insight>();
-
- // To aggregate all data per symbol for analysis
- var govContracts = dataPoints
- .Where(kvp => algorithm.Securities[kvp.Key.Underlying].Price != 0)
- .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Sum(x => ((QuiverGovernmentContract)x).Amount));
-
- // Long the top 10 highest government contract amount, predicting a higher expected income and return
- // Short the lowest 10 government contract amount, predicting a lower expected income and return
- var sortedByGovContract = from kvp in govContracts
- orderby kvp.Value descending
- select kvp.Key.Underlying;
- var longSymbols = sortedByGovContract.Take(10).ToList();
- var shortSymbols = sortedByGovContract.TakeLast(10).ToList();
-
- var insights = new List<Insight>();
- insights.AddRange(longSymbols.Select(symbol =>
- new Insight(symbol, Expiry.EndOfDay, InsightType.Price, InsightDirection.Up)));
- insights.AddRange(shortSymbols.Select(symbol =>
- new Insight(symbol, Expiry.EndOfDay, InsightType.Price, InsightDirection.Down)));
-
- _time = Expiry.EndOfDay(algorithm.Time);
-
- return insights;
- }
-
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
- {
- foreach (var security in changes.AddedSecurities)
- {
- // Requesting government contract data for trade signal generation
- var symbol = security.Symbol;
- var datasetSymbol = algorithm.AddData<QuiverGovernmentContract>(symbol).Symbol;
- _datasetSymbolBySymbol.Add(symbol, datasetSymbol);
- // History request
- var history = algorithm.History<QuiverGovernmentContract>(datasetSymbol, 10, Resolution.Daily);
- }
-
- foreach (var security in changes.RemovedSecurities)
- {
- var symbol = security.Symbol;
- if (_datasetSymbolBySymbol.ContainsKey(symbol))
- {
- // Remove government contract data subscription to release computation resources
- _datasetSymbolBySymbol.Remove(symbol, out var datasetSymbol);
- algorithm.RemoveSecurity(datasetSymbol);
- }
- }
- }
-}
- - The following example lists all US Equities with Government contracts in the past year. -
-#r "../QuantConnect.DataSource.QuiverGovernmentContracts.dll"
-using QuantConnect.DataSource;
-
-// Requesting data
-var aapl = qb.AddEquity("AAPL", Resolution.Daily).Symbol;
-var symbol = qb.AddData<QuiverGovernmentContract>(aapl).Symbol;
-
-// Historical data
-var history = qb.History<QuiverGovernmentContract>(symbol, 360, Resolution.Daily);
-foreach (var contracts in history)
-{
- foreach (QuiverGovernmentContract contract in contracts)
- {
- Console.WriteLine($"{contract.Symbol} amount at {contract.EndTime}: {contract.Amount}");
- }
-}
-
-// Add Universe Selection
-IEnumerable<Symbol> UniverseSelection(IEnumerable<BaseData> altCoarse)
-{
- return from d in altCoarse.OfType<QuiverGovernmentContractUniverse>()
- select d.Symbol;
-}
-var universe = qb.AddUniverse<QuiverGovernmentContractUniverse<(UniverseSelection);
-
-// Historical Universe data
-var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-360), qb.Time);
-foreach (var contracts in universeHistory)
-{
- foreach (QuiverGovernmentContractUniverse contract in contracts)
- {
- Console.WriteLine($"{contract.Symbol} amount at {contract.EndTime}: {contract.Amount}");
- }
-}
- qb = QuantBook()
-
-# Requesting Data
-aapl = qb.add_equity("AAPL", Resolution.DAILY).symbol
-symbol = qb.add_data(QuiverGovernmentContract, aapl).symbol
-
-# Historical data
-history = qb.history(QuiverGovernmentContract, symbol, 360, Resolution.DAILY)
-for (symbol, time), contracts in history.items():
- for contract in contracts:
- print(f"{contract.symbol} amount at {contract.end_time}: {contract.amount}")
-
-# Add Universe Selection
-def universe_selection(alt_coarse: List[QuiverGovernmentContractUniverse]) -> List[Symbol]:
- return [d.symbol for d in alt_coarse]
-
-universe = qb.add_universe(QuiverGovernmentContractUniverse, universe_selection)
-
-# Historical Universe data
-universe_history = qb.universe_history(universe, qb.time-timedelta(360), qb.time)
-for (_, time), contracts in universe_history.items():
- for contract in contracts:
- print(f"{contract.symbol} amount at {contract.end_time}: {contract.amount}")
-
- The US Government Contracts dataset provides
-
- QuiverGovernmentContract
-
- and
-
- QuiverGovernmentContractUniverse
-
- objects.
-
-
- QuiverGovernmentContract
-
- objects have the following attributes:
-
-
- QuiverGovernmentContractUniverse
-
- objects have the following attributes:
-
- -
- The WallStreetBets dataset by Quiver Quantitative tracks daily mentions of different equities on Reddit’s popular WallStreetBets forum. The data covers 6,000 Equities, starts in August 2018, and is delivered on a daily frequency. The dataset is created by scraping the daily discussion threads on r/WallStreetBets and parsing the comments for ticker mentions. -
-- This dataset depends on the - - US Equity Security Master - - dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes. -
-- For more information about the WallStreetBets dataset, including CLI commands and pricing, see the - - dataset listing - - . -
--
- - - -- - Quiver Quantitative - - was founded by two college students in February 2020 with the goal of bridging the information gap between Wall Street and non-professional investors. Quiver allows retail investors to tap into the power of big data and have access to actionable, easy to interpret data that hasn’t already been dissected by Wall Street. -
- - - -- The following snippet demonstrates how to request data from the WallStreetBets dataset: -
-self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
-self.dataset_symbol = self.add_data(QuiverWallStreetBets, self.aapl).symbol
-
-self._universe = self.add_universe(QuiverWallStreetBetsUniverse, self.universe_selection)
- _symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
-_datasetSymbol = AddData<QuiverWallStreetBets>(_symbol).Symbol;
-
-_universe = AddUniverse<QuiverWallStreetBetsUniverse>(UniverseSelection);
- - The following table describes the dataset properties: -
-| - Property - | -- Value - | -
|---|---|
| - Start Date - | -- August 2018 - | -
| - Asset Coverage - | -- 6,000 US Equities - | -
| - Data Density - | -- Sparse - | -
| - Resolution - | -- Daily - | -
| - Timezone - | -- UTC - | -
- To add WallStreetBets data to your algorithm, call the
-
- AddData
-
-
- add_data
-
- method. Save a reference to the dataset
-
- Symbol
-
- so you can access the data later in your algorithm.
-
class QuiverWallStreetBetsDataAlgorithm(QCAlgorithm):
- def initialize(self) -> None:
- self.set_start_date(2019, 1, 1)
- self.set_end_date(2020, 6, 1)
- self.set_cash(100000)
-
- self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
- self.dataset_symbol = self.add_data(QuiverWallStreetBets, self.aapl).symbol
- public class QuiverWallStreetBetsDataAlgorithm : QCAlgorithm
-{
- private Symbol _symbol, _datasetSymbol;
-
- public override void Initialize()
- {
- SetStartDate(2019, 1, 1);
- SetEndDate(2020, 6, 1);
- SetCash(100000);
- _symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
- _datasetSymbol = AddData<QuiverWallStreetBets>(_symbol).Symbol;
- }
-}
-
- To get the current WallStreetBets data, index the current
-
-
- Slice
-
-
- with the dataset
-
- Symbol
-
- . Slice objects deliver unique events to your algorithm as they happen, but the
-
- Slice
-
- may not contain data for your dataset at every time step. To avoid issues, check if the
-
- Slice
-
- contains the data you want before you index it.
-
def on_data(self, slice: Slice) -> None:
- if slice.contains_key(self.dataset_symbol):
- data_points = slice[self.dataset_symbol]
- for data_point in data_points:
- self.log(f"{self.dataset_symbol} mentions at {slice.time}: {data_point.mentions}")
- public override void OnData(Slice slice)
-{
- if (slice.ContainsKey(_datasetSymbol))
- {
- var dataPoints = slice[_datasetSymbol];
- foreach (var dataPoint in dataPoints)
- {
- Log($"{_datasetSymbol} mentions at {slice.Time}: {dataPoint.Mentions}");
- }
- }
-}
-
- To iterate through all of the dataset objects in the current
-
- Slice
-
- , call the
-
- Get
-
-
- get
-
- method.
-
def on_data(self, slice: Slice) -> None:
- for dataset_symbol, data_points in slice.get(QuiverWallStreetBets).items():
- for data_point in data_points:
- self.log(f"{dataset_symbol} mentions at {slice.time}: {data_point.mentions}")
- public override void OnData(Slice slice)
-{
- foreach (var kvp in slice.Get<QuiverWallStreetBets>())
- {
- var datasetSymbol = kvp.Key;
- var dataPoints = kvp.Value;
- foreach (var dataPoint in dataPoints)
- {
- Log($"{datasetSymbol} mentions at {slice.Time}: {dataPoint.Mentions}");
- }
- }
-}
-
- To get historical WallStreetBets data, call the
-
- History
-
-
- history
-
- method with the dataset
-
- Symbol
-
- . If there is no data in the period you request, the history result is empty.
-
# DataFrame -history_df = self.history(self.dataset_symbol, 100, Resolution.DAILY) - -# Dataset objects -history_bars = self.history[QuiverWallStreetBets](self.dataset_symbol, 100, Resolution.DAILY)-
var history = History<QuiverWallStreetBets>(_datasetSymbol, 100, Resolution.Daily);-
- For more information about historical data, see - - History Requests - - . -
- - - -
- To select a dynamic universe of US Equities based on WallStreetBets data, call the
-
- AddUniverse
-
-
- add_universe
-
- method with the
-
- QuiverWallStreetBetsUniverse
-
- class and a selection function.
-
def initialize(self) -> None: - self.universe = self.add_universe(QuiverWallStreetBetsUniverse, self.universe_selection) - -def universe_selection(self, alt_coarse: List[QuiverWallStreetBetsUniverse]) -> List[Symbol]: - return [d.symbol for d in alt_coarse if d.mentions > 100 and d.rank < 100]-
private Universe _universe;
-public override void Initialize()
-{
- _universe = AddUniverse<QuiverWallStreetBetsUniverse>(altCoarse =>
- {
- return from d in altCoarse.OfType<QuiverWallStreetBetsUniverse>()
- where d.Mentions > 10 && d.Rank > 10 select d.Symbol;
- });
-}
- - For more information about dynamic universes, see - - Universes - - . -
- - - -- You can get historical universe data in an algorithm and in the Research Environment. -
-
- To get historical universe data in an algorithm, call the
-
- History
-
-
- history
-
- method with the
-
- Universe
-
- object and the lookback period. If there is no data in the period you request, the history result is empty.
-
var universeHistory = History(_universe, 30, Resolution.Daily);
-foreach (var bets in universeHistory)
-{
- foreach (QuiverWallStreetBetsUniverse bet in bets)
- {
- Log($"{bet.Symbol} mentions at {bet.EndTime}: {bet.Mentions}");
- }
-}
- # DataFrame example where the columns are the QuiverWallStreetBetsUniverse attributes:
-history_df = self.history(self._universe, 30, Resolution.DAILY, flatten=True)
-
-# Series example where the values are lists of QuiverWallStreetBetsUniverse objects:
-universe_history = self.history(self._universe, 30, Resolution.DAILY)
-for (univere_symbol, time), bets in universe_history.items():
- for bet in bets:
- self.log(f"{bet.symbol} mentions at {bet.end_time}: {bet.mentions}")
-
- To get historical universe data in research, call the
-
- UniverseHistory
-
-
- universe_history
-
- method with the
-
- Universe
-
- object, a start date, and an end date. This method returns the filtered universe. If there is no data in the period you request, the history result is empty.
-
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);
-{
- foreach (QuiverWallStreetBetsUniverse bet in bets)
- {
- Log($"{bet.Symbol} rank at {bet.EndTime}: {bet.Rank}");
- }
-}
- # DataFrame example where the columns are the QuiverWallStreetBetsUniverse attributes:
-history_df = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)
-
-# Series example where the values are lists of QuiverWallStreetBetsUniverse objects:
-universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
-for (univere_symbol, time), bets in universe_history.items():
- for bet in bets:
- print(f"{bet.symbol} rank at {bet.end_time}: {bet.rank}")
-
- You can call the
-
- History
-
-
- history
-
- method in Research.
-
- To remove a subscription, call the
-
- RemoveSecurity
-
-
- remove_security
-
- method.
-
self.remove_security(self.dataset_symbol)-
RemoveSecurity(_datasetSymbol);-
- If you subscribe to WallStreetBets data for assets in a dynamic universe, remove the dataset subscription when the asset leaves your universe. To view a common design pattern, see + If you subscribe to US Government Contracts data for assets in a dynamic universe, remove the dataset subscription when the asset leaves your universe. To view a common design pattern, see Track Security Changes @@ -268488,393 +269900,359 @@
- The WallStreetBets dataset enables you to create strategies using the latest activity on the WallStreetBets daily discussion thread. Examples include the following strategies: + The Quiver Quantitative US Government Contracts dataset enables you to create strategies using the latest information on government contracts activity. Examples include the following strategies:
- The following example algorithm creates a dynamic universe of US Equities based on daily WallStreetBets data. When a security is mentioned on r/WallStreetBets more than five times in a day, the algorithm buys the security. When a security is mentioned five time in a day or less, the algorithm short sells the security. + The following example algorithm buys Apple stock when they receive a new government contract worth over $50K. If they receive a new contract worth under $10K, the algorithm short sells Apple.
from AlgorithmImports import *
-class QuiverWallStreetBetsDataAlgorithm(QCAlgorithm):
+class QuiverGovernmentContractAlgorithm(QCAlgorithm):
+
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
- self.set_cash(100000)
- # Seed the price of each asset with its last known price to avoid trading errors.
- self.settings.seed_initial_prices = True
- self.universe_settings.resolution = Resolution.DAILY
- # Filter using wall street bet insights
- self._universe = self.add_universe(QuiverWallStreetBetsUniverse, self.universe_selection)
-
- def on_data(self, slice: Slice) -> None:
- points = slice.Get(QuiverWallStreetBets)
- for point in points.Values:
- symbol = point.symbol.underlying
- security = self.securities[symbol]
- if not security.is_tradable:
- continue
-
- # Buy if the stock was mentioned more than 5 times in the WallStreetBets daily discussion, which translate into high popularity of rise
- if point.mentions > 5 and not security.holdings.is_long:
- self.market_order(symbol, 1)
-
- # Otherwise, short sell
- elif point.mentions <= 5 and not security.holdings.is_short:
- self.market_order(symbol, -1)
-
- def on_securities_changed(self, changes: SecurityChanges) -> None:
- for added in changes.added_securities:
- # Requesting wall street bet data to obtain the trader's insights
- quiver_wsb_symbol = self.add_data(QuiverWallStreetBets, added.symbol).symbol
+ self.aapl = self.add_equity("AAPL", Resolution.DAILY).symbol
+ # Subscribe to government contract data for AAPL to generate trade signal
+ self.dataset_symbol = self.add_data(QuiverGovernmentContract, self.aapl).symbol
- # Historical data
- history = self.history(QuiverWallStreetBets, quiver_wsb_symbol, 60, Resolution.DAILY)
+ # history request
+ history = self.history(self.dataset_symbol, 10, Resolution.DAILY)
+ self.debug(f"We got {len(history)} items from historical data request of {self.dataset_symbol}.")
- def universe_selection(self, alt_coarse: List[QuiverWallStreetBetsUniverse]) -> List[Symbol]:
- # Select the ones with popularity (mentions) of better-than-others performance (rank)
- return [d.symbol for d in alt_coarse \
- if d.mentions > 10 \
- and d.rank < 100]
- public class QuiverWallStreetBetsDataAlgorithm : QCAlgorithm + def on_data(self, slice: Slice) -> None: + # Trade only base on government contract data + for gov_contracts in slice.Get(QuiverGovernmentContract).values(): + # Buy if over 50000 government contract amount, suggesting a large income + if any([gov_contract.amount > 50000 for gov_contract in gov_contracts]): + self.set_holdings(self.aapl, 1) + # Sell if below 10000 government contract amount, suggesting a smaller than usual income + elif any([gov_contract.amount < 10000 for gov_contract in gov_contracts]): + self.set_holdings(self.aapl, -1)+
public class QuiverGovernmentContractAlgorithm : QCAlgorithm
{
- private Universe _universe;
+ private Symbol _symbol, _datasetSymbol;
+
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
- SetCash(100000);
- // Seed the price of each asset with its last known price to avoid trading errors.
- Settings.SeedInitialPrices = true;
- UniverseSettings.Resolution = Resolution.Daily;
- // Filter using wall street bet insights
- _universe = AddUniverse<QuiverWallStreetBetsUniverse>(altCoarse =>
- {
- // Select the ones with popularity (mentions) of better-than-others performance (rank)
- return from d in altCoarse.OfType<QuiverWallStreetBetsUniverse>()
- where d.Mentions > 10 && d.Rank < 100
- select d.Symbol;
- });
+ _symbol = AddEquity("AAPL").Symbol;
+ // Subscribe to government contract data for AAPL to generate trade signal
+ _datasetSymbol = AddData<QuiverGovernmentContract>(_symbol).Symbol;
+
+ // history request
+ var history = History<QuiverGovernmentContract>(new[] {_datasetSymbol}, 10, Resolution.Daily);
+ Debug($"We got {history.Count()} items from historical data request of {_datasetSymbol}.");
}
public override void OnData(Slice slice)
{
- var points = slice.Get<QuiverWallStreetBets>();
- foreach (var point in points.Values)
+ // Trade only base on government contract data
+ foreach (var kvp in slice.Get<QuiverGovernmentContract>())
{
- var symbol = point.Symbol.Underlying;
- var security = Securities[symbol];
- if (!security.IsTradable)
- {
- continue;
- }
-
- // Buy if the stock was mentioned more than 5 times in the WallStreetBets daily discussion, which translate into high popularity of rise
- if (point.Mentions > 5 && !security.Holdings.IsLong)
+ // Buy if over 50000 government contract amount, suggesting a large income
+ if (kvp.Value.Any(x => (int) (x as QuiverGovernmentContract).Amount > 50000m))
{
- MarketOrder(symbol, 1);
+ SetHoldings(_symbol, 1);
}
- // Otherwise, short sell
- else if (point.Mentions <= 5 && !security.Holdings.IsShort)
+ // Sell if below 10000 government contract amount, suggesting a smaller than usual income
+ else if (kvp.Value.Any(x => (int) (x as QuiverGovernmentContract).Amount < 10000m))
{
- MarketOrder(symbol, -1);
+ SetHoldings(_symbol, -1);
}
}
}
-
- public override void OnSecuritiesChanged(SecurityChanges changes)
- {
- foreach(var added in changes.AddedSecurities)
- {
- // Requesting wall street bet data to obtain the trader's insights
- var quiverWSBSymbol = AddData<QuiverWallStreetBets>(added.Symbol).Symbol;
- // Historical data
- var history = History<QuiverWallStreetBets>(quiverWSBSymbol, 60, Resolution.Daily);
- }
- }
}
- The following example algorithm creates a dynamic universe of US Equities based on daily WallStreetBets data. When a security is mentioned on r/WallStreetBets more than five times in a day, the algorithm buys the security. When a security is mentioned five time in a day or less, the algorithm short sells the security. + The following example algorithm creates a dynamic universe of US Equities that have just received a government contract worth at least $5K. Each day, it then forms an equal-weighted dollar-neutral portfolio with the 10 companies that received the largest contracts and the 10 companies that received the smallest contracts.
from AlgorithmImports import *
-class QuiverWallStreetBetsDataAlgorithm(QCAlgorithm):
+class QuiverGovernmentContractDataAlgorithm(QCAlgorithm):
+
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
+ # Seed the price of each asset with its last known price to avoid trading errors.
+ self.settings.seed_initial_prices = True
+ # Filter universe using government contract data
+ self.add_universe(QuiverGovernmentContractUniverse, self.universe_selection)
- self.universe_settings.resolution = Resolution.DAILY
- # Filter using wall street bet insights
- self._universe = self.add_universe(QuiverWallStreetBetsUniverse, self.universe_selection)
-
- self.add_alpha(WallStreamBetsAlphaModel())
+ # Custom alpha model that emit insights based on updated government contract data
+ self.add_alpha(QuiverGovernmentContractAlphaModel())
+ # Invest equally to evenly dissipate the capital concentration risk
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
- self.add_risk_management(NullRiskManagementModel())
-
self.set_execution(ImmediateExecutionModel())
+
+ def universe_selection(self, data: List[QuiverGovernmentContractUniverse]) -> List[Symbol]:
+ gov_contract_data_by_symbol = {}
- def universe_selection(self, alt_coarse: List[QuiverWallStreetBetsUniverse]) -> List[Symbol]:
- # Select the ones with popularity (mentions) of better-than-others performance (rank)
- return [d.symbol for d in alt_coarse
- if d.mentions > 10 and d.rank < 100]
-
-class WallStreamBetsAlphaModel(AlphaModel):
-
- symbol_data_by_symbol = {}
-
- def __init__(self, mentions_threshold: int = 5) -> None:
- self.mentions_threshold = mentions_threshold
+ for datum in data:
+ symbol = datum.symbol
+
+ if symbol not in gov_contract_data_by_symbol:
+ gov_contract_data_by_symbol[symbol] = []
+ gov_contract_data_by_symbol[symbol].append(datum)
+
+ # Only select the stocks with over 5000 government contracts, which is considered material information
+ return [symbol for symbol, d in gov_contract_data_by_symbol.items()
+ if sum([x.amount for x in d]) > 5000]
+
+class QuiverGovernmentContractAlphaModel(AlphaModel):
+ def __init__(self) -> None:
+ # A variable to control the rebalancing time
+ self.last_time = datetime.min
+ # To hold the government contract dataset symbol for managing subscription
+ self.dataset_symbol_by_symbol = {}
+
def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
- insights = []
+ if self.last_time > algorithm.time: return []
- points = slice.Get(QuiverWallStreetBets)
- for point in points.Values:
- # Buy if the stock was mentioned more than 5 times in the WallStreetBets daily discussion, which translate into high popularity of rise
- # Otherwise short sell
- target_direction = InsightDirection.UP if point.mentions > self.mentions_threshold else InsightDirection.DOWN
- self.symbol_data_by_symbol[point.symbol.underlying].target_direction = target_direction
-
- for symbol, symbol_data in self.symbol_data_by_symbol.items():
- # Ensure we have security data for the current Slice to avoid stale fill
- if not (slice.contains_key(symbol) and slice[symbol] is not None):
+ # Trade signal only based on government contract data
+ data_points = slice.Get(QuiverGovernmentContract)
+
+ if not data_points: return []
+
+ gov_contracts = {}
+ # To aggregate all data per symbol for analysis
+ for data_point in data_points:
+ if not algorithm.securities[data_point.key.underlying].price:
continue
-
- if symbol_data.target_direction is not None:
- insights += [Insight.price(symbol, timedelta(1), symbol_data.target_direction)]
- symbol_data.target_direction = None
+ if data_point.Key not in gov_contracts:
+ gov_contracts[data_point.Key] = 0
- return insights
+ for gov_contract in data_point.Value:
+ gov_contracts[data_point.Key] += gov_contract.amount
+
+ # Long the top 10 highest government contract amount, predicting a higher expected income and return
+ # Short the lowest 10 government contract amount, predicting a lower expected income and return
+ sorted_by_gov_contracts = sorted(gov_contracts.items(), key=lambda x: x[1])
+ long_symbols = [x[0].underlying for x in sorted_by_gov_contracts[-10:]]
+ short_symbols = [x[0].underlying for x in sorted_by_gov_contracts[:10]]
+ insights = []
+ for symbol in long_symbols:
+ insights.append(Insight.price(symbol, Expiry.END_OF_DAY, InsightDirection.UP))
+ for symbol in short_symbols:
+ insights.append(Insight.price(symbol, Expiry.END_OF_DAY, InsightDirection.DOWN))
+
+ self.last_time = Expiry.END_OF_DAY(algorithm.Time)
+
+ return insights
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for security in changes.added_securities:
+ # Requesting government contract data for trade signal generation
symbol = security.symbol
- self.symbol_data_by_symbol[symbol] = SymbolData(algorithm, symbol)
-
+ dataset_symbol = algorithm.add_data(QuiverGovernmentContract, symbol).symbol
+ self.dataset_symbol_by_symbol[symbol] = dataset_symbol
+ # Historical Data
+ history = algorithm.history(dataset_symbol, 10, Resolution.DAILY)
+
for security in changes.removed_securities:
- symbol_data = self.symbol_data_by_symbol.pop(security.symbol, None)
- if symbol_data:
- symbol_data.dispose()
-
-
-class SymbolData:
- target_direction = None
-
- def __init__(self, algorithm: QCAlgorithm, symbol: Symbol) -> None:
- self.algorithm = algorithm
-
- # Requesting wall street bet data to obtain the trader's insights
- self.quiver_wsb_symbol = algorithm.add_data(QuiverWallStreetBets, symbol).symbol
-
- # Historical data
- history = algorithm.history(self.quiver_wsb_symbol, 60, Resolution.DAILY)
-
- def dispose(self) -> None:
- # Unsubscribe from the Quiver WallStreetBets feed for this security to release computationa resources
- self.algorithm.remove_security(self.quiver_wsb_symbol)
- public class QuiverWallStreetBetsDataAlgorithm : QCAlgorithm + dataset_symbol = self.dataset_symbol_by_symbol.pop(security.symbol, None) + if dataset_symbol: + # Remove government contract data subscription to release computation resources + algorithm.remove_security(dataset_symbol)+
public class QuiverGovernmentContractFrameworkAlgorithm : QCAlgorithm
{
- private Universe _universe;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
-
- UniverseSettings.Resolution = Resolution.Daily;
- // Filter using wall street bet insights
- _universe = AddUniverse<QuiverWallStreetBetsUniverse>(altCoarse =>
+ // Seed the price of each asset with its last known price to avoid trading errors.
+ Settings.SeedInitialPrices = true;
+ // Filter universe using government contract data
+ AddUniverse<QuiverGovernmentContractUniverse>(data =>
{
- // Select the ones with popularity (mentions) of better-than-others performance (rank)
- return from d in altCoarse.OfType<QuiverWallStreetBetsUniverse>()
- where d.Mentions > 10 && d.Rank < 100
- select d.Symbol;
+ var govContractDataBySymbol = new Dictionary<Symbol, List<QuiverGovernmentContractUniverse>>();
+
+ foreach (var datum in data.OfType<QuiverGovernmentContractUniverse>())
+ {
+ var symbol = datum.Symbol;
+
+ if (!govContractDataBySymbol.ContainsKey(symbol))
+ {
+ govContractDataBySymbol.Add(symbol, new List<QuiverGovernmentContractUniverse>());
+ }
+ govContractDataBySymbol[symbol].Add(datum);
+ }
+
+ // Only select the stocks with over 5000 government contracts, which is considered material information
+ return from kvp in govContractDataBySymbol
+ where kvp.Value.Sum(x => x.Amount) > 5000m
+ select kvp.Key;
});
- AddAlpha(new WallStreamBetsAlphaModel());
-
+ // Custom alpha model that emit insights based on updated government contract data
+ AddAlpha(new QuiverGovernmentContractAlphaModel());
+
+ // Invest equally to evenly dissipate the capital concentration risk
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
- AddRiskManagement(new NullRiskManagementModel());
-
SetExecution(new ImmediateExecutionModel());
}
}
-public class WallStreamBetsAlphaModel : AlphaModel
+public class QuiverGovernmentContractAlphaModel: AlphaModel
{
- private Dictionary<Symbol, SymbolData> _symbolDataBySymbol = new Dictionary<Symbol, SymbolData>();
- private int _mentionsThreshold;
+ // A variable to control the rebalancing time
+ private DateTime _time;
+ // To hold the government contract dataset symbol for managing subscription
+ private Dictionary<Symbol, Symbol> _datasetSymbolBySymbol = new();
- public WallStreamBetsAlphaModel(int mentionsThreshold=5)
+ public QuiverGovernmentContractAlphaModel()
{
- _mentionsThreshold = mentionsThreshold;
+ _time = DateTime.MinValue;
}
-
+
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
{
+ if (_time > algorithm.Time) return new List<Insight>();
+
+ // Trade signal only based on government contract data
+ var dataPoints = slice.Get<QuiverGovernmentContract>();
+
+ if (dataPoints.IsNullOrEmpty()) return new List<Insight>();
+
+ // To aggregate all data per symbol for analysis
+ var govContracts = dataPoints
+ .Where(kvp => algorithm.Securities[kvp.Key.Underlying].Price != 0)
+ .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Sum(x => ((QuiverGovernmentContract)x).Amount));
+
+ // Long the top 10 highest government contract amount, predicting a higher expected income and return
+ // Short the lowest 10 government contract amount, predicting a lower expected income and return
+ var sortedByGovContract = from kvp in govContracts
+ orderby kvp.Value descending
+ select kvp.Key.Underlying;
+ var longSymbols = sortedByGovContract.Take(10).ToList();
+ var shortSymbols = sortedByGovContract.TakeLast(10).ToList();
+
var insights = new List<Insight>();
+ insights.AddRange(longSymbols.Select(symbol =>
+ new Insight(symbol, Expiry.EndOfDay, InsightType.Price, InsightDirection.Up)));
+ insights.AddRange(shortSymbols.Select(symbol =>
+ new Insight(symbol, Expiry.EndOfDay, InsightType.Price, InsightDirection.Down)));
- var points = slice.Get<QuiverWallStreetBets>();
- foreach (var point in points.Values)
- {
- // Buy if the stock was mentioned more than 5 times in the WallStreetBets daily discussion, which translate into high popularity of rise
- // Otherwise short sell
- var targetDirection = point.Mentions > _mentionsThreshold ? InsightDirection.Up : InsightDirection.Down;
- _symbolDataBySymbol[point.Symbol.Underlying].targetDirection = targetDirection;
- }
+ _time = Expiry.EndOfDay(algorithm.Time);
- foreach (var kvp in _symbolDataBySymbol)
- {
- var symbol = kvp.Key;
- var symbolData = kvp.Value;
-
- // Ensure we have security data for the current Slice to avoid stale fill
- if (!(slice.ContainsKey(symbol) && slice[symbol] != null))
- {
- continue;
- }
-
- if (symbolData.targetDirection != null)
- {
- insights.Add(Insight.Price(symbol, TimeSpan.FromDays(1), (InsightDirection)symbolData.targetDirection));
- symbolData.targetDirection = null;
- }
- }
return insights;
}
-
+
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
foreach (var security in changes.AddedSecurities)
{
+ // Requesting government contract data for trade signal generation
var symbol = security.Symbol;
- _symbolDataBySymbol.Add(symbol, new SymbolData(algorithm, symbol));
+ var datasetSymbol = algorithm.AddData<QuiverGovernmentContract>(symbol).Symbol;
+ _datasetSymbolBySymbol.Add(symbol, datasetSymbol);
+ // History request
+ var history = algorithm.History<QuiverGovernmentContract>(datasetSymbol, 10, Resolution.Daily);
}
-
+
foreach (var security in changes.RemovedSecurities)
{
var symbol = security.Symbol;
- if (_symbolDataBySymbol.ContainsKey(symbol))
+ if (_datasetSymbolBySymbol.ContainsKey(symbol))
{
- _symbolDataBySymbol[symbol].dispose();
- _symbolDataBySymbol.Remove(symbol);
+ // Remove government contract data subscription to release computation resources
+ _datasetSymbolBySymbol.Remove(symbol, out var datasetSymbol);
+ algorithm.RemoveSecurity(datasetSymbol);
}
}
}
-}
-
-public class SymbolData
-{
- private Symbol _quiverWSBSymbol;
- private QCAlgorithm _algorithm;
- public InsightDirection? targetDirection = null;
-
- public SymbolData(QCAlgorithm algorithm, Symbol symbol)
- {
- _algorithm = algorithm;
-
- // Requesting wall street bet data to obtain the trader's insights
- _quiverWSBSymbol = algorithm.AddData<QuiverWallStreetBets>(symbol).Symbol;
-
- // Historical data
- var history = algorithm.History<QuiverWallStreetBets>(_quiverWSBSymbol, 60, Resolution.Daily);
- }
-
- public void dispose()
- {
- // Unsubscribe from the Quiver WallStreetBets feed for this security to release computationa resources
- _algorithm.RemoveSecurity(_quiverWSBSymbol);
- }
}
- The following example lists low-ranking US Equities that are mentioned more than ten times on r/WallStreetBets. + The following example lists all US Equities with Government contracts in the past year.
#r "../QuantConnect.DataSource.QuiverWallStreetBets.dll" +#r "../QuantConnect.DataSource.QuiverGovernmentContracts.dll" using QuantConnect.DataSource; -var qb = new QuantBook(); - // Requesting data var aapl = qb.AddEquity("AAPL", Resolution.Daily).Symbol; -var symbol = qb.AddData<QuiverWallStreetBets>(aapl).Symbol; +var symbol = qb.AddData<QuiverGovernmentContract>(aapl).Symbol; // Historical data -var history = qb.History<QuiverWallStreetBets>(symbol, 60, Resolution.Daily); -foreach (var bet in history.OfType<QuiverWallStreetBets>()) +var history = qb.History<QuiverGovernmentContract>(symbol, 360, Resolution.Daily); +foreach (var contracts in history) { - Console.WriteLine($"{bet.Symbol} rank at {bet.EndTime}: {bet.Rank}"); + foreach (QuiverGovernmentContract contract in contracts) + { + Console.WriteLine($"{contract.Symbol} amount at {contract.EndTime}: {contract.Amount}"); + } } // Add Universe Selection IEnumerable<Symbol> UniverseSelection(IEnumerable<BaseData> altCoarse) { - return from d in altCoarse.OfType<QuiverWallStreetBetsUniverse>() - where d.Mentions > 10 && d.Rank < 100 select d.Symbol; + return from d in altCoarse.OfType<QuiverGovernmentContractUniverse>() + select d.Symbol; } -var universe = qb.AddUniverse<QuiverWallStreetBetsUniverse>(UniverseSelection); +var universe = qb.AddUniverse<QuiverGovernmentContractUniverse<(UniverseSelection); // Historical Universe data -var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-60), qb.Time); -foreach (var bets in universeHistory) +var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-360), qb.Time); +foreach (var contracts in universeHistory) { - foreach (QuiverWallStreetBetsUniverse bet in bets) + foreach (QuiverGovernmentContractUniverse contract in contracts) { - Console.WriteLine($"{bet.Symbol} rank at {bet.EndTime}: {bet.Rank}"); + Console.WriteLine($"{contract.Symbol} amount at {contract.EndTime}: {contract.Amount}"); } }qb = QuantBook() -# Requesting data +# Requesting Data aapl = qb.add_equity("AAPL", Resolution.DAILY).symbol -symbol = qb.add_data(QuiverWallStreetBets, aapl).symbol +symbol = qb.add_data(QuiverGovernmentContract, aapl).symbol # Historical data -history = qb.history(QuiverWallStreetBets, symbol, 60, Resolution.DAILY) -for (symbol, time), bet in history.iterrows(): - print(f"{symbol} rank at {time}: {bet['rank']}") +history = qb.history(QuiverGovernmentContract, symbol, 360, Resolution.DAILY) +for (symbol, time), contracts in history.items(): + for contract in contracts: + print(f"{contract.symbol} amount at {contract.end_time}: {contract.amount}") # Add Universe Selection -def universe_selection(alt_coarse: List[QuiverWallStreetBetsUniverse]) -> List[Symbol]: - return [d.symbol for d in alt_coarse if d.mentions > 10 and d.rank < 100] +def universe_selection(alt_coarse: List[QuiverGovernmentContractUniverse]) -> List[Symbol]: + return [d.symbol for d in alt_coarse] -universe = qb.add_universe(QuiverWallStreetBetsUniverse, universe_selection) +universe = qb.add_universe(QuiverGovernmentContractUniverse, universe_selection) # Historical Universe data -universe_history = qb.universe_history(universe, qb.time-timedelta(60), qb.time) -for (univere_symbol, time), bets in universe_history.items(): - for bet in bets: - print(f"{bet.symbol} rank at {bet.end_time}: {bet.rank}")+universe_history = qb.universe_history(universe, qb.time-timedelta(360), qb.time) +for (_, time), contracts in universe_history.items(): + for contract in contracts: + print(f"{contract.symbol} amount at {contract.end_time}: {contract.amount}")
- The WallStreetBets dataset provides
+ The US Government Contracts dataset provides
- QuiverWallStreetBets
+ QuiverGovernmentContract
and
- QuiverWallStreetBetsUniverse
+ QuiverGovernmentContractUniverse
objects.
- QuiverWallStreetBets
+ QuiverGovernmentContract
objects have the following attributes:
- QuiverWallStreetBetsUniverse
+ QuiverGovernmentContractUniverse
objects have the following attributes:
public class CorporateBuybacksDataAlgorithm : QCAlgorithm
{
- private Symbol _aapl;
- private Symbol _smartInsiderIntention;
- private Symbol _smartInsiderTransaction;
+ private Equity _equity;
+ private Symbol _smartInsiderIntentionData;
+ private Symbol _smartInsiderTransactionData;
private DateTime _entryTime;
-
+
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
-
- _aapl = AddEquity("AAPL", Resolution.Minute).Symbol;
-
- // Requesting insider trade intention news and actual trades to estimate the return, since insiders may have better information of the future confidence
- _smartInsiderIntention = AddData<SmartInsiderIntention>(_aapl).Symbol;
- _smartInsiderTransaction = AddData<SmartInsiderTransaction>(_aapl).Symbol;
-
- // Historical data
- var intentionHistory = History<SmartInsiderIntention>(_smartInsiderIntention, 365, Resolution.Daily);
- Debug($"We got {intentionHistory.Count()} items from our history request for intentions");
-
- var transactionHistory = History<SmartInsiderTransaction>(_smartInsiderTransaction, 365, Resolution.Daily);
- Debug($"We got {transactionHistory.Count()} items from our history request for transactions");
+ _equity = AddEquity("AAPL", Resolution.Daily);
+ // Request insider trade intention news and actual trades because insiders may have better information about future prospects.
+ _smartInsiderIntentionData = AddData<SmartInsiderIntention>(_equity.Symbol).Symbol;
+ _smartInsiderTransactionData = AddData<SmartInsiderTransaction>(_equity.Symbol).Symbol;
+ // Warm up custom data subscriptions with historical data.
+ var intentionHistory = History<SmartInsiderIntention>(_smartInsiderIntentionData, TimeSpan.FromDays(365), Resolution.Daily);
+ var intentionCount = intentionHistory.Count();
+ Debug($"We got {intentionCount} items from our history request for intentions");
+ var transactionHistory = History<SmartInsiderTransaction>(_smartInsiderTransactionData, TimeSpan.FromDays(365), Resolution.Daily);
+ var transactionCount = transactionHistory.Count();
+ Debug($"We got {transactionCount} items from our history request for transactions");
}
- public override void OnData(Slice slice)
+ public override void OnData(Slice data)
{
- // Buy Apple whenever we receive a buyback intention or transaction notification, given the insiders may have confidence in the future to buy more
- // This news may stimulate market popularity
- if (slice.ContainsKey(_smartInsiderIntention) || slice.ContainsKey(_smartInsiderTransaction))
+ // Buy Apple when insider buyback events suggest stronger sentiment and potential market attention.
+ if (data.ContainsKey(_smartInsiderIntentionData) || data.ContainsKey(_smartInsiderTransactionData))
{
- SetHoldings(_aapl, 1);
+ SetHoldings(_equity.Symbol, 1);
_entryTime = Time;
}
-
- // Liquidate holdings 3 days after the latest entry
- // The market popularity and possible overbrought is cooled
+ // Liquidate after three days so the position exits once the event reaction has cooled.
if (Portfolio.Invested && Time >= _entryTime + TimeSpan.FromDays(3))
{
Liquidate();
@@ -277927,7 +279293,69 @@ Transport Binary Data
- Follow these steps to transport binary files:
+ Follow these steps to transport binary files with
+
+ joblib
+
+ :
+
+
+ -
+ Add the following imports to your local program:
+
+
+ import joblib
+from io import BytesIO
+from base64 import b64encode, b64decode
+
+ -
+ Serialize your object and save it to a file. This Base64 serialization is necessary because the default
+
+ joblib.dump
+
+ serialization produces a binary file that the
+
+ download
+
+ method can't read without data corruption.
+
+
+ buffer = BytesIO()
+joblib.dump(my_object, buffer)
+base64_str = b64encode(buffer.getvalue()).decode('ascii')
+with open("my_model.b64", "w") as f:
+ f.write(base64_str)
+
+ -
+ Save the file to one of the
+
+ supported sources
+
+ . For example, save the file to Dropbox.
+
+ -
+
+ Download the remote file
+
+ into your project.
+
+
+ base64_str = self.download("<fileURL>")
+
+ -
+ Restore the object.
+
+
+ model_bytes = b64decode(base64_str.encode('ascii'))
+restored_model = joblib.load(BytesIO(model_bytes))
+
+
+
+ Follow these steps to transport binary files with
+
+ pickle
+
+ :
-
@@ -277935,21 +279363,23 @@
Transport Binary Data
import pickle
-import base64
+from base64 import b64encode, b64decode
-
- Serialize your object.
+ Serialize your object and save it to a file.
pickle_bytes = pickle.dumps(my_object)
-base64_str = base64.b64encode(pickle_bytes).decode('ascii')
+base64_str = b64encode(pickle_bytes).decode('ascii')
+with open("my_model.b64", "w") as f:
+ f.write(base64_str)
-
- Save the string representation of your object to one of the
+ Save the file to one of the
supported sources
- .
+ . For example, save the file to Dropbox.
-
@@ -277964,9 +279394,8 @@
Transport Binary Data
Restore the object.
- base64_bytes = base64_str.encode('ascii')
-model = base64.b64decode(base64_bytes)
-restored_model = pickle.loads(model)
+ model_bytes = b64decode(base64_str.encode('ascii'))
+restored_model = pickle.loads(model_bytes)
@@ -277997,9 +279426,11 @@
method.
- from sklearn.svm import SVR
+ import joblib
+from io import BytesIO
+from base64 import b64decode, b64encode
+from sklearn.svm import SVR
from sklearn.model_selection import GridSearchCV
-import joblib
class BulkDownloadExampleAlgorithm(QCAlgorithm):
def initialize(self) -> None:
@@ -278007,23 +279438,25 @@
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
# Request SPY data for model training, prediction, and trading.
- self.symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
# 2-year data to train the model.
training_length = 252*2
self.training_data = RollingWindow(training_length)
# Warm up the training dataset to train the model immediately.
- history = self.history[TradeBar](self.symbol, training_length, Resolution.DAILY)
+ history = self.history[TradeBar](self._symbol, training_length, Resolution.DAILY)
for trade_bar in history:
self.training_data.add(trade_bar)
# Retrieve the already trained model from the object store for immediate use.
if self.object_store.contains_key("sklearn_model"):
- file = self.object_store.get_file_path("sklearn_model")
- # Otherwise, bulk-download the model from an external source (Dropbox in this example).
+ self.model = joblib.load(self.object_store.get_file_path("sklearn_model"))
+ # Otherwise, bulk-download the base64-encoded model from an external source (Dropbox in this example).
else:
- file = self.download("https://www.dropbox.com/scl/fi/nhz2zxq3pr2bweia4av0o/sklearn_model?rlkey=loy09wbh69k9j6umlru9icsaj&st=6vdazyp4&dl=1")
- self.model = joblib.load(file)
+ url = "https://www.dropbox.com/scl/fi/tj7wmpv1u2ysvejb0skpm/sklearn_model_b64?rlkey=pvcnuvqrp78oz1t73rytgnvdx&dl=1"
+ base64_str = self.download(url)
+ model_bytes = b64decode(base64_str.encode('ascii'))
+ self.model = joblib.load(BytesIO(model_bytes))
# Train the model to use the prediction right away.
self.train(self.my_training_method)
@@ -278056,8 +279489,9 @@
self.model = self.model.fit(features, labels)
def on_data(self, slice: Slice) -> None:
- if self.symbol in slice.bars:
- self.training_data.add(slice.bars[self.symbol])
+ bar = slice.bars.get(self._symbol)
+ if bar:
+ self.training_data.add(bar)
# Get predictions by the updated features.
features, _ = self.get_features_and_labels()
@@ -278066,16 +279500,28 @@
# If the predicted direction is going upward, buy SPY.
if prediction > 0:
- self.set_holdings(self.symbol, 1)
+ self.set_holdings(self._symbol, 1)
# If the predicted direction is going downward, sell SPY.
elif prediction < 0:
- self.set_holdings(self.symbol, -1)
+ self.set_holdings(self._symbol, -1)
def on_end_of_algorithm(self) -> None:
# Store the model in the object store to retrieve it in other instances if the algorithm stops.
model_key = "sklearn_model"
- file_name = self.object_store.get_file_path(model_key)
- joblib.dump(self.model, file_name)
+ joblib.dump(self.model, self.object_store.get_file_path(model_key))
+ self._save_base64_encoded_version(model_key)
+
+ def _save_base64_encoded_version(self, model_key):
+ # Save a base64-encoded version of the model to upload to an external source (e.g., Dropbox).
+ buffer = BytesIO()
+ joblib.dump(self.model, buffer)
+ content = b64encode(buffer.getvalue()).decode('ascii')
+ path = self.object_store.get_file_path(f"{model_key}_b64")
+ self.object_store.save(path, content)
+
+ # Locally, you may want to use the open method
+ #with open(path, "w") as f:
+ # f.write(content)
Other Examples
@@ -331168,11 +332614,11 @@ Introduction
limit orders
- for muliple securities. Combo limit orders are different from
+ for multiple securities. Combo limit orders are different from
combo leg limit orders
- because you must set the limit price of all the leg orders to be the same with combo limit orders. With combo leg limit orders, you can create the order without forcing each leg to have the same limit price. Combo limit orders currently only work for trading Option contracts and their underlying Equities.
+ because you set a single limit price for the combined (net) price of all the legs, rather than a separate limit price per leg. Combo limit orders currently only work for trading Option contracts and their underlying Equities.
@@ -331859,11 +333305,11 @@ Introduction
limit orders
- for muliple securities. Combo leg limit orders are different from
+ for multiple securities. Combo leg limit orders are different from
combo limit orders
- because you can create combo leg limit orders without forcing each leg to have the same limit price. Combo leg limit orders currently only work for trading Option contracts.
+ because you set a separate limit price for each leg, rather than a single limit price for the combined (net) price of all the legs. Combo leg limit orders currently only work for trading Option contracts.
@@ -356613,7 +358059,11 @@ Tags
Order
- class you can set. To set an order tag, pass it as an argument when you create the order or use the order update methods.
+ class you can set. To set an order tag, pass it as an argument when you create the order or use the order update methods. This is useful for
+
+ debugging
+
+ your algorithm's trading logic because you can include the indicator values or conditions that triggered the order.
// Tag an order on creation
@@ -387427,7 +388877,7 @@ Account Currency
set the account currency
to USDT or another
-
+
Cryptocurrency that Binance supports
.
@@ -404459,6 +405909,58 @@ Date Rules
Trigger an event on the last tradable date of each week for a specific symbol minus an offset.
+ self.date_rules.quarter_start(days_offset: int = 0)
+
+
+ DateRules.QuarterStart(int daysOffset = 0)
+
+
+ self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterStart(Symbol symbol, int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(Symbol symbol, int daysOffset = 0)
+
+
@@ -405194,12 +406696,26 @@ Examples
TimeRules.AfterMarketOpen("SPY", 5),
RebalancingCode);
- // Schedule an event to fire at the end of the week, the symbol is optional.
+ // Schedule an event to fire at the end of the week, the symbol is optional.
// If specified, it will fire the last trading day for that symbol of the week.
// Otherwise, it will fire on the first day of the week.
Schedule.On(DateRules.WeekEnd("SPY"),
TimeRules.BeforeMarketClose("SPY", 5),
RebalancingCode);
+
+ // Schedule an event to fire at the beginning of the quarter, the symbol is optional.
+ // If specified, it will fire the first trading day for that symbol of the quarter.
+ // Otherwise, it will fire on the first day of the quarter.
+ Schedule.On(DateRules.QuarterStart("SPY"),
+ TimeRules.AfterMarketOpen("SPY"),
+ RebalancingCode);
+
+ // Schedule an event to fire at the end of the quarter, the symbol is optional.
+ // If specified, it will fire the last trading day for that symbol of the quarter.
+ // Otherwise, it will fire on the last day of the quarter.
+ Schedule.On(DateRules.QuarterEnd("SPY"),
+ TimeRules.BeforeMarketClose("SPY"),
+ RebalancingCode);
}
// The following methods are not defined in Initialize:
@@ -405301,6 +406817,20 @@ Examples
self.time_rules.before_market_close("SPY", 5),
self._rebalancing_code)
+ # Schedule an event to fire at the beginning of the quarter, the symbol is optional.
+ # If specified, it will fire the first trading day for that symbol of the quarter.
+ # Otherwise, it will fire on the first day of the quarter.
+ self.schedule.on(self.date_rules.quarter_start("SPY"),
+ self.time_rules.after_market_open("SPY"),
+ self._rebalancing_code)
+
+ # Schedule an event to fire at the end of the quarter, the symbol is optional.
+ # If specified, it will fire the last trading day for that symbol of the quarter.
+ # Otherwise, it will fire on the last day of the quarter.
+ self.schedule.on(self.date_rules.quarter_end("SPY"),
+ self.time_rules.before_market_close("SPY"),
+ self._rebalancing_code)
+
# The following methods from examples above should be defined in the algorithm body.
def _liquidate_unrealized_losses(self) -> None:
''' if we have over 1000 dollars in unrealized losses, liquidate'''
@@ -406764,6 +408294,17 @@
+
For more information about this indicator, see its
@@ -451429,6 +453003,13 @@
Indicator History
var indicatorHistory = IndicatorHistory(_swiss, _symbol, 100, Resolution.Minute);
var timeSpanIndicatorHistory = IndicatorHistory(_swiss, _symbol, TimeSpan.FromDays(10), Resolution.Minute);
var timePeriodIndicatorHistory = IndicatorHistory(_swiss, _symbol, new DateTime(2024, 7, 1), new DateTime(2024, 7, 5), Resolution.Minute);
+
+ // Access all attributes of indicatorHistory
+ var gauss = indicatorHistory.Select(x => ((dynamic)x).Gauss).ToList();
+ var butter = indicatorHistory.Select(x => ((dynamic)x).Butter).ToList();
+ var highPass = indicatorHistory.Select(x => ((dynamic)x).HighPass).ToList();
+ var twoPoleHighPass = indicatorHistory.Select(x => ((dynamic)x).TwoPoleHighPass).ToList();
+ var bandPass = indicatorHistory.Select(x => ((dynamic)x).BandPass).ToList();
}
}
class SwissArmyKnifeAlgorithm(QCAlgorithm):
@@ -451439,7 +453020,14 @@ Indicator History
indicator_history = self.indicator_history(self._swiss, self._symbol, 100, Resolution.MINUTE)
timedelta_indicator_history = self.indicator_history(self._swiss, self._symbol, timedelta(days=10), Resolution.MINUTE)
time_period_indicator_history = self.indicator_history(self._swiss, self._symbol, datetime(2024, 7, 1), datetime(2024, 7, 5), Resolution.MINUTE)
-
+
+ # Access all attributes of indicator_history
+ indicator_history_df = indicator_history.data_frame
+ gauss = indicator_history_df["gauss"]
+ butter = indicator_history_df["butter"]
+ high_pass = indicator_history_df["highpass"]
+ two_pole_high_pass = indicator_history_df["twopolehighpass"]
+ band_pass = indicator_history_df["bandpass"]
@@ -456706,9 +458294,299 @@ Indicator History
-
+
+ Supported Indicators
+ Wave Trend Oscillator
+
+
+Introduction
+
+
+
+
+ The WaveTrend Oscillator (WTO) is a momentum indicator that highlights overbought and oversold conditions by measuring how far the typical price has deviated from a smoothed moving average, normalized by an exponentially smoothed mean absolute deviation. The oscillator's main line (WT1) is an EMA of this normalized channel index, and the signal line (WT2) is an SMA of WT1; crossovers between the two lines are commonly used as entry and exit signals. Formula: HLC3 = (High + Low + Close) / 3 ESA = EMA(HLC3, channelPeriod) D = EMA(|HLC3 - ESA|, channelPeriod) CI = (HLC3 - ESA) / (0.015 * D) WT1 = EMA(CI, averagePeriod) (the indicator's Current.Value) WT2 = SMA(WT1, signalPeriod) (exposed via
+
+
+ )
+
+
+ To view the implementation of this indicator, see the
+
+ LEAN GitHub repository
+
+ .
+
+
+
+
+Using WTO Indicator
+
+
+
+ To create an automatic indicator for
+
+ WaveTrendOscillator
+
+ , call the
+
+ WTO
+
+
+ wto
+
+ helper method from the
+
+ QCAlgorithm
+
+ class. The
+
+ WTO
+
+
+ wto
+
+ method creates a
+
+ WaveTrendOscillator
+
+ object, hooks it up for automatic updates, and returns it so you can used it in your algorithm. In most cases, you should call the helper method in the
+
+ Initialize
+
+
+ initialize
+
+ method.
+
+
+
+
+ public class WaveTrendOscillatorAlgorithm : QCAlgorithm
+{
+ private Symbol _symbol;
+ private WaveTrendOscillator _wto;
+
+ public override void Initialize()
+ {
+ _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
+ _wto = WTO(_symbol, 10, 21, 4);
+ }
+
+ public override void OnData(Slice data)
+ {
+
+ if (_wto.IsReady)
+ {
+ // The current value of _wto is represented by itself (_wto)
+ // or _wto.Current.Value
+ Plot("WaveTrendOscillator", "wto", _wto);
+ // Plot all properties of abands
+ Plot("WaveTrendOscillator", "channelaverage", _wto.ChannelAverage);
+ Plot("WaveTrendOscillator", "channeldeviation", _wto.ChannelDeviation);
+ Plot("WaveTrendOscillator", "channelindexaverage", _wto.ChannelIndexAverage);
+ Plot("WaveTrendOscillator", "signal", _wto.Signal);
+ }
+ }
+}
+ class WaveTrendOscillatorAlgorithm(QCAlgorithm):
+ def initialize(self) -> None:
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+ self._wto = self.wto(self._symbol, 10, 21, 4)
+
+ def on_data(self, slice: Slice) -> None:
+
+ if self._wto.is_ready:
+ # The current value of self._wto is represented by self._wto.current.value
+ self.plot("WaveTrendOscillator", "wto", self._wto.current.value)
+ # Plot all attributes of self._wto
+ self.plot("WaveTrendOscillator", "channel_average", self._wto.channel_average.current.value)
+ self.plot("WaveTrendOscillator", "channel_deviation", self._wto.channel_deviation.current.value)
+ self.plot("WaveTrendOscillator", "channel_index_average", self._wto.channel_index_average.current.value)
+ self.plot("WaveTrendOscillator", "signal", self._wto.signal.current.value)
+
+
+ For more information about this method, see the
+
+ QCAlgorithm class
+
+
+ QCAlgorithm class
+
+ .
+
+
+ You can manually create a
+
+ WaveTrendOscillator
+
+ indicator, so it doesn't automatically update. Manual indicators let you update their values with any data you choose.
+
+
+ Updating your indicator manually enables you to control when the indicator is updated and what data you use to update it. To manually update the indicator, call the
+
+ Update
+
+
+ update
+
+ method. The indicator will only be ready after you prime it with enough data.
+
+
+ public class WaveTrendOscillatorAlgorithm : QCAlgorithm
+{
+ private Symbol _symbol;
+ private WaveTrendOscillator _wavetrendoscillator;
+
+ public override void Initialize()
+ {
+ _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
+ _wavetrendoscillator = new WaveTrendOscillator(10, 21, 4);
+ }
+
+ public override void OnData(Slice data)
+ {
+ if (data.Bars.TryGetValue(_symbol, out var bar))
+ _wavetrendoscillator.Update(bar);
+
+ if (_wavetrendoscillator.IsReady)
+ {
+ // The current value of _wavetrendoscillator is represented by itself (_wavetrendoscillator)
+ // or _wavetrendoscillator.Current.Value
+ Plot("WaveTrendOscillator", "wavetrendoscillator", _wavetrendoscillator);
+ // Plot all properties of abands
+ Plot("WaveTrendOscillator", "channelaverage", _wavetrendoscillator.ChannelAverage);
+ Plot("WaveTrendOscillator", "channeldeviation", _wavetrendoscillator.ChannelDeviation);
+ Plot("WaveTrendOscillator", "channelindexaverage", _wavetrendoscillator.ChannelIndexAverage);
+ Plot("WaveTrendOscillator", "signal", _wavetrendoscillator.Signal);
+ }
+ }
+}
+ class WaveTrendOscillatorAlgorithm(QCAlgorithm):
+ def initialize(self) -> None:
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+ self._wavetrendoscillator = WaveTrendOscillator(10, 21, 4)
+
+ def on_data(self, slice: Slice) -> None:
+ bar = slice.bars.get(self._symbol)
+ if bar:
+ self._wavetrendoscillator.update(bar)
+
+ if self._wavetrendoscillator.is_ready:
+ # The current value of self._wavetrendoscillator is represented by self._wavetrendoscillator.current.value
+ self.plot("WaveTrendOscillator", "wavetrendoscillator", self._wavetrendoscillator.current.value)
+ # Plot all attributes of self._wavetrendoscillator
+ self.plot("WaveTrendOscillator", "channel_average", self._wavetrendoscillator.channel_average.current.value)
+ self.plot("WaveTrendOscillator", "channel_deviation", self._wavetrendoscillator.channel_deviation.current.value)
+ self.plot("WaveTrendOscillator", "channel_index_average", self._wavetrendoscillator.channel_index_average.current.value)
+ self.plot("WaveTrendOscillator", "signal", self._wavetrendoscillator.signal.current.value)
+
+
+ For more information about this indicator, see its
+
+ reference
+
+
+ reference
+
+ .
+
+
+
+
+Visualization
+
+
+
+
+ The following plot shows values for some of the
+
+ WaveTrendOscillator
+
+ indicator properties:
+
+
+
+
+
+Indicator History
+
+
+
+ To get the historical data of the
+
+ WaveTrendOscillator
+
+ indicator, call the
+
+ IndicatorHistory
+
+
+ self.indicator_history
+
+ method. This method resets your indicator, makes a
+
+ history request
+
+ , and updates the indicator with the historical data. Just like with regular history requests, the
+
+ IndicatorHistory
+
+
+ indicator_history
+
+ method supports time periods based on a trailing number of bars, a trailing period of time, or a defined period of time. If you don't provide a
+
+ resolution
+
+ argument, it defaults to match the resolution of the security subscription.
+
+
+ public class WaveTrendOscillatorAlgorithm : QCAlgorithm
+{
+ private Symbol _symbol;
+ private WaveTrendOscillator _wto;
+
+ public override void Initialize()
+ {
+ _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
+ _wto = WTO(_symbol, 10, 21, 4);
+
+ var indicatorHistory = IndicatorHistory(_wto, _symbol, 100, Resolution.Minute);
+ var timeSpanIndicatorHistory = IndicatorHistory(_wto, _symbol, TimeSpan.FromDays(10), Resolution.Minute);
+ var timePeriodIndicatorHistory = IndicatorHistory(_wto, _symbol, new DateTime(2024, 7, 1), new DateTime(2024, 7, 5), Resolution.Minute);
+
+ // Access all attributes of indicatorHistory
+ var channelAverage = indicatorHistory.Select(x => ((dynamic)x).ChannelAverage).ToList();
+ var channelDeviation = indicatorHistory.Select(x => ((dynamic)x).ChannelDeviation).ToList();
+ var channelIndexAverage = indicatorHistory.Select(x => ((dynamic)x).ChannelIndexAverage).ToList();
+ var signal = indicatorHistory.Select(x => ((dynamic)x).Signal).ToList();
+ }
+}
+ class WaveTrendOscillatorAlgorithm(QCAlgorithm):
+ def initialize(self) -> None:
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+ self._wto = self.wto(self._symbol, 10, 21, 4)
+
+ indicator_history = self.indicator_history(self._wto, self._symbol, 100, Resolution.MINUTE)
+ timedelta_indicator_history = self.indicator_history(self._wto, self._symbol, timedelta(days=10), Resolution.MINUTE)
+ time_period_indicator_history = self.indicator_history(self._wto, self._symbol, datetime(2024, 7, 1), datetime(2024, 7, 5), Resolution.MINUTE)
+
+ # Access all attributes of indicator_history
+ indicator_history_df = indicator_history.data_frame
+ channel_average = indicator_history_df["channelaverage"]
+ channel_deviation = indicator_history_df["channeldeviation"]
+ channel_index_average = indicator_history_df["channelindexaverage"]
+ signal = indicator_history_df["signal"]
+
+
+
+
+
+
+
+
Supported Indicators
Wilder Accumulative Swing Index
@@ -456993,7 +458871,7 @@ Indicator History
-
+
Supported Indicators
Wilder Moving Average
@@ -457248,7 +459126,7 @@ Indicator History
-
+
Supported Indicators
Wilder Swing Index
@@ -457591,7 +459469,7 @@ Indicator History
-
+
Supported Indicators
Williams Percent R
@@ -457866,7 +459744,7 @@ Indicator History
-
+
Supported Indicators
Zero Lag Exponential Moving Average
@@ -458121,7 +459999,7 @@ Indicator History
-
+
Supported Indicators
Zig Zag
@@ -463363,6 +465241,276 @@
def is_ready(self) -> bool:
return len(self.positive_money_flow) == self.positive_money_flow.maxlen
+
+ Example 3: Custom Annualized Volatility Indicator
+
+
+ The following algorithm implements a custom annualized log-return volatility indicator using a rolling window of close prices.
+ It screens a
+
+ dynamic Equity universe
+
+ for overbought stocks whose annualized volatility exceeds 100% and enters short positions via
+
+ limit orders
+
+ using an equal-weight allocation, exiting when the
+
+ Connors Relative Strength Index
+
+ reverts below the exit threshold.
+
+
+ public class ConnorsCrashAlgorithm : QCAlgorithm
+{
+ private readonly int _rsiPeriod = 3, _streakPeriod = 2, _pctRankPeriod = 100, _volaPeriod = 100, _maxShorts = 40;
+ private readonly decimal _crsiEntry = 90m, _crsiExit = 30m;
+ private Universe _universe;
+ private readonly Dictionary<Symbol, (ConnorsRelativeStrengthIndex Crsi, CustomVolatility Vola)> _indicators = new();
+
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ SetCash(100_000);
+
+ Settings.AutomaticIndicatorWarmUp = true;
+ Settings.SeedInitialPrices = true;
+ UniverseSettings.Resolution = Resolution.Daily;
+
+ // Select liquid, tradeable-priced equities for the universe.
+ _universe = AddUniverse(fundamentals =>
+ fundamentals.Where(f => f.Price > 5 && f.DollarVolume > 1e6).Select(f => f.Symbol));
+
+ Schedule.On(
+ DateRules.EveryDay("SPY"),
+ TimeRules.At(8, 0),
+ Rebalance
+ );
+ }
+
+ public override void OnSecuritiesChanged(SecurityChanges changes)
+ {
+ foreach (var security in changes.AddedSecurities)
+ {
+ // Attach ConnorsRSI indicator to each security.
+ var crsi = CRSI(security.Symbol, _rsiPeriod, _streakPeriod, _pctRankPeriod);
+ // Initialize and warm up the custom volatility indicator.
+ var vola = new CustomVolatility(_volaPeriod);
+ foreach (var bar in History<TradeBar>(security.Symbol, _volaPeriod + 1))
+ {
+ vola.Update(bar);
+ }
+ RegisterIndicator(security.Symbol, vola, Resolution.Daily);
+ _indicators[security.Symbol] = (crsi, vola);
+ }
+ foreach (var security in changes.RemovedSecurities)
+ {
+ if (_indicators.TryGetValue(security.Symbol, out var pair))
+ {
+ DeregisterIndicator(pair.Crsi);
+ DeregisterIndicator(pair.Vola);
+ _indicators.Remove(security.Symbol);
+ }
+ Liquidate(security.Symbol);
+ }
+ }
+
+ private void Rebalance()
+ {
+ if (!_universe.Selected.Any()) return;
+
+ // Filter to securities with ready indicators.
+ var securities = _universe.Selected
+ .Where(s => Securities.ContainsKey(s) && _indicators.ContainsKey(s)
+ && _indicators[s].Crsi.IsReady && _indicators[s].Vola.IsReady)
+ .Select(s => Securities[s])
+ .ToList();
+
+ // Filter to securities with above-threshold annualized volatility.
+ var filterVola = securities.Where(s => _indicators[s.Symbol].Vola.Current.Value > 100).ToList();
+
+ // Find currently invested short positions.
+ var shortPositions = securities.Where(s => s.Holdings.IsShort).ToList();
+
+ // Liquidate short positions when ConnorsRSI falls below exit threshold.
+ foreach (var security in shortPositions)
+ {
+ if (_indicators[security.Symbol].Crsi.Current.Value < _crsiExit)
+ {
+ Liquidate(security.Symbol);
+ }
+ }
+
+ // Exclude symbols with pending open orders.
+ var pendingSymbols = Transactions.GetOpenOrderTickets()
+ .Select(t => t.Symbol)
+ .ToHashSet();
+
+ // Find short entry candidates that are not currently invested (high volatility and high CRSI).
+ var shortCandidates = filterVola
+ .Where(s => _indicators[s.Symbol].Crsi.Current.Value > _crsiEntry
+ && !s.Holdings.Invested
+ && !pendingSymbols.Contains(s.Symbol))
+ .OrderBy(s => _indicators[s.Symbol].Crsi.Current.Value)
+ .ThenBy(s => _indicators[s.Symbol].Vola.Current.Value)
+ .ToList();
+
+ // Set union: liquidated positions are only counted once.
+ var occupied = shortPositions.Select(s => s.Symbol).ToHashSet();
+ occupied.UnionWith(pendingSymbols);
+ var availableSlots = _maxShorts - occupied.Count;
+
+ if (availableSlots <= 0 || !shortCandidates.Any()) return;
+
+ var nOrders = Math.Min(shortCandidates.Count, availableSlots);
+ var targetWeight = -1m / _maxShorts;
+
+ foreach (var security in shortCandidates.TakeLast(nOrders))
+ {
+ var quantity = (int)CalculateOrderQuantity(security.Symbol, targetWeight);
+ if (quantity != 0)
+ {
+ LimitOrder(security.Symbol, quantity, Math.Round(1.03m * security.Price, 2));
+ }
+ }
+ }
+}
+
+public class CustomVolatility : TradeBarIndicator, IIndicatorWarmUpPeriodProvider
+{
+ private readonly RollingWindow<double> _window;
+
+ public override bool IsReady => _window.IsReady;
+ public int WarmUpPeriod => _window.Size;
+
+ public CustomVolatility(int period) : base("CustomVolatility")
+ {
+ _window = new RollingWindow<double>(period);
+ }
+
+ protected override decimal ComputeNextValue(TradeBar input)
+ {
+ // Annualized log-return volatility.
+ var price = (double)input.Value;
+ if (price <= 0) return Current.Value;
+
+ _window.Add(price);
+ if (!_window.IsReady) return 0m;
+
+ // Collect prices from oldest to newest to compute chronological log returns.
+ var prices = _window.ToArray().Reverse().ToArray();
+ var logDiffs = new double[prices.Length - 1];
+ for (var i = 0; i < logDiffs.Length; i++)
+ {
+ logDiffs[i] = Math.Log(prices[i + 1] / prices[i]);
+ }
+
+ // Annualized standard deviation of log returns.
+ var mean = logDiffs.Average();
+ var variance = logDiffs.Select(d => (d - mean) * (d - mean)).Average();
+ return (decimal)(Math.Sqrt(variance) * Math.Sqrt(252) * 100.0);
+ }
+}
+ class ConnorsCrash(QCAlgorithm):
+
+ def initialize(self):
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ self.set_cash(100_000)
+ self._rsi_period = 3
+ self._streak_period = 2
+ self._pct_rank_period = 100
+ self._vola_period = 100
+ self._crsi_entry = 90
+ self._crsi_exit = 30
+ self._max_shorts = 40
+ self._stop_trading_days_before_end = 1
+ self.settings.automatic_indicator_warm_up = True
+ self.settings.seed_initial_prices = True
+ self.universe_settings.resolution = Resolution.DAILY
+ # Select liquid, tradeable-priced equities for the universe.
+ self._universe = self.add_universe(
+ lambda fundamentals: [f.symbol for f in fundamentals if f.price > 5 and f.dollar_volume > 1e6]
+ )
+ self.schedule.on(
+ self.date_rules.every_day('SPY'),
+ self.time_rules.at(8, 0),
+ self._rebalance
+ )
+
+ def on_securities_changed(self, changes):
+ for security in changes.added_securities:
+ # Attach ConnorsRSI indicator to each security.
+ security.connors = self.crsi(security, self._rsi_period, self._streak_period, self._pct_rank_period)
+ # Initialize and warm up the custom volatility indicator.
+ security.volatility = CustomVolatility(self._vola_period)
+ for bar in self.history[TradeBar](security, self._vola_period + 1):
+ security.volatility.update(bar)
+ self.register_indicator(security, security.volatility)
+ for security in changes.removed_securities:
+ self.deregister_indicator(security.connors)
+ self.deregister_indicator(security.volatility)
+ self.liquidate(security)
+
+ def _rebalance(self):
+ if not self._universe.selected:
+ return
+ securities = [self.securities[symbol] for symbol in self._universe.selected]
+ securities = [s for s in securities if s.connors.is_ready and s.volatility.is_ready]
+ filter_vola = [s for s in securities if s.volatility.value > 100]
+ # Find currently invested short positions.
+ short_positions = [s for s in securities if s.holdings.is_short]
+ # Liquidate short positions when ConnorsRSI falls below exit threshold.
+ for security in short_positions:
+ if security.connors.current.value < self._crsi_exit:
+ self.liquidate(security)
+ # Exclude symbols with pending open orders.
+ pending_symbols = {t.symbol for t in self.transactions.get_open_order_tickets()}
+ # Find short entry candidates that are not currently invested (high volatility and high CRSI).
+ short_candidates = sorted([
+ s for s in filter_vola
+ if (s.connors.current.value > self._crsi_entry and
+ not s.holdings.invested and
+ s.symbol not in pending_symbols)
+ ], key=lambda s: (s.connors.current.value, s.volatility.value))
+ # Set union: liquidated positions are only counted once.
+ short_position_symbols = {s.symbol for s in short_positions}
+ occupied = short_position_symbols | pending_symbols
+ available_slots = self._max_shorts - len(occupied)
+ if available_slots <= 0 or not short_candidates:
+ return
+ n_orders = min(len(short_candidates), available_slots)
+ target_weight = -1 / self._max_shorts
+ for security in short_candidates[-n_orders:]:
+ quantity = int(self.calculate_order_quantity(security, target_weight))
+ if quantity:
+ self.limit_order(security, quantity, round(1.03 * security.price, 2))
+
+
+class CustomVolatility(PythonIndicator):
+
+ def __init__(self, period):
+ super().__init__()
+ self.value = 0
+ self._window = RollingWindow[float](period)
+
+ def update(self, input_: BaseData):
+ # Annualized log-return volatility.
+ price = input_.value
+ if price <= 0:
+ return
+ self._window.add(price)
+ if self._window.is_ready:
+ prices = np.array(list(self._window)[::-1])
+ log_diffs = np.diff(np.log(prices))
+ self.value = np.std(log_diffs) * math.sqrt(252) * 100.0
+ return self.is_ready
+
+ @property
+ def is_ready(self) -> bool:
+ return self._window.is_ready
+
Other Examples
@@ -463828,6 +465976,190 @@
self.deregister_indicator(removed.ema)
self.deregister_indicator(removed.sma)
+
+ Example 2: Reset Indicators on Corporate Actions
+
+
+ The following example shows how to select a universe of US Equities based on their price and SMA indicator.
+ The
+
+ SelectionData
+
+ class keeps track of the SMA indicator for each stock in the universe dataset.
+ When a split or dividend occurs for a stock, the data in its indicator becomes invalid because it doesn't account for the price adjustments that the split or dividend causes.
+ The
+
+ SelectionData
+
+ class resets and warms up the indicator with the
+
+ ScaledRaw
+
+
+ SCALED_RAW
+
+
+ data normalization mode
+
+ , which gives you accurate indicator values to use in your universe selection after each corporate action.
+
+
+ class EquityIndicatorUniverseSelectionAlgorithm(QCAlgorithm):
+
+ def initialize(self) -> None:
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ self.settings.seed_initial_prices = True
+ # Add a universe of US Equities based on an indicator.
+ self._selection_data_by_symbol = {}
+ self._universe = self.add_universe(self._select_assets)
+ # Add a warm-up period to warm up the indicators in the universe selection.
+ self.set_warm_up(timedelta(60))
+
+ def _select_assets(self, fundamentals):
+ # Update the indicator of all stocks in the universe dataset and
+ # get the subset of stocks that have their indicator ready.
+ ready_stocks = [
+ f for f in fundamentals
+ if self._selection_data_by_symbol.setdefault(f.symbol, SelectionData(self, f)).update(f)
+ ]
+ # As assests leave the Fundamental dataset, delete their SelectionData object.
+ for symbol in self._selection_data_by_symbol.keys() - {f.symbol for f in fundamentals}:
+ del self._selection_data_by_symbol[symbol]
+ # During warm-up, keep the universe empty.
+ if self.is_warming_up:
+ return []
+ # Select a subset of the stocks based on the indicator.
+ # Example: 10 stocks furthest above their SMA.
+ factor_by_symbol = {
+ f.symbol: f.price / self._selection_data_by_symbol[f.symbol].indicator.current.value
+ for f in ready_stocks
+ }
+ return sorted(
+ {k: v for k, v in factor_by_symbol.items() if v > 0},
+ key=lambda symbol: factor_by_symbol[symbol]
+ )[-100:]
+
+
+class SelectionData:
+
+ def __init__(self, algorithm, f):
+ self._algorithm = algorithm
+ self._price_scale_factor = f.price_scale_factor
+ self.indicator = SimpleMovingAverage(21)
+
+ def update(self, f):
+ # If there hasn't been a split or dividend since the last trading
+ # day, just update the indicator like normal.
+ if f.price_scale_factor == self._price_scale_factor:
+ return self.indicator.update(f.end_time, f.price)
+ # Otherwise, reset the indicator and warm it up with the new
+ # adjusted history.
+ self._price_scale_factor = f.price_scale_factor
+ self.indicator.reset()
+ history = self._algorithm.history[TradeBar](
+ f.symbol,
+ self.indicator.warm_up_period,
+ Resolution.DAILY,
+ data_normalization_mode=DataNormalizationMode.SCALED_RAW
+ )
+ for bar in history:
+ self.indicator.update(bar)
+ return self.indicator.is_ready
+ public class EquityIndicatorUniverseSelectionAlgorithm : QCAlgorithm
+{
+ private Dictionary<Symbol, SelectionData> _selectionDataBySymbol = new();
+ private Universe _universe;
+
+ public override void Initialize()
+ {
+ SetStartDate(2024, 9, 1);
+ SetEndDate(2024, 12, 31);
+ Settings.SeedInitialPrices = true;
+ // Add a universe of US Equities based on an indicator.
+ _universe = AddUniverse(SelectAssets);
+ // Add a warm-up period to warm up the indicators in the universe selection.
+ SetWarmUp(TimeSpan.FromDays(60));
+ }
+
+ private IEnumerable<Symbol> SelectAssets(IEnumerable<Fundamental> fundamentals)
+ {
+ // Update the indicator of all stocks in the universe dataset and
+ // get the subset of stocks that have their indicator ready.
+ var readyStocks = new List<Fundamental>();
+ foreach (var f in fundamentals)
+ {
+ if (!_selectionDataBySymbol.TryGetValue(f.Symbol, out var sd))
+ {
+ sd = new SelectionData(this, f);
+ _selectionDataBySymbol[f.Symbol] = sd;
+ }
+ if (sd.Update(f))
+ {
+ readyStocks.Add(f);
+ }
+ }
+ // As assests leave the Fundamental dataset, delete their SelectionData object.
+ var activeStocks = fundamentals.Select(f => f.Symbol).ToHashSet();
+ foreach (var symbol in _selectionDataBySymbol.Keys.Where(s => !activeStocks.Contains(s)).ToList())
+ {
+ _selectionDataBySymbol.Remove(symbol);
+ }
+ // During warm-up, keep the universe empty.
+ if (IsWarmingUp)
+ {
+ return Enumerable.Empty<Symbol>();
+ }
+ // Select a subset of the stocks based on the indicator.
+ // Example: 10 stocks furthest above their SMA.
+ return readyStocks
+ .Select(f => (f.Symbol, Factor: f.Price / _selectionDataBySymbol[f.Symbol].Indicator.Current.Value))
+ .Where(t => t.Factor > 0)
+ .OrderBy(t => t.Factor)
+ .TakeLast(100)
+ .Select(t => t.Symbol);
+ }
+}
+
+public class SelectionData
+{
+ private QCAlgorithm _algorithm;
+ private decimal _priceScaleFactor;
+ public SimpleMovingAverage Indicator { get; }
+
+ public SelectionData(QCAlgorithm algorithm, Fundamental f)
+ {
+ _algorithm = algorithm;
+ _priceScaleFactor = f.PriceScaleFactor;
+ Indicator = new SimpleMovingAverage(21);
+ }
+
+ public bool Update(Fundamental f)
+ {
+ // If there hasn't been a split or dividend since the last trading
+ // day, just update the indicator like normal.
+ if (f.PriceScaleFactor == _priceScaleFactor)
+ {
+ return Indicator.Update(f.EndTime, f.Price);
+ }
+ // Otherwise, reset the indicator and warm it up with the new
+ // adjusted history.
+ _priceScaleFactor = f.PriceScaleFactor;
+ Indicator.Reset();
+ var history = _algorithm.History<TradeBar>(
+ f.Symbol,
+ Indicator.WarmUpPeriod,
+ Resolution.Daily,
+ dataNormalizationMode: DataNormalizationMode.ScaledRaw
+ );
+ foreach (var bar in history)
+ {
+ Indicator.Update(bar);
+ }
+ return Indicator.IsReady;
+ }
+}
+
Other Examples
@@ -465756,11 +468088,14 @@ Example for Plotting
// Execute the following command in first
-#load "../Initialize.csx"
-
-// Create a QuantBook object
-#load "../QuantConnect.csx"
-using QuantConnect;
+#load "../Initialize.csx"
+
+
+ // Load the necessary assembly files.
+#load "../QuantConnect.csx"
+
+
+ using QuantConnect;
using QuantConnect.Research;
var qb = new QuantBook();
@@ -465801,8 +468136,12 @@ Example for Plotting
packages.
- #r "../Plotly.NET.dll"
-using Plotly.NET;
+ #r "nuget: Plotly.NET"
+#r "nuget: Plotly.NET.Interactive"
+
+
+ using Plotly.NET;
+using Plotly.NET.Interactive;
using Plotly.NET.LayoutObjects;
@@ -465872,15 +468211,11 @@ Example for Plotting
Line
- object and create the
-
- HTML
-
- object.
+ object and display the chart.
chart.WithLayout(layout);
-var result = HTML(GenericChart.toChartHTML(chart));
+display(chart);
@@ -465997,11 +468332,11 @@ Example for Logging
if (_emaShort > _emaLong && !Portfolio[_symbol].IsLong)
{
- MarketOrder(_symbol, 100, tag: $"BUY: ema-short: {_emaShort:F4} > ema-long: {_emaLong:F4}");
+ MarketOrder(_symbol, 100, tag: $"BUY: ema-short: {_emaShort:F4} > ema-long: {_emaLong:F4}");
}
else if (_emaShort < _emaLong && !Portfolio[_symbol].IsShort)
{
- MarketOrder(_symbol, -100, tag: $"SELL: ema-short: {_emaShort:F4} < ema-long: {_emaLong:F4}");
+ MarketOrder(_symbol, -100, tag: $"SELL: ema-short: {_emaShort:F4} < ema-long: {_emaLong:F4}");
}
}
def on_data(self, data: Slice):
@@ -466011,9 +468346,9 @@ Example for Logging
ema_short = self._ema_short.current.value
ema_long = self._ema_long.current.value
if ema_short > ema_long and not self.portfolio[self._symbol].is_long:
- self.market_order(self._symbol, 100, tag=f'BUY: ema-short: {ema_short:.4f} > ema-long: {ema_long:.4f}')
+ self.market_order(self._symbol, 100, tag=f'BUY: ema-short: {ema_short:.4f} > ema-long: {ema_long:.4f}')
elif ema_short < ema_long and not self.portfolio[self._symbol].is_short:
- self.market_order(self._symbol, -100, tag=f'SELL: ema-short: {ema_short:.4f} < ema-long: {ema_long:.4f}')
+ self.market_order(self._symbol, -100, tag=f'SELL: ema-short: {ema_short:.4f} < ema-long: {ema_long:.4f}')
In the
@@ -466073,11 +468408,14 @@ Example for Logging
// Execute the following command in first
-#load "../Initialize.csx"
-
-// Create a QuantBook object
-#load "../QuantConnect.csx"
-using QuantConnect;
+#load "../Initialize.csx"
+
+
+ // Load the necessary assembly files.
+#load "../QuantConnect.csx"
+
+
+ using QuantConnect;
using QuantConnect.Research;
var qb = new QuantBook();
@@ -466201,11 +468539,11 @@ Example for Logging
// Place a market order when the EMAs cross.
if (_emaShort > _emaLong && !Portfolio[_symbol].IsLong)
{
- MarketOrder(_symbol, 100, tag: $"BUY: ema-short: {_emaShort:F4} > ema-long: {_emaLong:F4}");
+ MarketOrder(_symbol, 100, tag: $"BUY: ema-short: {_emaShort:F4} > ema-long: {_emaLong:F4}");
}
else if (_emaShort < _emaLong && !Portfolio[_symbol].IsShort)
{
- MarketOrder(_symbol, -100, tag: $"SELL: ema-short: {_emaShort:F4} < ema-long: {_emaLong:F4}");
+ MarketOrder(_symbol, -100, tag: $"SELL: ema-short: {_emaShort:F4} < ema-long: {_emaLong:F4}");
}
}
@@ -466247,9 +468585,9 @@ Example for Logging
ema_short = self._ema_short.current.value
ema_long = self._ema_long.current.value
if ema_short > ema_long and not self.portfolio[self._symbol].is_long:
- self.market_order(self._symbol, 100, tag=f'BUY: ema-short: {ema_short:.4f} > ema-long: {ema_long:.4f}')
+ self.market_order(self._symbol, 100, tag=f'BUY: ema-short: {ema_short:.4f} > ema-long: {ema_long:.4f}')
elif ema_short < ema_long and not self.portfolio[self._symbol].is_short:
- self.market_order(self._symbol, -100, tag=f'SELL: ema-short: {ema_short:.4f} < ema-long: {ema_long:.4f}')
+ self.market_order(self._symbol, -100, tag=f'SELL: ema-short: {ema_short:.4f} < ema-long: {ema_long:.4f}')
def on_order_event(self, order_event: OrderEvent) -> None:
if order_event.status != OrderStatus.FILLED:
@@ -476991,7 +479329,7 @@ Use Cases
Tiingo
and
-
+
Benzinga
while reducing noise.
@@ -480094,6 +482432,58 @@ Schedule
Trigger an event on the last tradable date of each week for a specific symbol minus an offset.
+ self.date_rules.quarter_start(days_offset: int = 0)
+
+
+ DateRules.QuarterStart(int daysOffset = 0)
+
+
+ self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterStart(Symbol symbol, int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(Symbol symbol, int daysOffset = 0)
+
+
@@ -482007,7 +484397,7 @@ Add ETF Constituents Universe Selection
+ self.date_rules.quarter_start(days_offset: int = 0)
+
+
+ DateRules.QuarterStart(int daysOffset = 0)
+
+
+ self.date_rules.quarter_start(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterStart(Symbol symbol, int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(int daysOffset = 0)
+
+
+ self.date_rules.quarter_end(symbol: Symbol, days_offset: int = 0)
+
+
+ DateRules.QuarterEnd(Symbol symbol, int daysOffset = 0)
+
+
@@ -493138,241 +495580,391 @@
$$
- using Accord.Statistics;
-using MathNet.Numerics.Distributions;
+ using MathNet.Numerics.Distributions;
+
public class FrameworkRiskManagementAlgorithm : QCAlgorithm
{
+
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 9, 15);
SetCash(1000000);
-
// Add a universe of the most liquid stocks since their trend is more capital-supported.
- AddUniverseSelection(new QC500UniverseSelectionModel());
- // Emit insights all for selected stocks, rebalancing every 2 weeks.
+ AddUniverseSelection(new ETFConstituentsUniverseSelectionModel("SPY"));
+ // Emit insights for all selected stocks, rebalancing every two weeks.
AddAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(14)));
// Equal weighting on each insight is needed to dissipate capital risk evenly.
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
-
- // Liquidate on extreme catastrophic event.
+ // Liquidate on extreme catastrophic events.
AddRiskManagement(new TailValueAtRiskRiskManagementModel(0.05d, 14d));
}
+}
- private class TailValueAtRiskRiskManagementModel : RiskManagementModel
- {
- // The alpha level on TVaR calculation.
- private readonly double _alpha;
- // The number of days that the insight signal lasts for.
- private readonly double _days;
- private Dictionary<Symbol, SymbolData> _logRetBySymbol = new();
-
- public TailValueAtRiskRiskManagementModel(double alpha = 0.05d, double numDays = 14d)
- {
- _alpha = alpha;
- _days = numDays;
- }
-
- // Adjust the portfolio targets and return them. If there are no changes, emit nothing.
- public override IEnumerable<PortfolioTarget> ManageRisk(QCAlgorithm algorithm, IPortfolioTarget[] _)
- {
- var targets = new List<PortfolioTarget>();
-
- foreach (var (symbol, security) in algorithm.Securities)
- {
- if (!security.Invested)
- {
- continue;
- }
-
- var pnl = security.Holdings.UnrealizedProfitPercent;
- // If the %PnL is worse than the preset level TVaR, we liquidate it.
- if (pnl < GetTVaR(symbol))
- {
- // Cancel insights to avoid reordering afterward.
- algorithm.Insights.Cancel(new[] { symbol });
- // Liquidate.
- targets.Add(new PortfolioTarget(symbol, 0, tag: "Liquidate due to TVaR"));
- }
- }
-
- return targets;
- }
- private decimal GetTVaR(Symbol symbol)
- {
- if (!_logRetBySymbol.TryGetValue(symbol, out var symbolData))
- {
- return 0m;
- }
+public class TailValueAtRiskRiskManagementModel : RiskManagementModel
+{
+ private const string LogReturnKey = "LogReturn";
+ private const string LogReturnMeanKey = "LogReturnMean";
+ private const string LogReturnSdKey = "LogReturnSd";
+ private readonly double _alpha;
+ private readonly double _days;
+ private readonly List<Security> _securities = [];
- // TVaR = \mu + \sigma * \phi[\Phi^{-1}(p)] / (1 - p)
- // Scale up to the days of the signal. By stochastic calculus, we multiply by sqrt(days).
- var dailyTVaR = symbolData.MeanLogRet + symbolData.SdLogRet * Math.Sqrt(_days) * Normal.PDF(0d, 1d, Normal.InvCDF(0d, 1d, _alpha)) / (1d - _alpha);
- // We want the left side of the symmetric distribution.
- return -Convert.ToDecimal(dailyTVaR);
- }
+ public TailValueAtRiskRiskManagementModel(double alpha = 0.05d, double numDays = 7d)
+ {
+ // Set the alpha level for the TVaR calculation.
+ _alpha = alpha;
+ // Set the number of days the insight signal lasts.
+ _days = numDays;
+ }
- public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
+ public override IEnumerable<PortfolioTarget> ManageRisk(QCAlgorithm algorithm, IPortfolioTarget[] _)
+ {
+ var targets = new List<PortfolioTarget>();
+ foreach (var security in _securities)
{
- foreach (var added in changes.AddedSecurities)
+ if (!security.Invested)
{
- // Add SymbolData class to handle log returns.
- _logRetBySymbol[added.Symbol] = new SymbolData(algorithm, added.Symbol);
+ continue;
}
-
- foreach (var removed in changes.RemovedSecurities)
+ var pnl = security.Holdings.UnrealizedProfitPercent;
+ // Liquidate when the unrealized loss is worse than the preset TVaR level.
+ if (pnl < GetTVaR(security))
{
- // Stop subscription on the data to release computational resources.
- if (_logRetBySymbol.Remove(removed.Symbol, out var symbolData))
- {
- symbolData.Dispose();
- }
+ // Cancel insights to avoid reordering afterward.
+ var symbols = new List<Symbol> { security.Symbol };
+ algorithm.Insights.Cancel(symbols);
+ targets.Add(new PortfolioTarget(security.Symbol, 0, tag: "Liquidate due to TVaR"));
}
}
+ return targets;
}
- private class SymbolData
+ public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
- private readonly QCAlgorithm _algorithm;
- private readonly Symbol _symbol;
- // Since the return is assumed log-normal, we use the log return indicator to calculate TVaR later.
- private LogReturn _logRet = new(1);
- // Set up a rolling window to save the log return for calculating the mean and SD for TVaR calculation.
- private RollingWindow<double> _window = new(252);
-
- public bool IsReady => _window.IsReady;
-
- public double MeanLogRet => _window.Average();
-
- public double SdLogRet => Measures.StandardDeviation(_window.ToArray());
-
- public SymbolData(QCAlgorithm algorithm, Symbol symbol)
+ foreach (var security in changes.AddedSecurities)
{
- _algorithm = algorithm;
- // Register the indicator for automatic updating for daily log returns.
- algorithm.RegisterIndicator(symbol, _logRet, Resolution.Daily);
- // Add a handler to save the log return to the rolling window.
- _logRet.Updated += (_algorithm, point) => _window.Add((double)point.Value);
- // Warm up the rolling window.
- var history = algorithm.History<TradeBar>(symbol, 253, Resolution.Daily);
+ // Store the log return indicator and rolling window directly on the security.
+ var logReturn = algorithm.LOGR(security.Symbol, 1, Resolution.Daily);
+ var logReturnMean = IndicatorExtensions.SMA(logReturn, 252);
+ var logReturnSd = IndicatorExtensions.Of(new StandardDeviation(252), logReturn);
+ security.Set(LogReturnKey, logReturn);
+ security.Set(LogReturnMeanKey, logReturnMean);
+ security.Set(LogReturnSdKey, logReturnSd);
+ var history = algorithm.History<TradeBar>(security.Symbol, 253, Resolution.Daily);
foreach (var bar in history)
{
- _logRet.Update(bar.EndTime, bar.Close);
+ logReturn.Update(bar.EndTime, bar.Close);
}
+ _securities.Add(security);
}
-
- public void Dispose()
+ foreach (var security in changes.RemovedSecurities)
{
- // Stop subscription on the data to release computational resources.
- _algorithm.DeregisterIndicator(_logRet);
+ if (!_securities.Contains(security))
+ {
+ continue;
+ }
+ // Stop updating the log return indicator to release resources.
+ algorithm.DeregisterIndicator(security.Get<LogReturn>(LogReturnKey));
+ _securities.Remove(security);
}
}
+
+ private decimal GetTVaR(Security security)
+ {
+ var logReturnMean = security.Get<SimpleMovingAverage>(LogReturnMeanKey);
+ var logReturnSd = security.Get<StandardDeviation>(LogReturnSdKey);
+ // Calculate TVaR from the log return mean and standard deviation.
+ var dailyTVaR = (double)logReturnMean.Current.Value + (double)logReturnSd.Current.Value * Math.Sqrt(_days) * Normal.PDF(0d, 1d, Normal.InvCDF(0d, 1d, _alpha)) / (1d - _alpha);
+ // Use the left side of the symmetric distribution.
+ return -Convert.ToDecimal(dailyTVaR);
+ }
}
from scipy.stats import norm
+
class FrameworkRiskManagementAlgorithm(QCAlgorithm):
+
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 9, 15)
self.set_cash(1000000)
-
# Add a universe of the most liquid stocks since their trend is more capital-supported.
- self.add_universe_selection(QC500UniverseSelectionModel())
- # Emit insights all for selected stocks, rebalancing every 2 weeks.
+ self.add_universe_selection(ETFConstituentsUniverseSelectionModel('SPY'))
+ # Emit insights for all selected stocks, rebalancing every two weeks.
self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(14)))
- # Equal weighting on each insight to dissipate capital risk evenly.
+ # Equal weighting on each insight is needed to dissipate capital risk evenly.
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
-
# Liquidate on extreme catastrophic events.
self.add_risk_management(TailValueAtRiskRiskManagementModel(0.05, 14))
+
class TailValueAtRiskRiskManagementModel(RiskManagementModel):
- _log_ret_by_symbol = {}
def __init__(self, alpha: float = 0.05, num_days: float = 7) -> None:
- # The alpha level on TVaR calculation.
- self.alpha = alpha
- # The number of days that the insight signal lasts for.
- self.days = num_days
+ # Set the alpha level for the TVaR calculation.
+ self._alpha = alpha
+ # Set the number of days the insight signal lasts.
+ self._days = num_days
+ self._securities = []
- # Adjust the portfolio targets and return them. If there are no changes, emit nothing.
- def manage_risk(self, algorithm: QCAlgorithm, targets: List[PortfolioTarget]) -> List[PortfolioTarget]:
+ def manage_risk(self, algorithm: QCAlgorithm, targets: List[IPortfolioTarget]) -> List[IPortfolioTarget]:
targets = []
- for kvp in algorithm.securities:
- security = kvp.value
+ for security in self._securities:
if not security.invested:
continue
-
pnl = security.holdings.unrealized_profit_percent
- symbol = security.symbol
- # If the %PnL is worse than the preset level TVaR, we liquidate it.
- if pnl < self.get_tvar(symbol):
+ # Liquidate when the unrealized loss is worse than the preset TVaR level.
+ if pnl < self._get_tvar(security):
# Cancel insights to avoid reordering afterward.
- algorithm.insights.cancel([symbol])
- # Liquidate.
- targets.append(PortfolioTarget(symbol, 0, tag="Liquidate due to TVaR"))
-
+ algorithm.insights.cancel([security])
+ targets.append(PortfolioTarget(security, 0, tag="Liquidate due to TVaR"))
return targets
- def get_tvar(self, symbol: Symbol) -> float:
- symbol_data = self._log_ret_by_symbol.get(symbol)
- if not symbol_data:
- return 0
-
- # TVaR = \mu + \sigma * \phi[\Phi^{-1}(p)] / (1 - p)
- # Scale up to the days of the signal. By stochastic calculus, we multiply by sqrt(days).
- daily_tvar = symbol_data.mean_log_ret + symbol_data.sd_log_ret * np.sqrt(self.days) * norm.pdf(norm.ppf(self.alpha)) / (1 - self.alpha)
- # We want the left side of the symmetric distribution.
- return -daily_tvar
+ def _get_tvar(self, security: Security) -> float:
+ # Calculate TVaR from the log return mean and standard deviation.
+ return -(
+ security.log_return_mean.current.value
+ + security.log_return_sd.current.value
+ * np.sqrt(self._days)
+ * norm.pdf(norm.ppf(self._alpha))
+ / (1 - self._alpha)
+ )
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
- for added in changes.added_securities:
- # Add SymbolData class to handle log returns.
- self._log_ret_by_symbol[added.symbol] = SymbolData(algorithm, added.symbol)
+ for security in changes.added_securities:
+ # Store the log return indicator and rolling window directly on the security.
+ security.log_ret = algorithm.logr(security, 1, Resolution.DAILY)
+ security.log_return_mean = IndicatorExtensions.sma(security.log_ret, 252)
+ security.log_return_sd = IndicatorExtensions.of(StandardDeviation(252), security.log_ret)
+ history = algorithm.history[TradeBar](security, 253, Resolution.DAILY)
+ for bar in history:
+ security.log_ret.update(bar.end_time, bar.close)
+ self._securities.append(security)
+ for security in changes.removed_securities:
+ if security not in self._securities:
+ continue
+ # Stop updating the log return indicator to release resources.
+ algorithm.deregister_indicator(security.log_ret)
+ self._securities.remove(security)
+
+
+
+ Example 3: Bracket Risk Model
+
+
+ The following algorithm implements a custom bracket risk management model that combines a trailing stop-loss with a take-profit target.
+ Positions are exited when unrealized profit exceeds a threshold or when the price falls by more than a specified percentage from the trailing high.
+ It is used alongside an XGBoost Alpha model that trades Equities near their earnings dates.
+
+
+ from sklearn.model_selection import RandomizedSearchCV, train_test_split
+from sklearn.preprocessing import MinMaxScaler
+import xgboost as xgb
- for removed in changes.removed_securities:
- # Stop subscription on the data to release computational resources.
- symbol_data = self._log_ret_by_symbol.pop(removed.symbol, None)
- if symbol_data:
- symbol_data.dispose()
+class ModulatedNadionReplicator(QCAlgorithm):
-class SymbolData:
- def __init__(self, algorithm: QCAlgorithm, symbol: Symbol) -> None:
- self.algorithm = algorithm
- self.symbol = symbol
+ def initialize(self):
+ self.set_start_date(2024, 9, 1)
+ self.set_end_date(2024, 12, 31)
+ self.set_cash(100_000)
+ self.settings.free_portfolio_value_percentage = 0.05
+ self.settings.seed_initial_prices = True
+ self._spy = self.add_equity("SPY", Resolution.HOUR)
- # Since the return is assumed log-normal, we use the log return indicator to calculate TVaR later.
- self.log_ret = LogReturn(1)
- # Register the indicator for automatic updating for daily log returns.
- algorithm.register_indicator(symbol, self.log_ret, Resolution.DAILY)
- # Set up a rolling window to save the log return for calculating the mean and SD for TVaR calculation.
- self.window = RollingWindow(252)
- # Add a handler to save the log return to the rolling window.
- self.log_ret.updated += lambda _, point: self.window.add(point.value)
- # Warm up the rolling window.
- history = algorithm.history[TradeBar](symbol, 253, Resolution.DAILY)
- for bar in history:
- self.log_ret.update(bar.end_time, bar.close)
+ # Create universe parameters.
+ self.universe_settings.resolution = Resolution.HOUR
+ self.universe_settings.asynchronous = True
+ date_rule = self.date_rules.month_start(self._spy)
+ self.universe_settings.schedule.on(date_rule)
+ self.add_universe_selection(EarningsVolumeUniverseSelectionModel(10))
- @property
- def is_ready(self) -> bool:
- return self.window.is_ready
+ # Add the other framework models.
+ self.add_alpha(XGBoostAlphaModel(self, date_rule, self._spy))
+ self.set_portfolio_construction(InsightWeightingPortfolioConstructionModel())
+ self.set_risk_management(BracketRiskModel(0.05, 0.15))
- @property
- def mean_log_ret(self) -> float:
- # Mean log return for TVaR calculation.
- return np.mean(list(self.window))
+ # Add a warm up so the algorithm has insights on deployment day.
+ self.set_warm_up(timedelta(45))
- @property
- def sd_log_ret(self) -> float:
- # SD of log return for TVaR calculation.
- return np.std(list(self.window), ddof=1)
- def dispose(self) -> None:
- # Stop subscription on the data to release computational resources.
- self.algorithm.deregister_indicator(self.log_ret)
+class EarningsVolumeUniverseSelectionModel(FundamentalUniverseSelectionModel):
+ # Selects symbols by liquidity and nearest earnings report date.
+ def __init__(self, universe_size=10):
+ self._universe_size = universe_size
+ super().__init__(self._select)
+
+ def _select(self, fundamental):
+ # Sort the top 30 by price and dollar volume.
+ liquid = sorted(
+ [f for f in fundamental if f.has_fundamental_data and 20 <= f.price <= 200 and f.dollar_volume > 5_000_000],
+ key=lambda f: f.dollar_volume
+ )[-30:]
+
+ # Select symbols with nearest earnings report dates.
+ selected = sorted(
+ [f for f in liquid if f.earning_reports.file_date],
+ key=lambda f: str(f.earning_reports.file_date)
+ )[:self._universe_size]
+
+ return [f.symbol for f in selected]
+
+
+class XGBoostAlphaModel(AlphaModel):
+
+ def __init__(self, algorithm, date_rule, spy):
+ self._algorithm = algorithm
+ self._universe = []
+ self._insights = []
+ self._feature_window = 24
+ self._history_bars = 48
+ self._rsi_period = 12
+ self._scaler = MinMaxScaler(feature_range=(-1, 1))
+ self._spy = spy
+
+ # Create rate-of-change indicator for SPY with specified window.
+ self._spy.rocp = algorithm.rocp(spy, self._feature_window)
+ self._spy.rocp.window.size = self._feature_window
+ algorithm.indicator_history(self._spy.rocp, spy, self._spy.rocp.period + self._spy.rocp.window.size)
+
+ algorithm.train(date_rule, algorithm.time_rules.at(8, 0), self._train_models)
+ algorithm.schedule.on(date_rule, algorithm.time_rules.after_market_open(self._spy, 30), self._create_insights)
+
+ def _create_insights(self):
+ self._insights.clear()
+
+ # Extract predictions from all trained models.
+ for security in self._universe:
+ # Skip prediction if model not yet trained.
+ if not (security.model and security.rocp.window.is_ready and self._spy.rocp.window.is_ready):
+ continue
+ features, _ = self._build_features(security)
+ # Get prediction from the trained model.
+ magnitude = security.model.predict(features)[-1]
+ # Determine signal direction based on prediction magnitude.
+ direction = InsightDirection.FLAT
+ if magnitude > 0.05:
+ direction = InsightDirection.UP
+ elif magnitude < -0.05:
+ direction = InsightDirection.DOWN
+ # Generate price insights with computed weights and directions.
+ self._insights.append(Insight.price(security, timedelta(1), direction, weight=0.3 * abs(magnitude)))
+
+ def update(self, algorithm, data):
+ if algorithm.is_warming_up:
+ return []
+
+ insights = self._insights.copy()
+ self._insights.clear()
+
+ return insights
+
+ def on_securities_changed(self, algorithm, changes):
+ for security in changes.added_securities:
+ if security == self._spy or security in self._universe:
+ continue
+ # Add security and register indicators to universe.
+ self._universe.append(security)
+ security.model = None
+ security.rocp = algorithm.rocp(security, self._feature_window)
+ security.rsi = algorithm.rsi(security, self._rsi_period, MovingAverageType.SIMPLE)
+ security.atr = algorithm.atr(security, self._feature_window, MovingAverageType.SIMPLE)
+ # Configure window sizes and populate history for indicator and window.
+ bars = algorithm.history[TradeBar](security, self._feature_window * 2)
+ for indicator in [security.rocp, security.rsi, security.atr]:
+ indicator.window.size = self._feature_window
+ for bar in bars:
+ indicator.update(bar)
+
+ for security in changes.removed_securities:
+ if security not in self._universe:
+ continue
+ # Remove security and deregister indicators from universe.
+ self._universe.remove(security)
+ for indicator in [security.rocp, security.rsi, security.atr]:
+ algorithm.deregister_indicator(indicator)
+
+ def _build_features(self, security):
+ # Compute momentum and volatility indicators and normalize all features to consistent range.
+ scaled = self._scaler.fit_transform(np.hstack(
+ [self._get_indicator_history(self._spy.rocp)]
+ + [self._get_indicator_history(indicator) for indicator in [security.rocp, security.rsi, security.atr]]
+ ))
+
+ return scaled[:, :3], scaled[:, [3]]
+
+ def _get_indicator_history(self, indicator):
+ return np.array([x.value for x in indicator.window])[::-1].reshape(-1, 1)
+
+ def _train_models(self):
+ # Iterate through all security in the universe for model training.
+ for security in self._universe:
+ if not (security.rocp.window.is_ready and self._spy.rocp.window.is_ready):
+ continue
+
+ features, scaled_rocp = self._build_features(security)
+ target = scaled_rocp.ravel()
+
+ # Prepare training and validation splits from the feature matrix.
+ x_train, x_valid, y_train, y_valid = train_test_split(
+ features, target, test_size=0.35, random_state=42,
+ )
+
+ # Define hyperparameter grid for randomized search optimization.
+ parameters = {
+ 'n_estimators': [100, 200, 300, 400],
+ 'learning_rate': [0.001, 0.005, 0.01, 0.05],
+ 'max_depth': [8, 10, 12, 15],
+ 'gamma': [0.001, 0.005, 0.01, 0.02],
+ 'random_state': [42]
+ }
+ eval_set = [(x_train, y_train), (x_valid, y_valid)]
+ base_model = xgb.XGBRegressor(objective="reg:squarederror", verbosity=0)
+ model = RandomizedSearchCV(
+ estimator=base_model, param_distributions=parameters, n_iter=5, scoring="neg_mean_squared_error", cv=4, verbose=0,
+ )
+
+ # Execute randomized search for optimal model hyperparameters.
+ model.fit(x_train, y_train, eval_set=eval_set, verbose=False)
+ security.model = model
+
+
+class BracketRiskModel(RiskManagementModel):
+
+ def __init__(self, drawdown_pct, profit_pct):
+ # Store drawdown and profit thresholds as percentage values.
+ self._drawdown_pct = -abs(drawdown_pct)
+ self._profit_pct = abs(profit_pct)
+
+ def manage_risk(self, algorithm, targets):
+ # Build list of risk-adjusted targets.
+ adjusted_targets = []
+
+ # Iterate through all securities to evaluate positions.
+ for symbol, security in algorithm.securities.items():
+ # Reset trailing high for non-invested securities.
+ if not security.invested:
+ security.trailing_high = None
+ # Take profit when unrealized gains exceed the threshold.
+ elif security.holdings.unrealized_profit_percent > self._profit_pct:
+ adjusted_targets.append(PortfolioTarget(symbol, 0))
+ algorithm.insights.cancel([symbol])
+ # Initialize trailing high from the entry price.
+ elif security.trailing_high is None:
+ security.trailing_high = security.holdings.average_price
+ # Update trailing high if a new high is reached.
+ elif security.trailing_high < security.high:
+ security.trailing_high = security.high
+ # Exit position when drawdown from trailing high exceeds limit.
+ elif (security.low / security.trailing_high) - 1 < self._drawdown_pct:
+ adjusted_targets.append(PortfolioTarget(symbol, 0))
+ algorithm.insights.cancel([symbol])
+
+ return adjusted_targets
+
+