Compare commits

...

219 Commits
16535 ... 17023

Author SHA1 Message Date
Martin-Molinero
57adac59ee Update IB to latest 1034 (#8636) 2025-03-24 13:23:32 -03:00
Martin-Molinero
d57f75ade2 Fix for division by zero in option assigment check (#8644)
- Fix for division by zero in option assigment check. Adding regression
  test reproducing issue. Will now rely on normalized path in universe
  selection to clear the cache
2025-03-21 18:18:48 -03:00
Martin-Molinero
bbb72b771c Minor fix for host culture on regression tests (#8645) 2025-03-21 17:59:13 -03:00
JosueNina
1b4613bc75 Support conversion of IndicatorBase<BaseData> (#8635)
* Support registering indicators of type IndicatorBase<BaseData>

* Add IndicatorBase<BaseData> scenario for all the usages of ConvertPythonIndicator

* Add all scenarios in the test case
2025-03-20 15:31:12 -03:00
JosueNina
e994562d60 Add unit test to CommonIndicatorTest (#8628)
* Initial solution

* Update unit test

* Explicit conversion if T is IndicatorDataPoint

* Solve review comments

* Add override tests for Beta and Alpha

* Refactor and update unit test suite

* Create unit test for OptionIndicators

* Resolve review comments

* Resolve new review comments

* Add a new default selector
2025-03-20 10:16:00 -03:00
Roman Yavnikov
057f0b4d9e Feature: implement MarketOnCloseOrderTestParameters (#8625)
* feat: new MarketOnCloseOrderTestParameters

* feat: support new OrderType in CharlesSchwabBrokerageModel
2025-03-14 17:46:50 -03:00
Martin-Molinero
e6f2776fcf Update readme.md 2025-03-13 12:09:57 -03:00
Roman Yavnikov
87a65451ea Feature: Universe Data Downloader (#8612)
* feat: parsing of universe file path for different security types

* fix: market position in parsing of universe file
refactor: add example of universes file path in xml description method

* test:feat: parsing of universe path

* rename: return variable in ParseUniversePath

* feat: extension to create history request internally

* feat: entity  DataUniverseDownloaderGetParameters

* config: downloaderDataProvider project

* feat: create DataUniverseDownloadConfig in download project

* feat: run universe downloader in DownloaderProvider

* test:fix: missing using
test:remove: parameter ctor of DataDownloadConfig

* refactor: run Universe downloader in Main

* feat: GetUniverseFileName by processingDate

* refactor: CreateDataUniverseDownloaderGetParameters with using Start and EndDate
refactor: exception message in DataUniverseDownloadConfig

* feat: new out argument in TryParsePath's LeanData

* feat: RunUniverseDownloader in DownloadDataProvider

* feat: DerivativeUniverseData to write csv file
feat: extension to download universe data with different parameters

* remove: log warn which path when get universe file path

* refactor: DataUniverseDownloaderGetParameters
feat: run Download Universes file in DownloaderDataProvider internally

* refactor: overload TryParsePath only with 4 parameters

* remove: editconfig file in DownloaderDataProvider

* remove: validation on null parameters

* rename: typo DateType to DataType

* refactor: use endDate in ctor DataUniverseDownloaderGetParameters
refactor: use UnderlyingSymbol from base class Symbol property
remove: CreateDataUniverseDownloaderGetParameters()
refactor: put LoadSymbol in base class
clean/remove: DataUniverseDownloadConfig

* refactor: use Time.EachTradeableDay in CreateDataDownloaderGetParameters
remove: CheckMarketOpenStatus

* fix: RunUniverseDownloader with EndUtc in DownloaderDataProvider

* refactor: GetUniverseFullFilePath

* remove:  validate historyData like Any

* fix: use date from parsing path in DownloaderDataProvider

* feat: download QuoteBar for Universe file
feat: handle QuoteBar in DerivativeUniverseData
refactor: filter option in final dictionary

* revert: CreateHistoryRequest() in DownloaderExtensions

* feat: use optional parameter SecurityExchangeHours in DataUniverseDownloaderGetParameters
refactor: DataUniverseDownloaderGetParameters
refactor: use Log.Debug instead Log.Trace to prevent spamming

* fix: ordering of download universe data
revert: parameter ctor in DataDownloadConfig
revert:test: use parameter ctor instead of Config.Set

* clean: extra `usings`

* fix: Get DataType in DataDownloadConfig
feat: new ctor in BaseDataDownloadConfig
2025-03-12 19:38:18 -03:00
JosueNina
d00ef1c181 Use a fixed number of periods instead of WarmUpPeriod for the second indicator (#8624) 2025-03-12 17:41:08 -03:00
JosueNina
2e1f28d20d Fix IndicatorHistory for options indicators in Python (#8621)
* Fix IndicatorHistory api for options indicators

Fix for indicators based on OptionIndicatorBase to be able to use IndicatorHistory api. They require proper conversion of indicators from PyObjects

* Fix WarmupIndicator to support multi symbol indicators in Python

* Minor fix for WarmUpIndicator api

* Refactored switch statements for indicator conversion

* Solve comments review

* Refactored WarmUpIndicator to remove duplicated code

* Resolve review comments

---------

Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
2025-03-12 16:10:25 -03:00
Alexandre Catarino
d68a41ba73 Allow Receiving Broadcast from Source Project (#8622)
* Allow Receiving Broadcast from Source Project

* empty
2025-03-11 16:58:17 -03:00
JosueNina
09ca345ae8 Custom data type universe - python support (#8618)
* Cache registered custom python security and universe data types

Use this cache to get the correct config for history requests since pythonnet will always pass PythonData and we lose reference to the actual Python type

* Use local repo data for unit tests

* Move unit tests to algorithm history tests

* Use UniverseManager instead of CacheCustomPythonDataType

* Add regression algorithms

* Update regression algorithms to solve issues

* Update regression test and History

* Updated source path to avoid issues with linux

---------

Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
2025-03-10 17:33:17 -03:00
Alexandre Catarino
49265bd773 Adds BroadcastCommand Method (#8617)
* Adds BroadcastCommand Method

Send a command to all live algorithms.

* Addresses Peer-Review

* Minor tweaks

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-03-07 17:48:10 -03:00
Martin-Molinero
07003af6d5 Minor Update IB Order Properties (#8619)
- FA EqualQuantity was renamed to Equal, update docs
- Add remarks warning on exclusiveness of FaProfile, FaGroup and Account
2025-03-07 17:36:03 -03:00
JosueNina
5f8d76f6dd Update Stochastic period (#8613)
* Update Stochastic period

* Update regression algorithms

* Resolve review comments

* Fix Regression algorithms
2025-03-07 12:09:33 -03:00
Martin-Molinero
bcc53eff3b Add minor extension methods for value tasks (#8614) 2025-03-06 17:29:25 -03:00
Ricardo Andrés Marino Rojas
bca9ada795 Replace C2 symbol for C2 Exchange symbol (#8604)
* Initial draft of the solution

* Remove old format

* Address requested changes

* Add Index option test case

* nit changes

* Address Martin reviews, improve unit tests and solve 8577

* Add unit tests

* Nit change

* Address requested changes

* Address Martin reviews

* Nit changes and more unit tests

* Nit change

* Address requested changes

* Address requested changes
2025-03-06 13:21:31 -03:00
Martin-Molinero
5cba110b64 Add missing IB dependencies (#8615) 2025-03-05 12:32:33 -03:00
JosueNina
88b32b8352 Python Support for CompositeIndicator (#8598)
* Initial solution

* Add python support for CompositeIndicator

* Add unit tests and update CompositeIndicator

* Add new test case

* Update TryConvertToIndicator logic

* Solve review comments

* Resolve review comments

* Remove unnessary case

* Use GetIndicatorAsManagedObject instead of ConvertToIndicator

* Add regression tests
2025-03-04 15:25:15 -03:00
Martin-Molinero
fef5c8e9c8 Update readme.md 2025-03-04 11:50:13 -03:00
Jhonathan Abreu
867b7e8eb6 Upgrade IB gateway version to 30.10 (#8586)
* Upgrade IB gateway version to 3010

* Update ib gateway version in config file

* Remove ib-version config

Let the brokerage detect or set the correct ib gateway version
2025-03-03 13:17:23 -03:00
Zekun Wang
f9d84a6893 Remove outdated comments (#8601)
* remove oudated comments

* remove outdated comments

---------

Co-authored-by: Zekun Wang <zekun.wang@uwaterloo.ca>
2025-02-21 10:55:54 -03:00
Ricardo Andrés Marino Rojas
bd144e021d Add 2025 & 2024 holidays to MHDB Index entries (#8599) 2025-02-21 10:53:18 -03:00
JosueNina
1a852d2d45 Add new indexes, including market hours - part 4 (#8578)
* Add new indexes, including market hours - part 4

* Resolve review comments

* Add an entry to SPDB for ASX

* Add new indexes and update the old ones

* Add entries to SPDB
2025-02-19 18:50:38 -03:00
Ricardo Andrés Marino Rojas
99dc63a08d Remove trailing commas from MHDB (#8597) 2025-02-19 17:52:38 -03:00
Martin-Molinero
f59fedc042 Add backtest summary (#8593) 2025-02-19 11:32:18 -03:00
JosueNina
5596295774 Set DeploymentTarget to LocalPlatform (#8588) 2025-02-14 17:27:19 -03:00
Martin-Molinero
fabf1191b7 Improve live trading streaming packets (#8584)
* Improve live trading streaming packets

* Further improvements

* Add test for default empty holding

- Improve deserialization
2025-02-13 18:40:55 -03:00
Ricardo Andrés Marino Rojas
9be02d7fa5 Add bank holidays for CME Futures MHDB (#8539)
* Add bank holidays

* Add missing holidays to MHDB

* Add 2025 new year's eve bank holiday

* Add Columbus day and veterans day to bank holidays

* Add missing bank holidays entry

* Modify FuturesExpiryFunctions

* Add missing change

* Remove empty bankHolidays lists from MHDB

* Address review

* Add tests

* Address review

* Add bank holidays from 2009-2024

* Fix unit and regression tests

* Review bank holidays

* Fix tests

* MHDB tweaks

* Remove Bank holidays from CNH, MNH and MIR

* Add setting for bank holidays disabled by default

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-02-06 17:50:10 -03:00
JosueNina
55c995e13f Add new indexes, including market hours - part 3 (#8576)
* Add new indexes, including market hours - part 3

* Fix market hours
2025-02-06 13:02:05 -03:00
JosueNina
1d169a19ce Add new indexes, including market hours (#8573) 2025-02-06 11:08:53 -03:00
JosueNina
956ffdfa9c Add new indexes, including market hours (#8571) 2025-02-05 12:32:13 -03:00
Jhonathan Abreu
0b6255c1fc Update GitHub issue template to match new formats (#8572)
* Update GH issue template to match new formats

* Disable github blank issue template selector
2025-02-04 18:09:25 -03:00
JosueNina
6415de83cf Update exchange for new indexes (#8569)
* Update markets and market hours for new indexes

* Update market hours and IndexSymbols
2025-02-04 16:47:32 -04:00
Martin-Molinero
e38f3f3aaf Update RecyclableMemoryStream (#8574) 2025-02-04 17:11:46 -03:00
Jhonathan Abreu
40e887a106 Unseal greeks ComputeIndicator method (#8570) 2025-02-03 11:16:34 -03:00
Jhonathan Abreu
8149c291fc Dynamic market hours for time and date rules (#8541)
* Add unit test reproducing the bug

* Improve unit test

* Apply market hours database updates to instance

Make sure entries are updated instead of overridden so that consumers holding the mhdb can pick up the changes

* Improved unit tests

* Update data folder MHDB entries instead of overriding instance

* Optionally reset custom mhdb entries on reset

* Simplify mhdb reset in live trading

Cleanup and minor fixes

* Ensure symbol properties database updates are picked up by consumers

Update SPDB entries instead of overriding them, just like for the MHDB so that consumers pick up updates after refresh

* Fix for symbol properties update thread safety

* Minor improvements and cleanup

* Mhdb and spdb update logic simplification

* Move "force exchange always open" logic to mhdb

* Simplify symbol properties holder and updates

* Refactor security databases to use a common base class

Introduce BaseSecurityDatabase<T, TEntry> to encapsulate common functionality for MarketHoursDatabase and SymbolPropertiesDatabase.

* Cleanup
2025-01-31 15:00:14 -04:00
Jhonathan Abreu
de9f9bf309 Fix options indicators data synchronization (#8564)
* Add DualSymbolIndicator unit tests

* Introduce MultiSymbolIndicator for indicators working on multiple symbols

Use the new class as base for DualSymbolIndicator and OptionIndicatorBase.
The OptionIndicatorBase can now detect when ready even if underlying and options market close is different when resolution is daily.

* Accept any BaseData for options indicators

* Improve indicator conversion from python on registration

Also minor fixes

* Cleanup and simplification

* Fix ImpliedVolatility IsReady flag

* Update regression algorithm history count

AutomaticIndicatorWarmupOptionIndicatorsMirrorContractsRegressionAlgorithm history count decreased because options indicators period is now 1 instead of 2

* Address peer review
2025-01-31 14:22:06 -04:00
JosueNina
077b6e41d8 Updating Orders should fail if it causes insufficient margin (#8553)
* Initial solution

* Update regression test

* Update assertions

* Resolve PR comments

* Add more order types to regression test

* Update regression algorithm name

* Update old regression algorithm

* Refactor validation to check buying power only for non-ComboLeg update orders

* Update ValidateSufficientBuyingPowerForOrders

* Update regression algorithm

* Resolve review comments

* Use try out pattern
2025-01-31 11:29:30 -03:00
Martin-Molinero
37d0c42149 Minor improvements to compression (#8555) 2025-01-31 11:29:11 -03:00
Roman Yavnikov
ac1365cd7c feat: support new order types in CharlesSchwabBrokerageModel (#8561) 2025-01-29 15:40:26 +02:00
JosueNina
c3530a6a7f Update SPDB - Bybit (#8563) 2025-01-29 10:15:30 -03:00
Ricardo Andrés Marino Rojas
7318c6fc7c Add ICE and NYSE 2025, 2026 and 2027 holidays (#8557)
* Add ICE and NYSE 2025, 2026 and 2027 holidays

* Reduce common holidays
2025-01-28 16:21:32 -03:00
Ashutosh
2e0c3a03a5 Add index data part 1 (#8549)
* Update MHDB for new indexes - part 1

* Central Time correction

* Adding DJX
2025-01-28 15:12:13 -03:00
Ricardo Andrés Marino Rojas
824a754f81 Add CFE, SGX and INDIA 2025 Holidays to MHDB (#8558) 2025-01-28 15:10:47 -03:00
Alexandre Catarino
1000669975 Adds Collective2 Payload To Logs With Debugging Enabled (#8559) 2025-01-28 15:10:39 -03:00
Jhonathan Abreu
24a1fbba60 Clone configuration on re-subscription (#8560)
When re-subscribing a request after a fill forward resolution change, clone Config to avoid memory access race conditions when emitting new tradable date events
2025-01-28 15:09:40 -03:00
Jhonathan Abreu
25d53fe6ff Update default CFE mhdb entry (#8562)
Update segments to reflect regular and extended hours
2025-01-28 15:09:21 -03:00
JosueNina
cad5f20a3d Refactor SetHoldings to return a List<OrderTicket> (#8550)
* Refactor SetHoldings to return a List<OrderTicket>

* Add expectedQuantities to the testCases

* Update regression tests

* Update name of regressionAlgorithm

* Address review comments

* Update unit test
2025-01-23 18:44:29 -04:00
Jhonathan Abreu
c5c56bf98e Fix symbol changed events emission time (#8552)
* Fix symbol changed events emission time

Ensure the symbol changed events are emitted after the securities are processes by the main loop in the AlgorithmManager. This way the algorithm has access to the new symbol security since it would be added by the securities processing logic.

Also, allow all securities to be properly updated, including prices and cash, before emitting the event, so that the any logic (like placing orders) done by the algorithm on the handler has the correct data.

* Minor fix

* Minor change

* Minor change
2025-01-23 18:29:28 -04:00
JosueNina
9b35411f45 Refactor liquidation logic (#8544)
* Create regression tests and refactor liquidation logic

- Implemented regression tests for order creation and liquidation
  scenarios
- Removed LiquidateExistingHoldings method
- Replaced LiquidateExistingHoldings with the general Liquidate method

* Addressed review comments

* Addressed new comments review

* Update default value for 'tag'

* Update ExpectedStatistics

* Identify and liquidate portfolio symbols not included in targets

* Create a new regression test

* Fix minor comments

* Move regression tests to the correct folder
2025-01-22 12:53:48 -03:00
Martin-Molinero
2fe7f5b457 RUT index options support (#8542) 2025-01-22 11:56:42 -03:00
Martin-Molinero
64f848a7b1 Setup net9 C# research (#8548) 2025-01-22 11:56:02 -03:00
Roman Yavnikov
0937d08aa8 fix: missed assign order status in PlaceOrderWaitForStatus (#8546) 2025-01-21 15:59:52 -03:00
Roman Yavnikov
8330dd939e Test:Feat: LongFromZeroUpdateAndCancel (#8545) 2025-01-21 17:18:03 +02:00
JosueNina
1ef66a1083 Fix Retrieval of Historical Data for Equities with Different Resolutions (#8538)
* Refactor GetMatchingSubscriptions:

- Fixed retrieval of minute-resolution quote data for hour-resolution
  equity
- Ensured correct retrieval of data regardless of equity resolution
- Created a unit test to verify functionality

* Update unit test and create test cases

* Add new unit test

* Addressed review comments
2025-01-17 10:18:15 -03:00
Jhonathan Abreu
0fccf6017d Expand index market map (#8540)
* Expand index market map

* Cleanup
2025-01-16 10:49:30 -03:00
Jhonathan Abreu
41f9d1bd3a Support Collective2 white-label API (#8536)
* Support Collective2 white-labe api usage

* Make Collective2SignalExport Destination public and assignable

* Minor comment change
2025-01-15 16:49:55 -04:00
Martin-Molinero
c35d6ee194 Fix HSI future expiration function (#8534)
* Fix HSI future expiration function

- Fix HSI futures expiration function. Adding unit tests reproducing
  issue

* Minor update to sample test data
2025-01-15 15:04:15 -03:00
Ashutosh
1cb8fcf2d9 Update mhdb to add holidays for osaka exchange (#8533)
* Update mhdb to add holidays for osaka exchange

* Minor MHDB cleanup

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-01-15 11:29:37 -03:00
Jhonathan Abreu
58b7a9d22a Add FTSE Russell Exchange support (#8531)
* Add FTSE Russell Exchange support

* Cleanup
2025-01-15 10:36:20 -03:00
Jhonathan Abreu
2d4ca75670 Add Russell 2000 (RUT) market hours and symbol properties entries (#8530) 2025-01-14 17:23:08 -04:00
Martin-Molinero
cda769df74 Add Nikkei 225 index support (#8529)
- Add Osaka exchange for nikkei index. Adding regression test
- Improve default market resolution
2025-01-14 17:08:36 -03:00
JosueNina
5accfd6be3 Update secondsTimeStep value (#8528) 2025-01-14 15:17:55 -03:00
Martin-Molinero
265fd8b3b9 Update readme.md 2025-01-14 10:36:11 -03:00
JosueNina
d633fed3ff Handle zero price and target quantity case - Collective2 (#8525)
* Skip zero price and target quantity case

* Addressed PR comments

* Addressed new PR comments
2025-01-13 20:48:20 -03:00
JosueNina
f689826051 Added constructor to initialize USResident flag (#8526) 2025-01-13 20:47:37 -03:00
JosueNina
af7a2cfc85 Update installation instructions (#8524)
* Update readme.md to mention .NET 9 instead of .NET 6

* Update readme.md with new versions of python, pandas and wrapt

* Update readme.md for vscode and vs
2025-01-13 15:43:45 -03:00
Martin-Molinero
6982f6713b Fix index option cash profit (#8520)
- Fix so that option cash settlement impacts profit records. Updating
  existing and adding new tests
2025-01-13 12:52:12 -03:00
Ricardo Andrés Marino Rojas
50f887ca64 Fix delisting time handling in SubscriptionDataReader (#8470)
The delisting time is handled by the DateChangeTimeKeeper now, so there is no need for the SubscriptionDataReader to do any special logic for it.
This was preventing the new tradable date events to be emitted after the delisting date in some cases, like when the day after delisting is not tradable

Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
2025-01-13 10:22:14 -04:00
JosueNina
f08eda3bac Update SPDB with Bitfinex, Kraken, Binance, BinaceUS (#8516)
* Update SPDB with Bitfinex, Kraken, Binance, BinaceUS

* Update unit test

* Added TestCase for CNHT and USD

* Fixed bug in pair comparison logic, corrected concatenation approach

* Add unit test for currency pair match

* Added test cases for currency pair comparison

* Addressed review comments
2025-01-10 18:57:37 -03:00
Martin-Molinero
8ad1016710 Remove index resolution limitations (#8519)
- Remove index resolution limitations being imposed
2025-01-10 14:59:19 -03:00
Jhonathan Abreu
8937995ee4 Add Martin Luther King's day 2025 holiday to CME futures entries (#8515)
* Add Martin Luther King'day holiday to CME futures entries

Add unit test for MCL futures expiry function, first contract of 2025 expires on Jan17 but was returning the 20th

* Add holiday to equity and index

And by extension to options and index options

* Add holiday to other entries
2025-01-09 17:36:06 -04:00
JosueNina
ca7f7710e7 Update SPDB with Bybit and CoinBase (#8512)
* Update SPDB with Bybit

* Update SPDB with Coinbase

* Merge completed successfully without deletion

* Removed expiring crypto futures
2025-01-09 13:04:16 -03:00
Martin-Molinero
0b1b72e921 Fix for multiple market closes in date (#8509)
- Fixes related to support assets with multiple daily market closes.
  Adding unit and regression tests
2025-01-09 12:56:37 -03:00
JosueNina
c44819617f Update IdentityDataConsolidator to track last processed time (#8510) 2025-01-09 09:52:52 -03:00
JosueNina
3569a1f8d0 Collective2 - No index option (#8494)
* Inicial solution

* Use InitialMargin instead of MaintenanceMargin

* Addressed review comments

* Update unit test

* Refactor GenerateOptionTicker method to handle IndexOption

* Addressed PR comments

* Update unit test
2025-01-08 16:58:31 -03:00
oussamanahdi
d71dd86ff5 Updates LEAN readme with LEAN Architecture diagram (#8507)
* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md
2025-01-07 23:54:08 -03:00
JosueNina
96410b57a0 Add 1/9/2025 holiday to market-hours (#8508)
* Add 1/9/2025 holiday to market-hours

* Patched holidays in MarketHours

* Minor fix

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-01-07 23:52:25 -03:00
Martin-Molinero
f17726b890 Fix HSI future expirations (#8505) 2025-01-06 17:20:43 -03:00
Jhonathan Abreu
7ee297ab77 Add BTIC on cryptocurrencies futures back (#8503)
* Add BTIC on cryptocurrencies futures back

Add MIB (BTIC on micro bitcoin futures) and BRM (BTIC on micro ether futures) back

* Minor unit tests fix
2025-01-06 15:01:30 -04:00
Martin-Molinero
94fd3c8f64 Update HSI future margin (#8504) 2025-01-06 12:49:43 -03:00
Ashutosh
50a8de5f67 Update mhdb file for HKFE entries (#8501) 2025-01-06 11:07:59 -03:00
Martin-Molinero
af2043d7d3 Add hang seng future and index support (#8499) 2025-01-03 20:51:37 -03:00
Jhonathan Abreu
57ce6958dd Skip subscription to selected securities when no tradable dates (#8495)
* Skip "no tradable dates" log for options added on non-tradable dates

* Skip subscription to selected securities when no tradable dates

Skip selected securities subscriptions when there are no tradable dates available from selection time till end date

* Minor comment

* Remove "no tradable days" error log
2025-01-03 20:47:52 -03:00
Martin-Molinero
75d8e710d1 Add security Set (#8491) 2025-01-02 17:31:23 -03:00
Ricardo Andrés Marino Rojas
f75ea380e7 Add missing entries and clean MHDB (#8489)
* Move good friday to market entries and fix soft futures

* Keep holidays list order

* Nit change
2025-01-02 10:46:13 -03:00
JosueNina
f3ea223f2a Refactor Correlation and beta indicators (#8485)
* WIP: Refactor Correlation Indicator

* Simplified comparison logic and improved abstraction

* Refactor Correlation and Beta indicators

- Created a base class to handle indicators with dual-symbol
  functionality.
- Refactored the Beta and Correlation indicators to inherit from the new
  base class.
- Updated unit tests.
- Added a new regression test to validate the latest computed value.

* Addressed review comments

* Update regression test

* Add new unit test to CommonIndicatorTests

* Addressed new review comments
2025-01-02 10:42:01 -03:00
Ricardo Andrés Marino Rojas
fb49f5da70 Update CME Future entries MHDB (#8488)
* First potential update

* Add 2025 holidays, early closes and late opens

* Review and improve changes

* add missing entries

* Nit change

* Nit change
2024-12-30 20:28:04 -03:00
Martin-Molinero
0cda5c7f0d Improve brokerage WS default rate limits (#8486)
- Improve brokerage WS default reconnection rate limits
- Minor cleanup in WebSocketClientWrapper
2024-12-27 12:55:21 -03:00
Roman Yavnikov
9175b862d0 Feature: Validate FillPrice and FillQuantity in class BrokerageTest (#8483)
* test:feat: validate FillPrice and FillQuantity in Base Brokerage Test

* test:refactor: use Exception instead of Log
2024-12-26 18:44:24 -03:00
Roman Yavnikov
eca4f5b7f2 feat: init Config in BrokerageDataDownloader (#8482) 2024-12-26 12:57:27 -03:00
Martin-Molinero
2bdddc94b4 Update QuantConnect.csproj 2024-12-23 19:47:13 -03:00
Ricardo Andrés Marino Rojas
12930c444b Fix bug in Index security (#8472)
* Add unit test

* First potential solution

* Add regression tests

* Nit change

* Address requested changes

* Nit change

* Nit change

* Improve implementation

* Fix bugs

* Address requested changes
2024-12-23 16:32:25 -03:00
Derek Melchin
2ec979940c Update Beta.cs (#8478)
Update the docs to explain how the indicator handles missing data.
2024-12-23 16:10:11 -03:00
JosueNina
edd1aea8b0 Implement ZigZag (ZZ) indicator (#8454)
* Implement ZigZag Indicator

* Create Unit Test for ZigZag Indicator

* Update QCAlgorithm with ZigZag Indicator

* Resolved review comments

* Refactor ZigZag Indicator

- Refactored logic to streamline pivot updates and condition checks.
- Exposed PivotType enum to track pivot direction (High/Low).
- Updated CSV processing to reflect pivot type (High/Low).

* Refactor UpdatePivot logic
2024-12-23 13:19:39 -03:00
JosueNina
be4a34c7e4 Implement SqueezeMomentum (SM) indicator (#8462)
* Implement Squeeze Momentum Indicator

* Create unit test for SqueezeMomentum Indicator

* Update QCAlgorithm with SqueezeMomentum indicator

* Resolved review comments

* Switched to using Keltner indicator instead of manual calculation

* Refactor Squeeze Momentum indicator

- Make the Bollinger Bands and Keltner Channels indicators public.
- In IndicatorBase -> Update, if T is IndicatorDataPoint, then create a new
  IndicatorDataPoint.

* Fix issue with regression tests

* Fix unit test
2024-12-20 18:22:32 -03:00
JosueNina
3b559a5f3f Fix bug in beta value computation (#8466)
* Fix bug in beta calculation

- Beta is fill-forwarded
- A correct pair considered when they have different symbols and the
  same date
- Processing occurs when there are at least period+1 correct pairs

* Address review comments

* Add time zone handling and resolution-based truncation

* Fix regression test for Beta indicator

* Handle resolution for beta indicator

- Remove effectiveResolution and Beta constructor parameter for
  resolution.
- Streamlined resolution handling logic for Beta indicator.
- Fixed issues with regression test for Beta.

* Fix issue with period and WarmUpPeriod

* Update unit tests for Alpha indicator

* Fixing minor issues

* Add a variable to track if the previous symbol is the target

* Add regression test for Beta calculation between BTCUSD and SPY

* Add an extra period if the TZ are different
2024-12-20 18:22:04 -03:00
Martin-Molinero
d4fd936772 Update pythonnet to net9 (#8475) 2024-12-20 18:21:44 -03:00
Martin-Molinero
a0328426d9 Update readme.md 2024-12-19 18:15:57 -03:00
Martin-Molinero
890a19c871 Update readme.md 2024-12-19 16:30:13 -03:00
Martin-Molinero
5359561b9d Dotnet 9 (#8459)
* Dotnet 9

* Remove C# kernel
2024-12-19 14:01:26 -03:00
Jhonathan Abreu
a8592e08b5 Greeks calculation on expiration date (#8465)
* Add helper method to calculate options expiration date time

This allows to compute accurate time till expiry for greek indicators to be able to calculate on the actual expiration date before market close

* Update tolerance in greek indicators tests

* Minor fix

* Modify helper method to calculate settlement time instead of expiration time

* Cache option expiration date time

* Minor changes

* Minor changes
2024-12-13 18:23:31 -04:00
Ricardo Andrés Marino Rojas
fcb4ce637d Reduce unrequired live logs for derivatives chains (#8458)
* First draft of the solution

* Address requests

* Reduce more enrequired logs
2024-12-12 15:49:38 -04:00
Jhonathan Abreu
ec428c5f6c Daily options contracts valid open interest values (#8450)
* Fix for daily options open interest data to be added to contracts

* Cleanup

* Update regression algorithms stats

* Minor fix and cleanup

* Minor fix

* Minor fix

* Update regression algorithms data point count

* Address peer review
2024-12-12 14:50:59 -03:00
Ricardo Andrés Marino Rojas
2a62f16833 Make SignalExportManager skip non-tradeable securities (#8453)
* First approach

* Fix bug

* Address requests

* Address requests
2024-12-11 20:01:38 -03:00
Roman Yavnikov
f1c50e41a5 Feature: support trading IndexOption by TradeStation (#8456)
* feat: support IndexOption in TSBrokerageModel

* feat: add IndexOptionFee in TSFeeModel
2024-12-11 20:00:52 -03:00
Nikolay Baraboshkin
7445f7ec5a Improve performance of ConsolidatorScanPriority comparison (#8452)
* Improve the performance of ConsolidatorScanPriority comparison in SubscriptionManager

* address review comments
2024-12-11 19:59:33 -03:00
Martin-Molinero
8febb9ac45 Revert net version target (#8457) 2024-12-10 18:49:14 -03:00
Martin-Molinero
463044b64a Foundation update (#8455) 2024-12-10 18:07:26 -03:00
Louis Szeto
9865ce9815 Add example on volume share slippage model (#8437)
* add csharp example

* add python example

* regression

* add pythom implementation as example model

* peer review

* dependencies

* fix regression test
2024-12-09 15:37:35 -03:00
Ricardo Andrés Marino Rojas
81d7774c80 Fix bug when consolidating hourly bars into daily ones (#8442)
* First draft of the solution

* Add regression tests

* Improve solution and add unit test

* Address suggestions

* Improve unit tests

* Nit changes

* Fix regression algorithms
2024-12-06 14:42:40 -05:00
Nikolay Baraboshkin
22e04913a5 Improve the performance of RollingWindow.GetEnumerator (#8444)
* improve the performance of RollingWindow.GetEnumerator

Closes #8443

* address review comments
2024-12-05 17:32:02 -03:00
JosueNina
8e5893b708 Implement Hurst Exponent (HE) indicator (#8434)
* Implement Hurst Exponent indicator and unit test

- Implemented Hurst Exponent indicator class
- Created unit tests to validate indicator functionality
- Added helper methods for standard deviation and regression line slope

* Optimize Hurst Exponent calculation

- Removed redundat loops and unnecessary operations.
- Precomputed values fro time lag logarithms to avoid recalculation.
- Simplified logic in ComputeNextValue for better performance.
- Updated and clarified comments for improved readability.

* Refactor HurstExponent indicator

- Made _sumX and _sumX2 fields readonly.
- Updated loop for calculating time lag differences to avoid out of
  bound.
- Renamed lookbackPeriod with period.
- Replaced DateTime.Now with a fixed date.
2024-12-05 10:19:31 -03:00
Martin-Molinero
99558928f0 Improve ObjectStore root config handling (#8445) 2024-12-04 19:17:10 -03:00
Roman Yavnikov
a2efee8be9 feat: Binance future support StopMarket for CryptoFuture (#8441)
test:feat: CanSubmit StopMarket Crypto or CryptoFuture in Binance Model
2024-12-04 14:46:02 -03:00
Jhonathan Abreu
a1d0b6cde2 Live trading consolidation synchronization (#8436)
* Adjust time slice time for live trading

Adjust time slice to be driven by data, so that consolidators are update at the correct times.
Live trading uses DateTime.UtcNow which might be a few milliseconds after the latest data, causing some race conditions in consolidators scan times.

* Refactor: rounding time slice time down for past consolidators scan (live)

* Cleanup
2024-12-04 11:15:00 -04:00
JosueNina
8123e76e3c Validate inputs for safe logarithm calculation (#8439)
- Ensure both previousPoint and previousPoint2 are non-zero.
- Prevent division by zero and undefined errors.
- Add unit test to verity the new validation logic.
2024-12-03 17:30:07 -03:00
Jhonathan Abreu
a28d1f2ffe Universe data frames improvements (#8433)
* Default Data to null for ETFConstituentUniverses.

The data collection will be assigned only if needed. This allows data column to be filtered from dataframes since it will always be null for all constituents.

* Make base data collection aggregator reader fall back to BaseDataCollection

After instatiating the collection type, fall back to the base BaseDataCollection to aggregate data if the type is not a base data collection.

* Minor change

* Minor change

* Update pythonnet to 2.0.41

* Ignore data column for every flattened universe dataframe

* Filter empty collections columns in data frames

* Allow snake case named attributes in PythonSlice

* Remove PythonSlice Data Python class

Pythonnet handles dynamic objects behavior
2024-12-03 16:19:17 -04:00
Ricardo Andrés Marino Rojas
f4314549c3 Fix warming up bug QCAlgorithm.WarmUpIndicator() (#8431)
* First draft of the solution

* Add regression tests

* Nit changes

* Solve root issue

* Improve regression tests

* Reduce duplication

* Nit change

* Improve implementation

* Address suggestions

* Address requested improvements

* Nit change

* Nit changes

* Nit change
2024-11-29 16:35:37 -03:00
Jhonathan Abreu
d416580456 Adjust lower-resolution fill-forwarded strict end-timed daily bars (#8412)
* Adjust lower-resolution fill-forwarded daily bars when strict end times is enabled

This allows to get fill-forwarded bars with unchanged time stamps

* Minor fixes

* Minor test data changes

* Fixes and comments

* Address peer review and add some fixes

* Minor fix and add regression algorithm

* Minor fix
2024-11-29 09:52:01 -04:00
Jhonathan Abreu
93ce62536f Revert "Fix warming up bug in Stochastic indicator (#8422)" (#8430)
This reverts commit 312392d6ae.
2024-11-29 09:50:30 -04:00
Ricardo Andrés Marino Rojas
312392d6ae Fix warming up bug in Stochastic indicator (#8422)
* First draft of the solution

* Add regression tests

* Nit changes

* Solve root issue

* Improve regression tests

* Reduce duplication

* Nit change

* Improve implementation
2024-11-29 09:49:06 -04:00
JosueNina
01734e1f61 Implement Mesa Adaptive Moving Average (MAMA) Indicator (#8428)
* Initial implementation of MAMA indicator and tests

* Implemented Mesa Adaptive Moving Average (MAMA) indicator

- Implemented the MAMA indicator.
- Created methods with overloads to support custom and default
  fastLimit/slowLimit
- Included necessary logic to calculate the mesa adaptive moving average
  based on John's formula.
- Created unit tests to validate MAMA's behaviour.

* Refactor Mesa Adaptive Moving Average(MAMA)

- Separated the logic into smaller functions for better maintainability.
- Improved variable names to reflec their purpose.
- Updated comments to reflect changes and improve readability.
- Consolidated MAMA method overlaod by using default parameters values.

* Refactor variables and update method parameters

- Renamed variables for better clarity.
- Updated method to use 'IBaseDataBar' instead of 'TradeBar'
- Used 'MAMA({fastLimit}, {slowLimit}) instead of just 'MAMA'
2024-11-27 18:54:59 -03:00
Ricardo Andrés Marino Rojas
124063a2a4 Change Log.Trace() to Log.Debug() (#8429) 2024-11-27 18:27:54 -03:00
Ricardo Andrés Marino Rojas
b99da54d5a Implement Reset() method (#8410)
* First draft of the feature

* Add XML docs

* Fix and improve unit test

* Address suggestions

* Improve unit test

* Improve implementation
2024-11-27 16:53:02 -03:00
Jhonathan Abreu
bc5d51806d Universe data frames normalization (#8385)
* Normalize universe data frames

Universe and (generically BaseDataCollection) data frames are not normalize and unpacked into a data frame, instead of just creating data frames with the universe lists within it

* Fix unit tests and algorithms to expecte new universe dataframe format

* Fixes

* Add PandasConverter.DataFrameGenerator class

* Pandas data frame generator class fixes

* Add comments

* Housekeeping

* Add attributes to mark classes and properties for pandas processing

* Improve pandas properties expanding

Allow and handle duplicate names

* Use PandasData generalization for Lean common data types

* Add points time as column when converting base data collections to data frames

* Cleanup and minor changes

* Minor change

* Pandas data to get type members on demand

* Move Pandas helper classes to their own files

* Minor changes

* Add flatten argument to python history api

This allows users to decide whether they want fully expanded dataframes for universe and other collection data types. Else, master behavior is kept

* Adding missing changes to last commit

* Update Pythonnet version to 2.0.40

* Add flattent argument to algorithm's OptionChain api

* Minor changes

* Housekeeping

* Minor changes

* Bug fix skipping data collection data points

* Add comment

* Set correct exchange time to OptionUniverse instances

* Address peer review and cleanup

* Cleanup

* Minor changes
2024-11-26 16:16:34 -04:00
JosueNina
f3ed5b1206 Fix correlation type (#8426)
- Addressed bug causing mismatch between types of correlations.
- Updated C method to include CorrelationType.
- Created regression test to ensure proper validation.
2024-11-26 14:05:49 -03:00
Ricardo Andrés Marino Rojas
eb6c5d20f5 Fix typos (#8349)
* Fix typos

* Fix bugs

* second try to fix bugs

* Fix typos

* Nit change

* Update enums too

* Fix bugs
2024-11-26 11:36:14 -03:00
Ricardo Andrés Marino Rojas
b70b5bd5fe Add extended market hours option in DateRules.WeekStart() (#8400)
* First potential solution

* Add unit tests

* Address requested changes

* Add unit test reproducing user bug

* Missing update

* Address reviews

* Improve unit test

* Improve unit test

* Nit change

* Nit changes

* Nit changes
2024-11-25 18:09:44 -03:00
Ricardo Andrés Marino Rojas
5ac7d00e24 Normalize Date timezone (#8420)
* First draft of the solution

* Add unit test

* Nit change
2024-11-25 17:44:22 -03:00
JosueNina
469d960f50 Implement Connor's Relative Strength Index(CRSI) Indicator (#8419)
* Add Connors Relative Strength Index(CRSI) Indicator

- Implemented CRSI combining RSI, Streak RSI, and ROC
- Added unit tests for CRSI calculation to ensure correctness and
  reliability.
- Inclued the spy_crsi.csv file for testing purposes and validation of
  CRSI logic.

* Refactor CRSI indicator

- Updated the CRSI logic to use Percent Change of Daily Returns instead
  of ROC.
- Modified the ConnorsRelativeStrengthIndex class:
  - Updated ComputeNextValue to calculate daily returns and relative
    magnitude
- Improved documentation and comments

* Refactor CRSI Indicator:

- Refactored the method that updated the trend streak based on price
  changes.
- Created a new method ComputeTrendStreak.
- Added check for null or 0 value in _previousInput.

* Fix comments from code review

- Add _ to priceChangeRatios
- Move _srsi.Update() to the top to avoid duplication
2024-11-25 15:43:42 -03:00
Jhonathan Abreu
7eea365aa1 Let delistings through for internal subscriptions (#8398)
* Let delistings through for internal subscriptions

Without it, previously mapped continuous future contracts for which a position is open never received a delisting event for them to be liquidated and marked as non-tradable

* Update regression algorithm stats

* Revert/remove transaction handler initialization parameters DTO class

* Cleanup
2024-11-25 11:41:02 -03:00
Jhonathan Abreu
760071a2f7 Fix 0DTE index options selection (#8418)
* Revert parts of GH PR 8395 to fix 0DTE index options

* Add regression algorithms

* Cleanup

* Cleanup
2024-11-20 09:18:11 -04:00
Jhonathan Abreu
fa1ef4f763 Index option chain backwards compatibility (#8395)
* Fix option universe

Set right time using exchange time zone when reading.
Remove OptionUniverse market hours hack in GetEntry extension method.

* Minor change
2024-11-15 17:30:44 -04:00
Roman Yavnikov
f7b012aa11 Feature: Implementation Charles Schwab Brokerage (#8406)
* feat: ExtendedRegularTradingHours property in CharlesSchwabOrderProperties

* feat: BrokerageModel, FeeModel of Charles Schwab

* refactor: CharlesSchwab Fee model
remove: SecurityType.Index in CanSubmit CharlesSchwab

* refactor: CharlesSchwabFeeModel (a little bit simpler)

* refactor: CharlesSchwabFeeModel (more simpler)
2024-11-15 18:17:20 -03:00
JosueNina
725ad73240 Implement Average Range (AR) Indicator (#8404)
* Add Average Daily Range indicator and tests

- Implemented AverageDailyRange indicator
- The indicator uses a Simple Moving Average (SMA)
- Created unit tests for the indicator
- Includes example input data and test file (spy_adr.csv)

* Refactor AverageDailyRange Indicator

- Renamed AverageDailyRange to AverageRage for a more generic approach
- Replaced explicit types with 'var'
- Updated method name in test cases
- Placed AR method in the correct alphabetical order

* Solving minor issues with AR indicator

- Replace TradeBar with IBaseDataBar
- Remove unnecessary override methods
2024-11-15 11:19:55 -03:00
JosueNina
7bbf42f79b Implement Premier Stochastic Oscillator (PSO) Indicator (#8394)
* Implement Premier Stochastic Oscillator (PSO)

- Added PremierStochasticOscillator class with two Exponential Moving
  Averages (_ema1 and _ema2) for double smoothing.
- Implemented PSO computation:
  - Normalized Stochastic (nsk) = 0.1 * (Fast%K - 50)
  - Double-smoothed Normalized Stochastic
- Added XML documentation for public methods and key calculations.

This commit introduces a new indicator.

* Add license header and adjust spacing

* Refactor Premier Stochastic Oscillator (PSO)

- Renamed smoothing variables for clarity
- Integrated PSO logic directly in ComputeNextValue
- Used IndicatorExtensions for streamlined EMA chaining
- Updated tests to match refactored logic

* Refactor PSO

- Changed "STO" to "PSO"
- Removed unused imports
- Updated private fields
- Minor code cleanup
2024-11-14 18:22:46 -03:00
Ricardo Andrés Marino Rojas
f2da037d42 Solve divide by zero exception in McGinleyDynamic indicator (#8397)
* Add SafeDivision() method

* Add assertions

* Nit changes

* Nit change
2024-11-14 18:20:18 -03:00
Ricardo Andrés Marino Rojas
5c5c527252 Use SafeDivision() method to avoid overflow exception in CCI (#8396)
* Use SafeDivision() method to avoid overflow exception

* Nit change
2024-11-14 18:20:00 -03:00
Martin-Molinero
71d09a3567 Private cloud minor improvements (#8409)
* Private cloud tweaks

* Minor tweaks for optimization
2024-11-14 17:22:33 -03:00
JosueNina
085476a222 job_queue: fix typos in comments (#8390)
Corrected minor typos in comments within the JobQueue class to improve
readability

- Verify all comments for further errors
2024-11-01 19:13:49 -03:00
Alexandre Catarino
c78774b99a Adds Country Static Class (#8389)
This class contains all countries and mapping them to their ISO 3166-1 alpha-3 codes.
2024-11-01 19:13:07 -03:00
Ricardo Andrés Marino Rojas
d5b2e4d8cc Make Target.MoveAhead() case insensitive (#8382)
* First draft of the solution

* Try a different approach

* Nit change

* Add unit tests

* Add edge cases

* Address requests
2024-10-24 09:29:16 -03:00
Ricardo Andrés Marino Rojas
828d9238b8 Remove duplicated keys in OpenInterestFutureUniverseSelectionModel (#8365)
* First draft of the solution

* Enhance implementation
2024-10-21 09:43:06 -03:00
Jhonathan Abreu
f2100adb46 Fix price shifts around futures rollover date (#8371)
* Test

* Fix price shift on continuous future rollover

* Keep track of both data and exchange time in subscription data reader

* Fix for daily and hourly resolutions.

Add daily and hour algorithms

* Fixes for emitting new exchange dates at the beginning and end when data is not available

* Cleanup

* Minor fix

* Minor fix: detect mapping in data reader after advancing time keeper

* Minor fix

* More fixes

* More fixes

* Fixes for universe files

* More fixes for daily resolution data

* Separate DateChangeTimeKeeper to its own file

* Add DateChangeTimeKeeper unit tests

* Minor fix

* Add more DateChangeTimeKeeper unit tests

* Address peer review

* Address peer review

* Address peer review

* Detect mappings using the config NewSymbol event

* DateChangeTimeKeeper performance improvement for time zone conversions

* Clean up date change time keeper

* Cleanup

* Minor regression algo update

* Cleanup

* Cleanup

* Fix perform universe selection on sundays for continuous futures with extended market hours

* Cleanup

* Address peer review

* More cleanup

* More cleanup
2024-10-21 09:38:00 -03:00
Jhonathan Abreu
159fa5a182 Fix Python Consolidate API to respect strict daily times for Daily resolution (#8373)
* Fix ConsolidateRegressionAlgorithm

- Fix Bitcoin custom data time range. Historical data goes from April 2014
- Fix expected consolidated bar counts
- Fix python Consolidate implementations to respect daily strict times for Daily resolution

* Housekeeping
2024-10-16 17:35:10 -03:00
Ricardo Andrés Marino Rojas
8ef0a4977b Fix bug in QuantBook.UniverseHistory() when using Monthly date rule (#8368)
* Fix bug in Universe history with montly selection

* Reduce duplication

* Fix missing overload method

* Address requests

* Nit change

* Improve implementation

* Improve implementation

* Fix bug and add more unit tests

* Nit change

* Address requested changes

* Address requested changes

* Nit change
2024-10-16 17:34:26 -03:00
Martin-Molinero
ffdb615a4d Add research node packet (#8360) 2024-10-15 13:38:39 -03:00
Martin-Molinero
8f57a8c8ff Update readme.md 2024-10-14 18:56:42 -03:00
Roman Yavnikov
a831adc9c8 Fix: Broken Regression Algorithms (#8366)
* fix: CustomData/RegisterIndicator-RegressionAlgorithm

* fix: CustomDataPropertiesRegressionAlgorithm

* fix: CustomDataRegressionAlgorithm py

* fix: CustomDataPropertiesRegressionAlgorithm py

* fix: RegisterIndicatorRegressionAlgorithm py

* refactror: use nasdaq instead of quandl in proxy url
2024-10-10 11:36:18 -03:00
Roman Yavnikov
6b22254924 Feature: new sorting property in SubscriptionDataSource and SortEnumerator (#8352)
* feat: sort property in SubscriptionDataSource

* refactor: read lines (with sort opportunity) in TextSubscriptionDataSourceReader

* refactor: xml description of Sort property in SubscriptionDataSource

* revet: TextSubscriptionDataSourceReader changes

* feat: develop UnsortedTextSubscriptionDataSourceReader

* remove: UnsortedTextSubscriptionDataSourceReader

* feat: develop SortEnumerator
feat: use SortEnumerator in SubscriptionDataReader

* revert: TextSubscriptionDataSourceReader changes

* feat: use sort Enumerator in LiveCustomDataSubscriptionEnumeratorFactory

* test:feat: Unsorted Live Data Feed with using Object Store

* test:feat: history CustomData request with unsorted data

* refactor: develop TryWrapper on SortEnumerator

* remove: extra spacing

* refactor: Sort in SubscriptionDataSource

* feat: add RegressionAlgorithms when source return data in Descending format

* refactor: xml description of prop Sort in  SubscriptionDataSource

* refactor: SortEnumerator

* test:refactor access modifier in ExampleCustomDataWithSort

* test:refactor: increase performance LiveDataFeedSourcesDataFromObjectStore

* feat: add xml comment of regression algorithm

* test:revert: access modifier to public in internal test class

* test:refactor: use while instead of timer

* Revert "test:refactor: use while instead of timer"

This reverts commit 4fe43da809.
2024-10-07 18:16:33 -03:00
Ricardo Andrés Marino Rojas
0e61415ce2 Fix bug ImmediateExecutionModel when using Crypto (#8355)
* First draft of the solution

* Add missing algorithm

* Improve regression tests

* Nit change

* Address requests

* Nit change

* Address minor requests

* Nit changes

* Nit suggestion
2024-10-07 16:46:37 -03:00
Martin-Molinero
16c893deb6 Fix history manager configuration assertion (#8361) 2024-10-07 10:40:28 -03:00
Ricardo Andrés Marino Rojas
33048149af Add custom ToString() method in API classes (#8357)
* Potential solution

* Improve solution

* Nit change

* Nit change
2024-10-07 10:37:11 -03:00
Martin-Molinero
0a2c05ab1e Improve performance of OptionChain (#8359)
- Improve performance of OptionChain by creating a single pandas df
2024-10-04 20:03:53 -03:00
Martin-Molinero
e16b27f089 Update readme.md 2024-10-04 13:33:59 -03:00
Jhonathan Abreu
0a9dc2c71c QCAlgorithm's OptionChain() api refactor (#8334)
* Fix pandas converter to handle list of data with different symbols

* Properly convert list of data into dataframe

Take into consideration data for multiple symbols in the same list

* Cleanup

* Index dataframes by symbol object instead of SID string

* Add symbol equality operator to compare against object

* Exclude "ID" from option chain dataframe

* Minor fix

* Add greeks columns directly in option chain dataframe.

Also add pass-through properties for greek values in OptionUniverse

* Some cleanup

* Minor fix

* Add new QCAlgorithm.OptionChains() method

- Use OptionChains as output
- Add DataFrame to OptionChain and OptionChains
- Rename Greeks classes
- Add ISymbolProvider for classes that have a symbol (IBaseData, OptionContract)

* Unify QCAlgorithmOptionChain API

Also refactor OptionContract to handle: (1) Actual market data and option price model data, and (2) OptionUniverse data

* Pass symbol properties to OptionUniverse option chain from algorithm

* Format OptionContract for dataframe

* Minor fix

* Add multiple option chains api regression algorithms and other minor changes

* Address peer review

Add NullGreeks class: keep ModeledGreeks as internal as possible

* Minor fix and add PandasConverter unit tests

* Peer review: Non-thread-safe Lazy for Python

* Handle Greeks unwrapping by PandasData

* PandasData cleanup

* Add data and other minor changes

* Unit test fix

* Update Pythonnet to 2.0.39

* Cleanup

* PandasData handling children class members

Address peer review

* Fix: indexing symbol conversion in pandas mapper

* Fix pandas mapper to convert string keys to symbol only when necessary

* Cleanup

* Cleanup

* Add PandasColumn python class to handle proper indexing

This allows propery hash and equality between Symbols, C# strings and Python strings

* Minor fixes

* Symbol cache improvements

* Minor fix for cache miss

* Revert PandasMapper reserved names and improvements

* Minor fix

* Revert reserved names

* Minor fix for Symbol equality operators

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-10-04 12:26:15 -04:00
Martin-Molinero
7c9aa858c2 Improve python command serialization (#8351)
- Fix bug in python command serialization, expanding existing tests
2024-10-02 09:19:04 -03:00
Martin-Molinero
8fb70b20d0 Enhance command support (#8348)
* Enhance command support

- Enhance command support, adding link helper methods. Adding and
  expanding new tests
- Minor improvement for command str representation

* Minor test fix
2024-09-30 16:01:08 -03:00
Louis Szeto
809faa24de Add Backspread Option Strategies (#8312)
* Call and put backspread definitions

* Margin model

* regression tests

* strategy unit test

* refactor

* Use option strategies to order
2024-09-26 16:57:20 -03:00
Jhonathan Abreu
ad5aa263c0 Infer data type from configs in bar count history requests (#8344)
* Infer data type from configs in bar count history requests

* Infer data type from configs in bar count history requests

* Minor changes

* Minor fix

* Cleanup
2024-09-26 16:51:19 -03:00
Roman Yavnikov
a1bb907e03 Feature:Alpaca: support MarketOnOpen and MarketOnClose (#8341)
* feat: missed Alpaca config in Launcher

* feature: support of new OrderTypes for Equtity in AlpacaBrokerage model
2024-09-25 14:30:27 -03:00
Roman Yavnikov
71540f5015 Feature: support MarketOnOpen and MarketOnClose (#8340)
* remove: not used proxy config TradeStation

* feat: missed config of TradeStation in Launcher

* feat: support new OrderTypes in TradeStationBrokerageModel
2024-09-24 15:11:36 -03:00
Kevin Wheeler
a0055a3695 Improve data not found error messages. (#8295)
* Improve data not found error messages.

* Minor tweaks

---------

Co-authored-by: Kevin Wheeler <spreadlove5683@gmail.com>
Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-09-20 16:56:58 -03:00
Martin-Molinero
0b285df496 Minor fix for option contract universe (#8337) 2024-09-20 13:16:20 -03:00
Martin Molinero
4d37096b3f Reduce realtime shutdown timeout 2024-09-20 10:04:58 -03:00
Martin Molinero
7c42ea795f Minor improvement for live trading shutdown 2024-09-19 20:09:21 -03:00
Martin-Molinero
f2f1d06237 Improve shutdown (#8335) 2024-09-19 19:32:29 -03:00
Martin-Molinero
86fd80a31a Generic live command support (#8330)
* Generic command support

- Adding generic algorithm command support. Adding regression algorithms
- Allow PythonWrapper to validate classes too

* Minor improvements
2024-09-19 16:02:42 -03:00
Roman Yavnikov
c556d16775 Feature: new Tick constructor for TickType.OpenInterest (#8323)
* feat: create OpenInterest constrcutor of Tick

* feat: GetSubscribedSymbols by TickType

* test:feat: GetSubscribeSymbolsBySpecificTickType

* refactor: equal channel name with InvariantCultureIgnoreCase
2024-09-17 12:52:24 -03:00
Martin-Molinero
6351773a01 Option universe resolution improvements (#8324)
* Option universe improvements

- Improvement for resolution handling of option universes, affecting
  performance in live mode. Adding regression algorithm

* Minor fix for research test
2024-09-16 10:22:58 -03:00
Jhonathan Abreu
bf4b08e202 Fix: adjust option expiry reference date (#8322)
* Fix: adjust option expiry reference date

* Add universe files

* Update data and other minor changes

* Minor changes

* Add regression algorithm summary
2024-09-13 18:22:26 -04:00
Jhonathan Abreu
fa9ff399cc Euro Stoxx 50 Index and Index Futures support (#8278)
* EUREX data

EUREX data model and sample data

* Add EUREX futures expiry function and sample algorithms

* Add EuroStoxx50 futures map and factor files

* Reduce eurex data for repo

* Map eurex market to primary exchange

* Update Euro Stoxx 50 (FESX) map and factol files

* Update Euro Stoxx 50 (FESX) minute data

* Added EURSD data

* Added 2 basic FESX futures algorithms in CSharp and Python (#2)

* Add regression algorithms

* Update regression algorithms and data

* Minor change

* Cleanup

---------

Co-authored-by: paulius-an <118921953+paulius-an@users.noreply.github.com>
2024-09-12 10:00:16 -04:00
Jhonathan Abreu
16c4259342 Add QCAlgorithm.OptionChain() method to fetch option chains (#8316)
* Add new QCAlgorithm.OptionChain method to get full data option chain

* Add extension method to get canonical symbol

* Support future options in new OptionChain method

* Replace option chain provider with OptionChain method in some regression algorithms

* Add new regression algorithms for OptionChain method

* Replace option chain provider with OptionChain method in some regression algorithms

* Minor

* Cleanup

* Minor changes in regression algorithms

* Minor adjustments
2024-09-11 15:15:51 -04:00
Ricardo Andrés Marino Rojas
724d0b06a5 Add extra argument in QuantBook.UniverseHistory() for using an IDateRule (#8301)
* First draft of the solution

* Handle end date better

* Improve unit tests

* Add extra argument in missing method

* Nit change

* Nit change

* Nit change

* Undo changes to C# generic UniverseHistory()

* Address suggestions

* Improve unit test

* Add null checks

* Minor adjustment

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-09-11 13:41:57 -03:00
Ricardo Andrés Marino Rojas
ba7fe05574 Add BeforeMarketOpen() and AfterMarketClose() date rules (#8311)
* First draft of the solution

* Add unit tests

* Improve unit tests

* Nit changes
2024-09-10 15:56:31 -03:00
Ricardo Andrés Marino Rojas
50437946e2 Add missing end_date in python regression algorithm (#8315) 2024-09-10 14:33:44 -03:00
Ricardo Andrés Marino Rojas
418970bb48 Add TravisExclude category to failing CI unit test (#8313) 2024-09-10 13:25:41 -03:00
Roman Yavnikov
bef045a360 Fix: Get GroupOrders ByBrokerageId (#8310)
* fix: Get GroupOrders ByBrokerageId

* test:feat: return all combo orders with the same brokerageId
2024-09-10 13:25:22 -03:00
Jhonathan Abreu
49bf436aa2 Remove Lean path info from runtime exceptions (#8309)
* Strip lean path info from runtime exceptions

* Minor fix
2024-09-09 17:54:29 -04:00
Jhonathan Abreu
e29bb2c5e0 File-based options universe (#8212)
* Initial options universe with greeks implementation

* Options universe improvements

* Address peer review

* File based options universe fixes and improvements.

- Adjust OptionUniverse start-end times and period.
- Adapt unit tests and some algorithms to pass with new options universe selection.

* Updated options regression algorithms stats for new universe data

* Updated options regression algorithms stats for new universe data

* Updated options regression algorithms stats for new universe data

* Updated options regression algorithms stats for new universe data

* Updated options regression algorithms stats for new universe data

* Option chain provider with new options universe

* Allow canonical option history requests

* Address peer review

* Address peer review

* Fix symbols parsing in OptionUniverse

* Fix universe selection subscriptions start time to not include extended market hours

* Minor changes

* Minor changes

* Peer recommended changes and fixes

* Update regression algorithm stats

* Update regression algorithms stats and minor fixes

* Fix option chain provider history request

* Round option indicators values

* Added option universe csv header property

* Update regression algorithms stats

* Update regression algorithms stats

* Data fixes and regression algos stats update

* Unit test fixes

* Minor changes

* Option chain handling in live trading data feed

* Minor changes

* Added processed data provider

* Fix thread-safety violation in Slice class

* Minor change

* Update options filter universe API to use OptionUniverse data

Add new filter methods for greeks, IV and open interest

* Option filter universe api updates

* Add OptionUniverse history regression algorithms

* Add regression algorithms for new options filter universe api methods

* Added options greeks data and updated regression algorithms

* Address peer review

* Address peer review

* Add more assertions to new options filter api regression algorithms

* Minor performance improvement.

Reduce greeks binomial model steps to 140

* Minor tests updates

* Greeks numerical models performance improvements

* Greeks numerical models performance improvements

* Revert array pool change for option pricing numerical models

* Update default dividend yield provider depending on option type

* [TEST]

* Add helper method con calculate time till expiration

* Use double in price option numerical models

* Implied volatility calculation improvements

- Adjust root finding method accuracy as a factor of the option price
- Use BSM to get a first guess

* Cleanup

* Some regression algorithms and unit tests cleanup

* Regression tests updates after rebasing from master

* Add universe files

* Self review and cleanup

* Minor regression tests updates after rebase

* Fix: set data time zone to same as exchange tz for options universes

* Minor change

* Minor change

* Fix for live trading options universe selection

* Keep underlying when aggregating collections in BaseDataCollectionAggregatorEnumerator

* Update index options regression algorithms stats

* Minor change

* Address peer review

* Memory usage improvements

* Minor build fix

* Minor changes and test fixes

* Cache symbols in OptionUniverse

* Cleanup

* Fix index option creation in OptionUniverse

* Use cached underlying SID when parsing from string

* Abstract symbols cache to BaseDataCollection

* Return actual underlying symbol when mapping decomposing ICO ticker

* Address peer review

* Minor performance improvements reduce garbage

* Limit Symbols and SIDs cache size to help with memory usage

* Minor fix in symbols and sid cache cleanup

* Build fix

* Lazily parse greeks on individual access

* Cleanup and tests

* Address peer review

* Minor greeks fix

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2024-09-09 12:39:31 -03:00
Dennis Yemelyanov
8fcc9f7d4e fix some comments for option security types (#8304) 2024-09-09 11:37:26 -03:00
Andy Geach
5209332074 Update readme.md to remove references to Visual Studio for Mac, which has been discontinued (#8298) 2024-09-06 11:59:28 -03:00
Roman Yavnikov
adfad475cc Feature:TradeStationBrokerage: support ComboMarket && ComboLimit (#8290)
* refactor: adding OrderId in GroupOrderManger

* feat: new support of OrderTypes in TradeStationBrokerageModel
feat: unSupported OrderTypes in CanUpdateOrder's TradeStationBrokerageModel

* feat: AllOrNone property in TradeStationOrderProperties

* feat: unsupported SubmitCrossZero of Combo Order in TSBrokerageModel

* test:feat: submit / update CrossZero Combo Orders

* feat: new Message Brokerage error message
refactor: use new Message in TradeStationBrokerageModel

* feat: setter of Id in GroupOrderManager

* feat: new constructor of GroupOrderManager

* feat: develop GroupOrderCacheManager service

* fix: groupOrderManger.Id in OrderProvider

* fix: incrementOrderGroupOrderManagerID in BrokerageTransactionHandler
feat: add _groupOrderManagerId in OrderProvider

* remove: extra semicolon

* refactor: prevent increment GroupOrderID

* feat: add new Exchanges

* feat: Try Get Group Combo Orders extension

* refactor: ComboORderType in TSBrokerageModel

* remove: implementing of prop ID in GroupOrderManager

* refactor: UnsupportedCrossZeroByOrderType message

* fix: warning of UnsupportedCrossZeroByOrderType

* fix: several exchanges code based on tradier docs
https://documentation.tradier.com/brokerage-api/reference/exchanges

* feat: add missed Exchange in Global class

* refactor: possible update LimitPrice in TSBrokerageModel
test:feat: validate upddate LimitPrice of ComboLimit Order

* refactor: GroupOrderCacheManager
remove: TryGetGroupCachedOrders from extension

* refactor: exchange SPHR to MIAX_SAPPHIRE

* remove: Exchange BYX cuz It is BATS_Y

* refactor: change position of Exchange C2

* refactor: change constructor's access modifier in class Exchange
2024-09-06 10:31:14 -03:00
Martin-Molinero
21fcadf0f8 Ignore failing live future option unit test (#8300) 2024-09-05 16:42:42 -03:00
Ricardo Andrés Marino Rojas
e893e67e9b Throw exception when base currency not found (#8289)
* First draft of the solution

* The same check for crytpo is done before

* Fix failing unit tests

* Remove non perpetual crypto futures from SPDB

* Address requests

* Fix failing unit tests
2024-09-04 12:14:53 -03:00
Alexandre Catarino
3b588d04fb Adds Overload to AddIndexOption (#8291)
* Adds Overload to AddIndexOption

Simplify usage. We don't need to create/add the underlying explicitly, see AddIndexOption(string, Resolution, string, bool) overload.

* Addresses Peer-Review

- Default market is `null` instead of `Market.USA` allowing for `BrokerageModel` setup.
- `AddIndexOption` and `AddIndexOptionContract` methods now return `indexOption` objects.

* Fixes Logic Bug
2024-09-04 10:30:05 -03:00
Ricardo Andrés Marino Rojas
e81bcbb987 Improve PythonIndicator.IsReady implementation (#8287)
* First draft of the solution

* nit change

* Add improvements

* Fix failing unit tests

* Add improvements
2024-09-04 10:07:13 -03:00
Roman Yavnikov
96e91b446d Fix: #8226, update spdb binance/binanceus (#8293)
* feature: update binance spdb data

* feature: update binanceus spdb data

* test:fix: EURUSDC stable coins conversation
2024-09-04 10:05:07 -03:00
Ricardo Andrés Marino Rojas
403f0348bd Update Bybit SPDB (#8294)
* Update Bybit SPDB

* Remove trailing comma
2024-09-03 17:55:12 -03:00
Ricardo Andrés Marino Rojas
eeeb310438 Update minimum price variation of some entries of CME futures in SPDB (#8288)
* Update some entries of CME futures in SPDB

* Adjust 6B minimum price variation
2024-08-28 19:59:40 -03:00
oussamanahdi
271f0bb08e Update readme.md (#8286) 2024-08-26 19:11:04 -03:00
Ricardo Andrés Marino Rojas
3a09c70851 Fix warm up indicator bugs (#8279)
* Potential solution

* Try a different approach

* Improve unit tests

* Nit change

* Improve implementation

* Fix another bug and improve unit tests
2024-08-26 10:20:40 -03:00
Roman Yavnikov
f31251732e Fix: Coinbase MinimumOrderSize tests based on new SPDB data (#8276)
* test:fix: minimValue based on new SPDB data

* fix: Estimated Strategy Capacity in FractionalQuantityRegressionAlgorithm
2024-08-23 11:47:45 -03:00
Roman Yavnikov
9baacdbdd6 feat: Coinbase SPDB update (#8273) 2024-08-22 17:42:58 -03:00
Martin-Molinero
363d469d6a Minor indicator history fix (#8270)
* Minor indicator history fix

- Take into account warmup period when used, the last bar of the warmup
  period is counted as a data point.
- Fix bug where in some cases the last data point could of been missed
  and the indicator not updated with it

* Minor tweak
2024-08-22 16:48:26 -03:00
Ricardo Andrés Marino Rojas
c186addf94 Add missing price magnifier in SPDB (#8271) 2024-08-22 16:44:26 -03:00
Ricardo Andrés Marino Rojas
17049dcd56 Fix null exception thrown in SubscriptionManager.ScanPastConsolidators (#8267)
* Initial draft of the solution

* Improve implemetation

* Nit change

* Address requests

* Switch from LinkedList ot List

* Fix bug
2024-08-22 09:55:41 -03:00
Jhonathan Abreu
d88387ac67 Extend Python wrappers error messages (#8257)
* Implement runtime checks for python wrappers

* Implement runtime checks for python wrappers

* Add more python wrappers runtime checks

* Add dictionary conversion unit tests

* Add python wrappers runtime checks for properties

* CLeanup base python wrapper messages
2024-08-19 14:27:32 -04:00
Ricardo Andrés Marino Rojas
74c3501ed3 Fix bug for history requests with custom symbols (#8262)
* Potential solution to the bug

* Add test file

* Fix bugs

* Address requested changes
2024-08-19 15:26:42 -03:00
Ricardo Andrés Marino Rojas
a543af71dc Solve bug (#8256) 2024-08-19 11:57:21 -03:00
Jhonathan Abreu
9b332c2149 Dividend yield calculation fix (#8264)
* Fix dividend yield calculation

* Get security price as input for dividend yield provider

* Account for splits in dividend yield provider

* Fix split adjustment for dividend yield calculation

* Use right dividend yield in options indicators
2024-08-19 09:30:05 -04:00
keshavdalmia10
1e620e54fe Feature 8132 implement vortex indicator (#8242)
* Implemented the vortex indicator.

* changed the vortex.cs calculations

* chore: Refactor VortexTests.cs and QCAlgorithm.Indicators.cs

* Refactor VortexTests.cs

* made changes according to the comments

* used indicator exxtension methods

* made changes in the naming convention and added condition for division by zero.

* Using composite indicators to clean up

---------

Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
2024-08-14 15:43:21 -03:00
Martin-Molinero
7879795207 Enable daily precise end time by default (#8254)
* Default daily precise end times

- Enable by default daily precise end times. Updating stats
- Minor fix for algorithm manager consolidator updates, adding new regression test
  asserting behavior and updating others
- Minor fix for SubscriptionData creator avoid round down on warmup if
  not appropiate
- Adjust consolidators to emit on daily strict end times if requested
  daily resolution and setting enabled
- Updating regression algorithms

* Skip daily data on extended market hours

* Some cleanup and self review

* Revert unrequired change
2024-08-14 12:49:56 -03:00
Noah Misch
d2d366e3f9 Fix sign of order quantity in example algorithm OnMarginCall(). (#8251)
Despite the comments about avoiding margin calls and about padding, this
turned a proposed sale of 100 shares into a *buy* of 110 shares.
2024-08-12 17:40:51 -03:00
Ricardo Andrés Marino Rojas
5226b7a468 Add more options to Field class (#8228)
* First draft of the solution

* Reduce duplication and add more properties

* Add regression tests

* Add xml docs

* Add unit tests

* Improve regression and unit tests

* Address requested changes

* Address request and improve unit tests

* Add unit test and fix bug

* Improve unit tests and implementation

* Nit change

* Address reviews

* Improve regression tests

* Address requests

* Fix bug

* Address requests
2024-08-07 19:08:34 -03:00
FemtoTrader
1947a58541 Implements new indicator - CKS - ChandeKrollStop (#8198)
* Implements ChandeKrollStop

* readonly

* Move IsReady/WarmUpPeriod above the constructors

* remove private _period

* minor

* rename Stops to Short/Long

* using Maximum/Minimum

* fix tests

* rename some variables and use movingAverageType for ATR

* movingAverageType
2024-08-07 14:51:39 -03:00
Roman Yavnikov
1bca3f6081 feat: missed reference on DownloaderDataProvider in Lean.Launcher (#8247) 2024-08-07 14:51:05 -03:00
Noah Misch
2b1136e446 Fix algorithms using OnData(TradeBars) w/o using arg or other OnData(). (#8245)
Commit d24f665ee4 removed the
Engine/AlgorithmManager.cs support for OnData(TradeBars), making these
methods dead code.  Hence, some of these algorithms no longer placed
orders.  Fix by changing OnData(TradeBars) to OnData(Slice).  Files that
use the TradeBars argument or use OnData(Dividends) have the same
trouble; leave them for future work.
2024-08-06 10:15:56 -03:00
Roman Yavnikov
86fcc40c3e Feature: Generic brokerage downloader wrapper (#8235)
* feat: new constructor of AlgorithmNodePacket

* refactor: extract JobQueue configuration

* remove: not used `using` in IDataDownloader

* feat: create BrokerageDataDownloader

* Revert "refactor: extract JobQueue configuration"

This reverts commit 5778936b71.

* Revert "feat: new constructor of AlgorithmNodePacket"

This reverts commit d7a565ff76.

* feat: new config `data-download-brokerage` in DataDownloadProvider

* refactor: initialize in BrokerageDataDownloader

* remove: not used `using` in Program's DataDownloadProvider

* remove: not used ref on QuantConnect.Queue proj

* refactor: use default market based on SecurityType

* refactor: MarketName in DataDownloadConfig struct
test:feat: validate MarketName

* feat: support Canonical Symbols in BrokerageDataDownloader

* remove: not used command arguments

* feat: init CacheProvider of IOptionChainProvider in Downloader

* feat: add brokerage message event in BrokerageDataDownloader
2024-07-31 19:02:13 -03:00
Jhonathan Abreu
9eb484625d Default option pricing models for options indicators (#8229)
* Set best recommended model based on option style.

The best option model will be used in options indicators based on option style if not specified

* Reduced Greeks/IV numerical models steps to 100

* Minor fixes

* Minor changes and improvements

* Changed default pricing model for IV

* Minor performance improvements

* Minor performance improvements and fixes

* Minor change

* Minor regression algorithm fix

* Update greek indicators internal IV indicator only when not user provided

* Revert unnecessary changes

* Minor changes

* Cleanup
2024-07-30 10:15:21 -04:00
FemtoTrader
85ca5be258 Implements new indicator - RSV - Rogers-Satchell volatility (#8183)
* implement Rogers-Satchell volatility

* naming RSVolat to avoid confusion between volume and volatility

* fix InitializeIndicator call

* fix AcceptsRenkoBarsAsInput test

* add symbol parameter to InitializeIndicator

* Update RogersSatchellVolatility.cs

* some fixes after review

* Return 0 when Open High Low or Close is 0

* IBaseDataBar
2024-07-29 14:47:16 -03:00
Martin-Molinero
9a84a6bd17 Minor test brokerage security provider improvement (#8231) 2024-07-29 13:41:37 -03:00
Martin-Molinero
a46acef9f8 Minor improvements (#8223)
- Liquidate takes into account invested flag
- Minor tweaks for symbol representation parsing
2024-07-23 12:18:26 -03:00
keshavdalmia10
69fa2fd689 Made changes in the ParseOptionTickerOSI function. Now it can handle … (#8219)
* Made changes in the ParseOptionTickerOSI function. Now it can handle both with and without space

* added new function GenerateOptionTickerOSICompact and added the test cases for it, expanded test cases for ParseOptionTickerOSI

* added assertions for strikePrice and date, corrected the indentation
2024-07-23 11:23:11 -03:00
Martin-Molinero
2df58bbca3 Accept live UniverseProvider returning null (#8222)
- Similar to HistoryProviders and Live DataQueueHandler calls, adjust
  live Universe provider manager to handle null returned values
2024-07-23 10:30:19 -03:00
Martin-Molinero
050030bca8 Minor improvement to Invested holdings flag (#8221) 2024-07-23 10:27:40 -03:00
FemtoTrader
7e40b4f1ab Implements new indicator - SOBV - Smoothed On Balance Volume (#8180)
* fix conflict

* fix all SmoothedOnBalanceVolumeTests tests except AcceptsRenkoBarsAsInput

* fix InitializeIndicator call

* fix AcceptsRenkoBarsAsInput test

* add symbol parameter to InitializeIndicator

* shorter
2024-07-22 18:27:52 -03:00
1121 changed files with 149080 additions and 12567 deletions

View File

@@ -1,4 +1,11 @@
<!--- This template provides sections for bugs and features. Please delete any irrelevant sections before submitting -->
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
#### Expected Behavior
<!--- Required. Describe the behavior you expect to see for your case. -->
@@ -24,4 +31,4 @@
<!--- Required for Bugs, feature request can delete the line below. -->
- [ ] I have provided detailed steps to reproduce the issue
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -0,0 +1,26 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
#### Expected Behavior
<!--- Required. Describe the behavior you expect to see for your case. -->
#### Actual Behavior
<!--- Required. Describe the actual behavior for your case. -->
#### Potential Solution
<!--- Optional. Describe any potential solutions and/or thoughts as to what may be causing the difference between expected and actual behavior. -->
#### Checklist
<!--- Confirm that you've provided all the required information. -->
<!--- Required fields --->
- [ ] I have completely filled out this template
- [ ] I have confirmed that this issue exists on the current `master` branch
- [ ] I have confirmed that this is not a duplicate issue by searching [issues](https://github.com/QuantConnect/Lean/issues)
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->

View File

@@ -9,14 +9,19 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
# Only run on push events (not on pull_request) for security reasons in order to be able to use secrets
if: ${{ github.event_name == 'push' }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- name: Run API Tests
uses: addnab/docker-run-action@v3
with:

View File

@@ -9,12 +9,18 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:

View File

@@ -7,7 +7,7 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
with:

View File

@@ -9,12 +9,17 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:

View File

@@ -9,12 +9,17 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:

View File

@@ -9,12 +9,17 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:
@@ -25,7 +30,7 @@ jobs:
# install dependencies
pip3 install papermill==2.4.0 clr-loader==0.1.6
# install kernel
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.340501
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.607001
# Add dotnet tools to Path
export PATH="$HOME/.dotnet/tools:$PATH"
# activate kernel for jupyter

View File

@@ -9,12 +9,17 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:
@@ -48,10 +53,10 @@ jobs:
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.TensorflowProbabilityTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run Hvplot Python Package Test
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.HvplotTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run Keras Python Package Test
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.KerasTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run Transformers
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Transformers" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.XTransformers" --blame-hang-timeout 120seconds --blame-crash && \
# Run Shap
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ShapTest" --blame-hang-timeout 120seconds --blame-crash
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ShapTest|KerasTest|PyvinecopulibTest" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Mlforecast" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.MlxtendTest|Thinc" --blame-hang-timeout 120seconds --blame-crash

View File

@@ -12,16 +12,16 @@ This document contains information regarding ways to use Visual Studio to work w
<h2>Option 1: Lean CLI</h2>
To use Lean CLI follow the instructions for installation and tutorial for usage in our [documentation](https://www.quantconnect.com/docs/v2/lean-cli/getting-started/lean-cli).
To use Lean CLI follow the instructions for installation and tutorial for usage in our [documentation](https://www.quantconnect.com/docs/v2/lean-cli/key-concepts/getting-started).
<br />
<h2>Option 2: Install Locally</h2>
1. Install [.Net 6](https://dotnet.microsoft.com/download) for the project
1. Install [.Net 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
2. (Optional) Get [Python 3.8.13](https://www.python.org/downloads/release/python-3813/) for running Python algorithms
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-38) for your platform
2. (Optional) Get [Python 3.11.11](https://www.python.org/downloads/release/python-31111/) for running Python algorithms
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-311) for your platform
3. Get [Visual Studio](https://visualstudio.microsoft.com/vs/)
@@ -35,7 +35,7 @@ Your environment is prepared and ready to run lean
<h1>How to use Lean</h1>
This section will cover configuring, launching and debugging lean. This is only applicable to option 2 from above. This does not apply to Lean CLI, please refer to [CLI documentation](https://www.quantconnect.com/docs/v2/lean-cli/getting-started/lean-cli)
This section will cover configuring, launching and debugging lean. This is only applicable to option 2 from above. This does not apply to Lean CLI, please refer to [CLI documentation](https://www.quantconnect.com/docs/v2/lean-cli/key-concepts/getting-started)
<br />

6
.vscode/readme.md vendored
View File

@@ -51,10 +51,10 @@ If you would like to mount any additional local files to your container, checkou
<h2>Option 3: Install Dependencies Locally</h2>
1. Install [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) for the project
1. Install [.NET 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
2. (Optional) Get [Python 3.8.13](https://www.python.org/downloads/release/python-3813/) for running Python algorithms
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-38) for your platform
2. (Optional) Get [Python 3.11.11](https://www.python.org/downloads/release/python-31111/) for running Python algorithms
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-311) for your platform
3. Get [Visual Studio Code](https://code.visualstudio.com/download)
- Get the Extension [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) for C# Debugging

View File

@@ -128,7 +128,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "9"},
{"Average Win", "0.86%"},
{"Average Loss", "-0.27%"},
{"Compounding Annual Return", "184.364%"},
{"Compounding Annual Return", "206.404%"},
{"Drawdown", "1.700%"},
{"Expectancy", "1.781"},
{"Start Equity", "100000"},
@@ -148,10 +148,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0.532"},
{"Treynor Ratio", "-1.174"},
{"Total Fees", "$14.78"},
{"Estimated Strategy Capacity", "$47000000.00"},
{"Estimated Strategy Capacity", "$120000000.00"},
{"Lowest Capacity Asset", "IBM R735QTJ8XC9X"},
{"Portfolio Turnover", "41.18%"},
{"OrderListHash", "d929e7959f079ad4fed42e8f3b35e39e"}
{"OrderListHash", "713c956deb193bed2290e9f379c0f9f9"}
};
}
}

View File

@@ -40,8 +40,8 @@ namespace QuantConnect.Algorithm.CSharp
var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
_contract = OptionChainProvider.GetOptionContractList(aapl, Time)
.OrderBy(symbol => symbol.ID.Symbol)
_contract = OptionChain(aapl)
.OrderBy(x => x.ID.Symbol)
.FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(_contract);
@@ -90,7 +90,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm

View File

@@ -39,8 +39,8 @@ namespace QuantConnect.Algorithm.CSharp
var aapl = AddEquity("AAPL").Symbol;
_contract = OptionChainProvider.GetOptionContractList(aapl, Time)
.OrderBy(symbol => symbol.ID.Symbol)
_contract = OptionChain(aapl)
.OrderBy(x => x.ID.Symbol)
.FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American);
}
@@ -87,7 +87,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm

View File

@@ -0,0 +1,151 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Brokerages;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression test to explain how Beta indicator works
/// </summary>
public class AddBetaIndicatorNewAssetsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Beta _beta;
private SimpleMovingAverage _sma;
private decimal _lastSMAValue;
public override void Initialize()
{
SetStartDate(2015, 05, 08);
SetEndDate(2017, 06, 15);
SetCash(10000);
AddCrypto("BTCUSD", Resolution.Daily);
AddEquity("SPY", Resolution.Daily);
EnableAutomaticIndicatorWarmUp = true;
_beta = B("BTCUSD", "SPY", 3, Resolution.Daily);
_sma = SMA("SPY", 3, Resolution.Daily);
_lastSMAValue = 0;
if (!_beta.IsReady)
{
throw new RegressionTestException("Beta indicator was expected to be ready");
}
}
public override void OnData(Slice slice)
{
var price = Securities["BTCUSD"].Price;
if (!Portfolio.Invested)
{
var quantityToBuy = (int)(Portfolio.Cash * 0.05m / price);
Buy("BTCUSD", quantityToBuy);
}
if (Math.Abs(_beta.Current.Value) > 2)
{
Liquidate("BTCUSD");
Log("Liquidated BTCUSD due to high Beta");
}
Log($"Beta between BTCUSD and SPY is: {_beta.Current.Value}");
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
var order = Transactions.GetOrderById(orderEvent.OrderId);
var goUpwards = _lastSMAValue < _sma.Current.Value;
_lastSMAValue = _sma.Current.Value;
if (order.Status == OrderStatus.Filled)
{
if (order.Type == OrderType.Limit && Math.Abs(_beta.Current.Value - 1) < 0.2m && goUpwards)
{
Transactions.CancelOpenOrders(order.Symbol);
}
}
if (order.Status == OrderStatus.Canceled)
{
Log(orderEvent.ToString());
}
}
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public virtual List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 5798;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 77;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "436"},
{"Average Win", "0.28%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "1.926%"},
{"Drawdown", "1.000%"},
{"Expectancy", "1.650"},
{"Start Equity", "10000.00"},
{"End Equity", "10411.11"},
{"Net Profit", "4.111%"},
{"Sharpe Ratio", "0.332"},
{"Sortino Ratio", "0.313"},
{"Probabilistic Sharpe Ratio", "74.084%"},
{"Loss Rate", "90%"},
{"Win Rate", "10%"},
{"Profit-Loss Ratio", "25.26"},
{"Alpha", "0.003"},
{"Beta", "0.001"},
{"Annual Standard Deviation", "0.01"},
{"Annual Variance", "0"},
{"Information Ratio", "-0.495"},
{"Tracking Error", "0.111"},
{"Treynor Ratio", "2.716"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$87000.00"},
{"Lowest Capacity Asset", "BTCUSD 2XR"},
{"Portfolio Turnover", "2.22%"},
{"OrderListHash", "4fcffc45d82203bb6ded8a0e86070b4f"}
};
}
}

View File

@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
if (!_beta.IsReady)
{
throw new RegressionTestException("_beta indicator was expected to be ready");
throw new RegressionTestException("Beta indicator was expected to be ready");
}
}
@@ -60,7 +60,7 @@ namespace QuantConnect.Algorithm.CSharp
LimitOrder("IBM", 10, price * 0.1m);
StopMarketOrder("IBM", 10, price / 0.1m);
}
if (_beta.Current.Value < 0m || _beta.Current.Value > 2.80m)
{
throw new RegressionTestException($"_beta value was expected to be between 0 and 2.80 but was {_beta.Current.Value}");

View File

@@ -115,7 +115,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 73;
public long DataPoints => 76;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -164,7 +164,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 311879;
public long DataPoints => 311881;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -49,7 +49,7 @@ namespace QuantConnect.Algorithm.CSharp
{
foreach (var contract in futuresContracts)
{
var option_contract_symbols = OptionChainProvider.GetOptionContractList(contract.Symbol, Time).ToList();
var option_contract_symbols = OptionChain(contract.Symbol).ToList();
if(option_contract_symbols.Count == 0)
{
continue;
@@ -93,7 +93,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 12169;
public long DataPoints => 12172;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -55,10 +55,10 @@ namespace QuantConnect.Algorithm.CSharp
{
_optionFilterRan = true;
var expiry = new HashSet<DateTime>(optionContracts.Select(x => x.Underlying.ID.Date)).SingleOrDefault();
// Cast to IEnumerable<Symbol> because OptionFilterContract overrides some LINQ operators like `Select` and `Where`
var expiry = new HashSet<DateTime>(optionContracts.Select(x => x.Symbol.Underlying.ID.Date)).SingleOrDefault();
// Cast to List<Symbol> because OptionFilterContract overrides some LINQ operators like `Select` and `Where`
// and cause it to mutate the underlying Symbol collection when using those operators.
var symbol = new HashSet<Symbol>(((IEnumerable<Symbol>)optionContracts).Select(x => x.Underlying)).SingleOrDefault();
var symbol = new HashSet<Symbol>(((List<Symbol>)optionContracts).Select(x => x.Underlying)).SingleOrDefault();
if (expiry == null || symbol == null)
{
@@ -220,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 608377;
public long DataPoints => 608380;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -46,8 +46,8 @@ namespace QuantConnect.Algorithm.CSharp
{
if (_option == null)
{
var option = OptionChainProvider.GetOptionContractList(_twx, Time)
.OrderBy(symbol => symbol.ID.Symbol)
var option = OptionChain(_twx)
.OrderBy(x => x.ID.Symbol)
.FirstOrDefault(optionContract => optionContract.ID.Date == _expiration
&& optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American);
@@ -122,7 +122,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm

View File

@@ -13,12 +13,12 @@
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect.Algorithm.CSharp
{
@@ -110,14 +110,14 @@ namespace QuantConnect.Algorithm.CSharp
foreach (var addedSecurity in changes.AddedSecurities)
{
var option = OptionChainProvider.GetOptionContractList(addedSecurity.Symbol, Time)
.OrderBy(symbol => symbol.ID.Symbol)
var option = OptionChain(addedSecurity.Symbol)
.OrderBy(contractData => contractData.ID.Symbol)
.First(optionContract => optionContract.ID.Date == _expiration
&& optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(option);
foreach (var symbol in new[] { option, option.Underlying })
foreach (var symbol in new[] { option.Symbol, option.UnderlyingSymbol })
{
var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList();
@@ -174,7 +174,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 2;
/// <summary>
/// Final status of the algorithm

View File

@@ -39,12 +39,12 @@ namespace QuantConnect.Algorithm.CSharp
UniverseSettings.MinimumTimeInUniverse = TimeSpan.Zero;
UniverseSettings.FillForward = false;
AddEquity("SPY", Resolution.Daily);
AddEquity("SPY", Resolution.Hour);
var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
_contract = OptionChainProvider.GetOptionContractList(aapl, Time)
.OrderBy(symbol => symbol.ID.StrikePrice)
_contract = OptionChain(aapl)
.OrderBy(x => x.ID.StrikePrice)
.FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(_contract);
@@ -116,12 +116,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 3930;
public long DataPoints => 3814;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm
@@ -135,13 +135,13 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-0.70%"},
{"Compounding Annual Return", "-47.178%"},
{"Average Loss", "-0.50%"},
{"Compounding Annual Return", "-39.406%"},
{"Drawdown", "0.700%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},
{"End Equity", "99303"},
{"Net Profit", "-0.697%"},
{"End Equity", "99498"},
{"Net Profit", "-0.502%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
@@ -156,10 +156,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0.008"},
{"Treynor Ratio", "0"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$6400000.00"},
{"Estimated Strategy Capacity", "$5000000.00"},
{"Lowest Capacity Asset", "AAPL VXBK4R62CXGM|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "22.80%"},
{"OrderListHash", "c2878a81bbb4e52c4fcd6a4f259abc3d"}
{"Portfolio Turnover", "22.70%"},
{"OrderListHash", "29fd1b75f6db05dd823a6db7e8bd90a9"}
};
}
}

View File

@@ -13,7 +13,6 @@
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.UniverseSelection;
@@ -59,19 +58,9 @@ namespace QuantConnect.Algorithm.CSharp
var changeOptions = changes.AddedSecurities.Concat(changes.RemovedSecurities)
.Where(s => s.Type == SecurityType.Option);
// Susbtract one minute to get the actual market open. If market open is at 9:30am, this will be invoked at 9:31am
var expectedTime = Time.TimeOfDay - TimeSpan.FromMinutes(1);
var allOptionsWereChangedOnMarketOpen = changeOptions.All(s =>
if (Time != Time.Date)
{
var firstMarketSegment = s.Exchange.Hours.MarketHours[Time.DayOfWeek].Segments
.First(segment => segment.State == MarketHoursState.Market);
return firstMarketSegment.Start == expectedTime;
});
if (!allOptionsWereChangedOnMarketOpen)
{
throw new RegressionTestException("Expected options filter to be run only on market open");
throw new RegressionTestException($"Expected options filter to be run only at midnight. Actual was {Time}");
}
}
@@ -88,7 +77,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all time slices of algorithm
/// </summary>
public long DataPoints => 5952220;
public long DataPoints => 470217;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -35,14 +35,15 @@ namespace QuantConnect.Algorithm.CSharp
private readonly HashSet<Symbol> _expectedData = new HashSet<Symbol>();
private readonly HashSet<Symbol> _expectedUniverses = new HashSet<Symbol>();
private bool _expectUniverseSubscription;
private DateTime _universeSubscriptionTime;
// order of expected contract additions as price moves
private int _expectedContractIndex;
private readonly List<Symbol> _expectedContracts = new List<Symbol>
{
SymbolRepresentation.ParseOptionTickerOSI("GOOG 151224P00747500"),
SymbolRepresentation.ParseOptionTickerOSI("GOOG 151224P00750000"),
SymbolRepresentation.ParseOptionTickerOSI("GOOG 151224P00752500")
SymbolRepresentation.ParseOptionTickerOSI("GOOG 151224P00752500"),
SymbolRepresentation.ParseOptionTickerOSI("GOOG 151224P00755000")
};
public override void Initialize()
@@ -68,7 +69,7 @@ namespace QuantConnect.Algorithm.CSharp
Log($"SubscriptionManager.Subscriptions: {string.Join(" -- ", SubscriptionManager.Subscriptions)}");
throw new RegressionTestException($"Unexpected {OptionChainSymbol} subscription presence");
}
if (!slice.ContainsKey(Underlying))
if (Time != _universeSubscriptionTime && !slice.ContainsKey(Underlying))
{
// TODO : In fact, we're unable to properly detect whether or not we auto-added or it was manually added
// this is because when we auto-add the underlying we don't mark it as an internal security like we do with other auto adds
@@ -91,7 +92,7 @@ namespace QuantConnect.Algorithm.CSharp
var actual = string.Join(Environment.NewLine, UniverseManager.Keys.OrderBy(s => s.ToString()));
throw new RegressionTestException($"{Time}:: Detected differences in expected and actual universes{Environment.NewLine}Expected:{Environment.NewLine}{expected}{Environment.NewLine}Actual:{Environment.NewLine}{actual}");
}
if (_expectedData.AreDifferent(slice.Keys.ToHashSet()))
if (Time != _universeSubscriptionTime && _expectedData.AreDifferent(slice.Keys.ToHashSet()))
{
var expected = string.Join(Environment.NewLine, _expectedData.OrderBy(s => s.ToString()));
var actual = string.Join(Environment.NewLine, slice.Keys.OrderBy(s => s.ToString()));
@@ -99,7 +100,7 @@ namespace QuantConnect.Algorithm.CSharp
}
// 10AM add GOOG option chain
if (Time.TimeOfDay.Hours == 10 && Time.TimeOfDay.Minutes == 0)
if (Time.TimeOfDay.Hours == 10 && Time.TimeOfDay.Minutes == 0 && !_expectUniverseSubscription)
{
if (Securities.ContainsKey(OptionChainSymbol))
{
@@ -110,9 +111,9 @@ namespace QuantConnect.Algorithm.CSharp
googOptionChain.SetFilter(u =>
{
// we added the universe at 10, the universe selection data should not be from before
if (u.Underlying.EndTime.Hour < 10)
if (u.LocalTime.Hour < 10)
{
throw new RegressionTestException($"Unexpected underlying data point {u.Underlying.EndTime} {u.Underlying}");
throw new RegressionTestException($"Unexpected selection time {u.LocalTime}");
}
// find first put above market price
return u.IncludeWeeklys()
@@ -124,6 +125,7 @@ namespace QuantConnect.Algorithm.CSharp
_expectedSecurities.Add(OptionChainSymbol);
_expectedUniverses.Add(OptionChainSymbol);
_expectUniverseSubscription = true;
_universeSubscriptionTime = Time;
}
// 11:30AM remove GOOG option chain
@@ -151,7 +153,7 @@ namespace QuantConnect.Algorithm.CSharp
var expectedContract = _expectedContracts[_expectedContractIndex];
if (added.Symbol != expectedContract)
{
throw new RegressionTestException($"Expected option contract {expectedContract} to be added but received {added.Symbol}");
throw new RegressionTestException($"Expected option contract {expectedContract.Value} to be added but received {added.Symbol}");
}
_expectedContractIndex++;
@@ -186,7 +188,7 @@ namespace QuantConnect.Algorithm.CSharp
if (Securities.ContainsKey(Underlying))
{
Console.WriteLine($"{Time:o}:: PRICE:: {Securities[Underlying].Price} CHANGES:: {changes}");
Log($"{Time:o}:: PRICE:: {Securities[Underlying].Price} CHANGES:: {changes}");
}
}
@@ -203,7 +205,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 200807;
public long DataPoints => 3502;
/// <summary>
/// Data Points count of the algorithm history
@@ -227,7 +229,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "99079"},
{"End Equity", "98784"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
@@ -243,10 +245,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$6.00"},
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBR0BSWIX2|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "1.49%"},
{"OrderListHash", "bd115ec8bb7734b1561d6a6cc6c00039"}
{"Estimated Strategy Capacity", "$4000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ2BZBZT2|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "2.58%"},
{"OrderListHash", "09f766c470a8bcf4bb6862da52bf25a7"}
};
}
}

View File

@@ -59,7 +59,7 @@ namespace QuantConnect.Algorithm.CSharp
var ticket = MarketOrder("AIG", 1);
if (ticket.Status != OrderStatus.Invalid)
if (ticket.Status != OrderStatus.Invalid || aig.HasData || aig.Price != 0)
{
throw new RegressionTestException("Expected order to always be invalid because there is no data yet!");
}

View File

@@ -41,8 +41,8 @@ namespace QuantConnect.Algorithm.CSharp
var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
var contracts = OptionChainProvider.GetOptionContractList(aapl, Time)
.OrderBy(symbol => symbol.ID.StrikePrice)
var contracts = OptionChain(aapl)
.OrderBy(x => x.ID.StrikePrice)
.Where(optionContract => optionContract.ID.OptionRight == OptionRight.Call
&& optionContract.ID.OptionStyle == OptionStyle.American)
.Take(2)
@@ -106,7 +106,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm

View File

@@ -81,7 +81,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 53;
public long DataPoints => 50;
/// <summary>
/// Data Points count of the algorithm history
@@ -98,33 +98,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "10"},
{"Average Win", "0%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-14.233%"},
{"Drawdown", "3.300%"},
{"Expectancy", "-1"},
{"Total Orders", "6"},
{"Average Win", "0.01%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "1296.838%"},
{"Drawdown", "0.400%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "99831.88"},
{"Net Profit", "-0.168%"},
{"Sharpe Ratio", "62.464"},
{"End Equity", "102684.23"},
{"Net Profit", "2.684%"},
{"Sharpe Ratio", "34.319"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "1.117"},
{"Beta", "1.19"},
{"Annual Standard Deviation", "0.213"},
{"Annual Variance", "0.046"},
{"Information Ratio", "70.778"},
{"Tracking Error", "0.043"},
{"Treynor Ratio", "11.2"},
{"Total Fees", "$22.21"},
{"Estimated Strategy Capacity", "$340000000.00"},
{"Alpha", "-5.738"},
{"Beta", "1.381"},
{"Annual Standard Deviation", "0.246"},
{"Annual Variance", "0.06"},
{"Information Ratio", "-26.937"},
{"Tracking Error", "0.068"},
{"Treynor Ratio", "6.106"},
{"Total Fees", "$18.61"},
{"Estimated Strategy Capacity", "$980000000.00"},
{"Lowest Capacity Asset", "FB V6OIPNZEM8V9"},
{"Portfolio Turnover", "26.92%"},
{"OrderListHash", "3832790c7dd9d50805b6206129b01110"}
{"Portfolio Turnover", "25.56%"},
{"OrderListHash", "5ee20c8556d706ab0a63ae41b6579c62"}
};
}
}

View File

@@ -92,7 +92,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 234018;
public long DataPoints => 234015;
/// <summary>
/// Data Points count of the algorithm history
@@ -109,33 +109,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "23"},
{"Average Win", "0.00%"},
{"Total Orders", "21"},
{"Average Win", "0.01%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-75.275%"},
{"Drawdown", "5.800%"},
{"Expectancy", "-0.609"},
{"Compounding Annual Return", "-77.566%"},
{"Drawdown", "6.000%"},
{"Expectancy", "-0.811"},
{"Start Equity", "100000"},
{"End Equity", "94419.21"},
{"Net Profit", "-5.581%"},
{"Sharpe Ratio", "-3.288"},
{"Sortino Ratio", "-3.828"},
{"Probabilistic Sharpe Ratio", "5.546%"},
{"Loss Rate", "73%"},
{"Win Rate", "27%"},
{"Profit-Loss Ratio", "0.43"},
{"Alpha", "-0.495"},
{"Beta", "1.484"},
{"Annual Standard Deviation", "0.196"},
{"Annual Variance", "0.039"},
{"Information Ratio", "-3.843"},
{"Tracking Error", "0.141"},
{"Treynor Ratio", "-0.435"},
{"Total Fees", "$31.25"},
{"Estimated Strategy Capacity", "$550000000.00"},
{"End Equity", "94042.73"},
{"Net Profit", "-5.957%"},
{"Sharpe Ratio", "-3.345"},
{"Sortino Ratio", "-3.766"},
{"Probabilistic Sharpe Ratio", "4.557%"},
{"Loss Rate", "89%"},
{"Win Rate", "11%"},
{"Profit-Loss Ratio", "0.70"},
{"Alpha", "-0.519"},
{"Beta", "1.491"},
{"Annual Standard Deviation", "0.2"},
{"Annual Variance", "0.04"},
{"Information Ratio", "-3.878"},
{"Tracking Error", "0.147"},
{"Treynor Ratio", "-0.449"},
{"Total Fees", "$29.11"},
{"Estimated Strategy Capacity", "$680000000.00"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "7.33%"},
{"OrderListHash", "2add92a1f922c6730d8c20ff65934a46"}
{"Portfolio Turnover", "7.48%"},
{"OrderListHash", "2c814c55e7d7c56482411c065b861b33"}
};
}
}

View File

@@ -238,7 +238,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 37748;
public long DataPoints => 36573;
/// <summary>
/// Data Points count of the algorithm history
@@ -255,33 +255,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Total Orders", "8"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "19.147%"},
{"Drawdown", "0%"},
{"Compounding Annual Return", "11.027%"},
{"Drawdown", "0.000%"},
{"Expectancy", "0"},
{"Start Equity", "10000000"},
{"End Equity", "10019217.27"},
{"Net Profit", "0.192%"},
{"Sharpe Ratio", "15.743"},
{"End Equity", "10011469.88"},
{"Net Profit", "0.115%"},
{"Sharpe Ratio", "11.963"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.17"},
{"Beta", "0.037"},
{"Annual Standard Deviation", "0.01"},
{"Alpha", "0.07"},
{"Beta", "-0.077"},
{"Annual Standard Deviation", "0.008"},
{"Annual Variance", "0"},
{"Information Ratio", "5"},
{"Tracking Error", "0.094"},
{"Treynor Ratio", "4.278"},
{"Total Fees", "$307.50"},
{"Estimated Strategy Capacity", "$2600000.00"},
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "10.61%"},
{"OrderListHash", "854d4ba6a4ae39f9be2f9a10c8544fe5"}
{"Information Ratio", "3.876"},
{"Tracking Error", "0.105"},
{"Treynor Ratio", "-1.215"},
{"Total Fees", "$282.50"},
{"Estimated Strategy Capacity", "$61000000000.00"},
{"Lowest Capacity Asset", "NB R735QTJ8XC9X"},
{"Portfolio Turnover", "3.62%"},
{"OrderListHash", "0ea806c53bfa2bdca2504ba7155ef130"}
};
}
}

View File

@@ -93,33 +93,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "52"},
{"Total Orders", "53"},
{"Average Win", "0.00%"},
{"Average Loss", "0.00%"},
{"Compounding Annual Return", "0.096%"},
{"Compounding Annual Return", "0.076%"},
{"Drawdown", "0.100%"},
{"Expectancy", "3.321"},
{"Expectancy", "2.933"},
{"Start Equity", "100000"},
{"End Equity", "100089.09"},
{"Net Profit", "0.089%"},
{"Sharpe Ratio", "-8.214"},
{"Sortino Ratio", "-9.025"},
{"Probabilistic Sharpe Ratio", "40.893%"},
{"Loss Rate", "24%"},
{"Win Rate", "76%"},
{"Profit-Loss Ratio", "4.67"},
{"End Equity", "100070.90"},
{"Net Profit", "0.071%"},
{"Sharpe Ratio", "-9.164"},
{"Sortino Ratio", "-9.852"},
{"Probabilistic Sharpe Ratio", "36.417%"},
{"Loss Rate", "27%"},
{"Win Rate", "73%"},
{"Profit-Loss Ratio", "4.41"},
{"Alpha", "-0.008"},
{"Beta", "0.008"},
{"Annual Standard Deviation", "0.001"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.961"},
{"Tracking Error", "0.092"},
{"Treynor Ratio", "-0.826"},
{"Total Fees", "$52.00"},
{"Estimated Strategy Capacity", "$32000000000.00"},
{"Treynor Ratio", "-0.911"},
{"Total Fees", "$53.00"},
{"Estimated Strategy Capacity", "$16000000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "0.02%"},
{"OrderListHash", "fab920b5fc92a6e14d8128564249fbfa"}
{"OrderListHash", "685c37df6e4c49b75792c133be189094"}
};
}
}

View File

@@ -82,7 +82,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 21;
public int AlgorithmHistoryDataPoints => 18;
/// <summary>
/// Final status of the algorithm

View File

@@ -296,7 +296,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1267414;
public long DataPoints => 27071;
/// <summary>
/// Data Points count of the algorithm history
@@ -316,7 +316,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "3"},
{"Average Win", "0%"},
{"Average Loss", "-0.40%"},
{"Compounding Annual Return", "-22.717%"},
{"Compounding Annual Return", "-21.378%"},
{"Drawdown", "0.400%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},

View File

@@ -118,7 +118,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 713369;
public long DataPoints => 713375;
/// <summary>
/// Data Points count of the algorithm history
@@ -136,32 +136,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "2.90%"},
{"Average Win", "2.48%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "13.087%"},
{"Drawdown", "1.100%"},
{"Compounding Annual Return", "11.325%"},
{"Drawdown", "1.500%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "106387.1"},
{"Net Profit", "6.387%"},
{"Sharpe Ratio", "1.532"},
{"Sortino Ratio", "871.704"},
{"Probabilistic Sharpe Ratio", "90.613%"},
{"End Equity", "105549.6"},
{"Net Profit", "5.550%"},
{"Sharpe Ratio", "1.332"},
{"Sortino Ratio", "879.904"},
{"Probabilistic Sharpe Ratio", "79.894%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.088"},
{"Beta", "-0.022"},
{"Annual Standard Deviation", "0.054"},
{"Alpha", "0.075"},
{"Beta", "-0.017"},
{"Annual Standard Deviation", "0.053"},
{"Annual Variance", "0.003"},
{"Information Ratio", "-1.35"},
{"Tracking Error", "0.1"},
{"Treynor Ratio", "-3.781"},
{"Information Ratio", "-1.48"},
{"Tracking Error", "0.099"},
{"Treynor Ratio", "-4.187"},
{"Total Fees", "$10.75"},
{"Estimated Strategy Capacity", "$1100000000.00"},
{"Estimated Strategy Capacity", "$7100000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.32%"},
{"OrderListHash", "2f6afca6b20a56eea9dd327dcb401682"}
{"Portfolio Turnover", "2.33%"},
{"OrderListHash", "9c524830ffc7354327638142ae62acd2"}
};
}
}

View File

@@ -123,7 +123,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 2217299;
public long DataPoints => 2217330;
/// <summary>
/// Data Points count of the algorithm history
@@ -141,32 +141,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "4.45%"},
{"Average Loss", "-0.26%"},
{"Compounding Annual Return", "8.423%"},
{"Drawdown", "0.800%"},
{"Expectancy", "8.202"},
{"Average Win", "2.86%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "12.959%"},
{"Drawdown", "1.100%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "104162.1"},
{"Net Profit", "4.162%"},
{"Sharpe Ratio", "0.951"},
{"Sortino Ratio", "2.8"},
{"Probabilistic Sharpe Ratio", "53.568%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "17.40"},
{"Alpha", "0.053"},
{"Beta", "-0.005"},
{"Annual Standard Deviation", "0.054"},
{"End Equity", "106337.1"},
{"Net Profit", "6.337%"},
{"Sharpe Ratio", "1.41"},
{"Sortino Ratio", "1.242"},
{"Probabilistic Sharpe Ratio", "77.992%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.071"},
{"Beta", "0.054"},
{"Annual Standard Deviation", "0.059"},
{"Annual Variance", "0.003"},
{"Information Ratio", "-1.681"},
{"Tracking Error", "0.099"},
{"Treynor Ratio", "-10.255"},
{"Information Ratio", "-1.392"},
{"Tracking Error", "0.097"},
{"Treynor Ratio", "1.518"},
{"Total Fees", "$10.75"},
{"Estimated Strategy Capacity", "$190000000.00"},
{"Estimated Strategy Capacity", "$890000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.34%"},
{"OrderListHash", "f34d9277d1d81a8125879f5ff8202626"}
{"Portfolio Turnover", "2.32%"},
{"OrderListHash", "f60fc7dcba2c1ff077afeb191aee5008"}
};
}
}

View File

@@ -167,11 +167,7 @@ namespace QuantConnect.Algorithm.CSharp
{
if (Portfolio.CashBook["LTC"].Amount > 0)
{
// The following two statements currently behave differently if we have initial holdings:
// https://github.com/QuantConnect/Lean/issues/1860
Liquidate("LTCUSD");
// SetHoldings("LTCUSD", 0);
}
}
}

View File

@@ -66,7 +66,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 73;
public long DataPoints => 72;
/// <summary>
/// Data Points count of the algorithm history
@@ -86,30 +86,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "246.546%"},
{"Drawdown", "1.200%"},
{"Compounding Annual Return", "424.375%"},
{"Drawdown", "0.800%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "103463.69"},
{"Net Profit", "3.464%"},
{"Sharpe Ratio", "19.094"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "97.754%"},
{"End Equity", "104486.22"},
{"Net Profit", "4.486%"},
{"Sharpe Ratio", "17.304"},
{"Sortino Ratio", "35.217"},
{"Probabilistic Sharpe Ratio", "96.835%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.005"},
{"Beta", "0.998"},
{"Annual Standard Deviation", "0.138"},
{"Annual Variance", "0.019"},
{"Information Ratio", "-34.028"},
{"Tracking Error", "0"},
{"Treynor Ratio", "2.644"},
{"Total Fees", "$3.45"},
{"Estimated Strategy Capacity", "$970000000.00"},
{"Alpha", "-0.249"},
{"Beta", "1.015"},
{"Annual Standard Deviation", "0.141"},
{"Annual Variance", "0.02"},
{"Information Ratio", "-19"},
{"Tracking Error", "0.011"},
{"Treynor Ratio", "2.403"},
{"Total Fees", "$3.49"},
{"Estimated Strategy Capacity", "$1200000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "10.09%"},
{"OrderListHash", "39a84b9f15bb4e8ead0f0ecb59f28562"}
{"Portfolio Turnover", "10.01%"},
{"OrderListHash", "70f21e930175a2ec9d465b21edc1b6d9"}
};
}
}

View File

@@ -0,0 +1,239 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests and demonstrates EUREX futures subscription and trading:
/// - It tests contracts rollover by adding a continuous future and asserting that mapping happens at some point.
/// - It tests basic trading by buying a contract and holding it until expiration.
/// - It tests delisting and asserts the holdings are liquidated after that.
/// </summary>
public class BasicTemplateEurexFuturesAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Future _continuousContract;
private Symbol _mappedSymbol;
private Symbol _contractToTrade;
private int _mappingsCount;
private decimal _boughtQuantity;
private decimal _liquidatedQuantity;
private bool _delisted;
public override void Initialize()
{
SetStartDate(2024, 5, 30);
SetEndDate(2024, 6, 23);
SetAccountCurrency(Currencies.EUR);
SetCash(1000000);
_continuousContract = AddFuture(Futures.Indices.EuroStoxx50, Resolution.Minute,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.FirstDayMonth,
contractDepthOffset: 0);
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
_mappedSymbol = _continuousContract.Mapped;
var benchmark = AddIndex("SX5E");
SetBenchmark(benchmark.Symbol);
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(security => seeder.SeedSecurity(security));
}
public override void OnData(Slice slice)
{
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
if (++_mappingsCount > 1)
{
throw new RegressionTestException($"{Time} - Unexpected number of symbol changed events (mappings): {_mappingsCount}. " +
$"Expected only 1.");
}
Debug($"{Time} - SymbolChanged event: {changedEvent}");
if (changedEvent.OldSymbol != _mappedSymbol.ID.ToString())
{
throw new RegressionTestException($"{Time} - Unexpected symbol changed event old symbol: {changedEvent}");
}
if (changedEvent.NewSymbol != _continuousContract.Mapped.ID.ToString())
{
throw new RegressionTestException($"{Time} - Unexpected symbol changed event new symbol: {changedEvent}");
}
// Let's trade the previous mapped contract, so we can hold it until expiration for testing
// (will be sooner than the new mapped contract)
_contractToTrade = _mappedSymbol;
_mappedSymbol = _continuousContract.Mapped;
}
// Let's trade after the mapping is done
if (_contractToTrade != null && _boughtQuantity == 0 && Securities[_contractToTrade].Exchange.ExchangeOpen)
{
Buy(_contractToTrade, 1);
}
if (_contractToTrade != null && slice.Delistings.TryGetValue(_contractToTrade, out var delisting))
{
if (delisting.Type == DelistingType.Delisted)
{
_delisted = true;
if (Portfolio.Invested)
{
throw new RegressionTestException($"{Time} - Portfolio should not be invested after the traded contract is delisted.");
}
}
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
if (orderEvent.Symbol != _contractToTrade)
{
throw new RegressionTestException($"{Time} - Unexpected order event symbol: {orderEvent.Symbol}. Expected {_contractToTrade}");
}
if (orderEvent.Direction == OrderDirection.Buy)
{
if (orderEvent.Status == OrderStatus.Filled)
{
if (_boughtQuantity != 0 && _liquidatedQuantity != 0)
{
throw new RegressionTestException($"{Time} - Unexpected buy order event status: {orderEvent.Status}");
}
_boughtQuantity = orderEvent.Quantity;
}
}
else if (orderEvent.Direction == OrderDirection.Sell)
{
if (orderEvent.Status == OrderStatus.Filled)
{
if (_boughtQuantity <= 0 && _liquidatedQuantity != 0)
{
throw new RegressionTestException($"{Time} - Unexpected sell order event status: {orderEvent.Status}");
}
_liquidatedQuantity = orderEvent.Quantity;
if (_liquidatedQuantity != -_boughtQuantity)
{
throw new RegressionTestException($"{Time} - Unexpected liquidated quantity: {_liquidatedQuantity}. Expected: {-_boughtQuantity}");
}
}
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
foreach (var addedSecurity in changes.AddedSecurities)
{
if (addedSecurity.Symbol.SecurityType == SecurityType.Future && addedSecurity.Symbol.IsCanonical())
{
_mappedSymbol = _continuousContract.Mapped;
}
}
}
public override void OnEndOfAlgorithm()
{
if (_mappingsCount == 0)
{
throw new RegressionTestException($"Unexpected number of symbol changed events (mappings): {_mappingsCount}. Expected 1.");
}
if (!_delisted)
{
throw new RegressionTestException("Contract was not delisted");
}
// Make sure we traded and that the position was liquidated on delisting
if (_boughtQuantity <= 0 || _liquidatedQuantity >= 0)
{
throw new RegressionTestException($"Unexpected sold quantity: {_boughtQuantity} and liquidated quantity: {_liquidatedQuantity}");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 133947;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 26;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-0.11%"},
{"Compounding Annual Return", "-1.667%"},
{"Drawdown", "0.100%"},
{"Expectancy", "-1"},
{"Start Equity", "1000000"},
{"End Equity", "998849.48"},
{"Net Profit", "-0.115%"},
{"Sharpe Ratio", "-34.455"},
{"Sortino Ratio", "-57.336"},
{"Probabilistic Sharpe Ratio", "0.002%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0.002"},
{"Annual Variance", "0"},
{"Information Ratio", "-6.176"},
{"Tracking Error", "0.002"},
{"Treynor Ratio", "0"},
{"Total Fees", "€1.02"},
{"Estimated Strategy Capacity", "€2300000000.00"},
{"Lowest Capacity Asset", "FESX YJHOAMPYKRS5"},
{"Portfolio Turnover", "0.40%"},
{"OrderListHash", "54040d29a467becaedcf59d79323321b"}
};
}
}

View File

@@ -13,6 +13,7 @@
* limitations under the License.
*/
using QuantConnect.Data;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
@@ -41,8 +42,8 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">TradeBars IDictionary object with your stock data</param>
public void OnData(TradeBars data)
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{

View File

@@ -176,12 +176,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1325;
public long DataPoints => 1185;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 4;
public int AlgorithmHistoryDataPoints => 2;
/// <summary>
/// Final status of the algorithm
@@ -193,33 +193,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0.53%"},
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "3.011%"},
{"Compounding Annual Return", "-0.010%"},
{"Drawdown", "0.000%"},
{"Expectancy", "0"},
{"Start Equity", "1000000"},
{"End Equity", "1005283.2"},
{"Net Profit", "0.528%"},
{"Sharpe Ratio", "1.285"},
{"End Equity", "999983.2"},
{"Net Profit", "-0.002%"},
{"Sharpe Ratio", "-225.214"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "83.704%"},
{"Probabilistic Sharpe Ratio", "0.135%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.015"},
{"Beta", "-0.004"},
{"Annual Standard Deviation", "0.011"},
{"Alpha", "-0.008"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "-4.774"},
{"Tracking Error", "0.084"},
{"Treynor Ratio", "-3.121"},
{"Total Fees", "$4.30"},
{"Estimated Strategy Capacity", "$5900000000.00"},
{"Information Ratio", "-5.146"},
{"Tracking Error", "0.083"},
{"Treynor Ratio", "-542.359"},
{"Total Fees", "$2.15"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "0.27%"},
{"OrderListHash", "90f952729deb9cb20be75867576e5b87"}
{"Portfolio Turnover", "0.13%"},
{"OrderListHash", "7c8700a9baa24f6f76d866e7d88cc19c"}
};
}
}

View File

@@ -83,7 +83,7 @@ namespace QuantConnect.Algorithm.CSharp
// if found, trade it.
// Also check if exchange is open for regular or extended hours. Since daily data comes at 8PM, this allows us prevent the
// algorithm from trading on friday when there is not after-market.
if (contract != null && Securities[contract.Symbol].Exchange.Hours.IsOpen(Time, true))
if (contract != null)
{
MarketOrder(contract.Symbol, 1);
}
@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 13934;
public virtual long DataPoints => 12474;
/// <summary>
/// Data Points count of the algorithm history
@@ -134,33 +134,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "128"},
{"Average Win", "0.26%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-0.071%"},
{"Drawdown", "0.400%"},
{"Expectancy", "-0.116"},
{"Total Orders", "34"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.106%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.178"},
{"Start Equity", "1000000"},
{"End Equity", "999287.06"},
{"Net Profit", "-0.071%"},
{"Sharpe Ratio", "-1.999"},
{"Sortino Ratio", "-1.806"},
{"Probabilistic Sharpe Ratio", "10.091%"},
{"Loss Rate", "97%"},
{"Win Rate", "3%"},
{"Profit-Loss Ratio", "27.29"},
{"Alpha", "-0.008"},
{"Beta", "0.001"},
{"End Equity", "1001066.2"},
{"Net Profit", "0.107%"},
{"Sharpe Ratio", "-1.695"},
{"Sortino Ratio", "-0.804"},
{"Probabilistic Sharpe Ratio", "14.797%"},
{"Loss Rate", "88%"},
{"Win Rate", "12%"},
{"Profit-Loss Ratio", "9.01"},
{"Alpha", "-0.007"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.367"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-5.445"},
{"Total Fees", "$285.44"},
{"Estimated Strategy Capacity", "$1000.00"},
{"Treynor Ratio", "-4.112"},
{"Total Fees", "$76.30"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "3.41%"},
{"OrderListHash", "394c47e4e0f54c5981d7c8aa99e9bc83"}
{"Portfolio Turnover", "0.92%"},
{"OrderListHash", "9507abc8348ff3cb1e2a9a5f48d128a7"}
};
}
}

View File

@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 163415;
public override long DataPoints => 163416;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm

View File

@@ -41,40 +41,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 87289;
public override long DataPoints => 87292;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "638"},
{"Average Win", "0.02%"},
{"Total Orders", "716"},
{"Average Win", "0.03%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-1.610%"},
{"Drawdown", "1.600%"},
{"Expectancy", "-0.841"},
{"Compounding Annual Return", "-1.716%"},
{"Drawdown", "1.700%"},
{"Expectancy", "-0.770"},
{"Start Equity", "1000000"},
{"End Equity", "983783.82"},
{"Net Profit", "-1.622%"},
{"Sharpe Ratio", "-8.787"},
{"Sortino Ratio", "-5.428"},
{"End Equity", "982718.38"},
{"Net Profit", "-1.728%"},
{"Sharpe Ratio", "-8.845"},
{"Sortino Ratio", "-5.449"},
{"Probabilistic Sharpe Ratio", "0.000%"},
{"Loss Rate", "96%"},
{"Win Rate", "4%"},
{"Profit-Loss Ratio", "3.21"},
{"Profit-Loss Ratio", "4.89"},
{"Alpha", "-0.018"},
{"Beta", "-0.003"},
{"Beta", "-0.002"},
{"Annual Standard Deviation", "0.002"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.473"},
{"Information Ratio", "-1.483"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "5.593"},
{"Total Fees", "$1456.18"},
{"Estimated Strategy Capacity", "$9000.00"},
{"Treynor Ratio", "9.102"},
{"Total Fees", "$1634.12"},
{"Estimated Strategy Capacity", "$8000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "17.91%"},
{"OrderListHash", "b5214a0fcd0694093aa2a478a983de1a"}
{"Portfolio Turnover", "20.10%"},
{"OrderListHash", "aa7e574f86b70428ca0afae381be80ba"}
};
}
}

View File

@@ -14,14 +14,7 @@
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
@@ -43,40 +36,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 16161;
public override long DataPoints => 14182;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "156"},
{"Average Win", "0.31%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-0.024%"},
{"Drawdown", "0.400%"},
{"Expectancy", "-0.035"},
{"Total Orders", "32"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.184"},
{"Start Equity", "1000000"},
{"End Equity", "999754.94"},
{"Net Profit", "-0.025%"},
{"Sharpe Ratio", "-1.602"},
{"Sortino Ratio", "-1.913"},
{"Probabilistic Sharpe Ratio", "11.172%"},
{"Loss Rate", "97%"},
{"Win Rate", "3%"},
{"Profit-Loss Ratio", "36.65"},
{"End Equity", "1001108"},
{"Net Profit", "0.111%"},
{"Sharpe Ratio", "-1.688"},
{"Sortino Ratio", "-0.772"},
{"Probabilistic Sharpe Ratio", "14.944%"},
{"Loss Rate", "88%"},
{"Win Rate", "12%"},
{"Profit-Loss Ratio", "8.47"},
{"Alpha", "-0.007"},
{"Beta", "-0.001"},
{"Annual Standard Deviation", "0.005"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.359"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "8.008"},
{"Total Fees", "$347.56"},
{"Estimated Strategy Capacity", "$1000.00"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "4.16%"},
{"OrderListHash", "52580f1e94ab1875301d3bbd157f4580"}
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "ea6fdf3133bde7063e4fc0fa809ae260"}
};
}
}

View File

@@ -41,24 +41,24 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 228834;
public override long DataPoints => 228941;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "1990"},
{"Total Orders", "1992"},
{"Average Win", "0.01%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-4.683%"},
{"Compounding Annual Return", "-4.687%"},
{"Drawdown", "4.700%"},
{"Expectancy", "-0.911"},
{"Start Equity", "1000000"},
{"End Equity", "952831.02"},
{"Net Profit", "-4.717%"},
{"Sharpe Ratio", "-7.178"},
{"Sortino Ratio", "-5.126"},
{"End Equity", "952789.22"},
{"Net Profit", "-4.721%"},
{"Sharpe Ratio", "-7.183"},
{"Sortino Ratio", "-5.14"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "97%"},
{"Win Rate", "3%"},
@@ -69,12 +69,12 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0"},
{"Information Ratio", "-1.702"},
{"Tracking Error", "0.09"},
{"Treynor Ratio", "5.049"},
{"Total Fees", "$4538.98"},
{"Treynor Ratio", "5.054"},
{"Total Fees", "$4543.28"},
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "56.68%"},
{"OrderListHash", "60f85901ecc345e597c0153506792285"}
{"Portfolio Turnover", "56.73%"},
{"OrderListHash", "424536177e9be5895bab50638ef43a9d"}
};
}
}

View File

@@ -61,8 +61,8 @@ namespace QuantConnect.Algorithm.CSharp
AddIndexOptionContract(SpxOption, Resolution);
_emaSlow = EMA(Spx, 80);
_emaFast = EMA(Spx, 200);
_emaSlow = EMA(Spx, Resolution > Resolution.Minute ? 6 : 80);
_emaFast = EMA(Spx, Resolution > Resolution.Minute ? 2 : 200);
Settings.DailyPreciseEndTime = true;
}
@@ -93,12 +93,25 @@ namespace QuantConnect.Algorithm.CSharp
}
}
/// <summary>
/// Asserts indicators are ready
/// </summary>
/// <exception cref="RegressionTestException"></exception>
protected void AssertIndicators()
{
if (!_emaSlow.IsReady || !_emaFast.IsReady)
{
throw new RegressionTestException("Indicators are not ready!");
}
}
public override void OnEndOfAlgorithm()
{
if (Portfolio[Spx].TotalSaleVolume > 0)
{
throw new RegressionTestException("Index is not tradable.");
}
AssertIndicators();
}
/// <summary>

View File

@@ -62,6 +62,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new ArgumentException($"Bar Count {BarCounter} is not expected count of {ExpectedBarCount}");
}
AssertIndicators();
if (Resolution != Resolution.Daily)
{
@@ -69,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
}
var openInterest = Securities[SpxOption].Cache.GetAll<OpenInterest>();
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 23, 0, 0))
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 15, 15, 0))
{
throw new ArgumentException($"Unexpected open interest time: {openInterest.Single().EndTime}");
}
@@ -105,7 +106,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 121;
public override long DataPoints => 122;
/// <summary>
/// Data Points count of the algorithm history
@@ -125,7 +126,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "11"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "621.484%"},
{"Compounding Annual Return", "653.545%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "1000000"},

View File

@@ -14,7 +14,6 @@
*
*/
using System;
using QuantConnect.Data;
using System.Collections.Generic;
using QuantConnect.Indicators;
@@ -48,8 +47,8 @@ namespace QuantConnect.Algorithm.CSharp
var spxOptions = AddIndexOption(_spx, Resolution);
spxOptions.SetFilter(filterFunc => filterFunc.CallsOnly());
_emaSlow = EMA(_spx, 80);
_emaFast = EMA(_spx, 200);
_emaSlow = EMA(_spx, Resolution > Resolution.Minute ? 6 : 80);
_emaFast = EMA(_spx, Resolution > Resolution.Minute ? 2 : 200);
Settings.DailyPreciseEndTime = true;
}
@@ -110,6 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException("Trade volume should be greater than zero by the end of this algorithm");
}
AssertIndicators();
}
public Symbol InvertOption(Symbol symbol)
@@ -123,6 +123,18 @@ namespace QuantConnect.Algorithm.CSharp
symbol.ID.Date);
}
/// <summary>
/// Asserts indicators are ready
/// </summary>
/// <exception cref="RegressionTestException"></exception>
protected void AssertIndicators()
{
if (!_emaSlow.IsReady || !_emaFast.IsReady)
{
throw new RegressionTestException("Indicators are not ready!");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>

View File

@@ -67,7 +67,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 378;
public override long DataPoints => 360;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -38,7 +38,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 2163;
public override long DataPoints => 1269;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -102,7 +102,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 471135;
public long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
@@ -142,7 +142,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$70000.00"},
{"Estimated Strategy Capacity", "$69000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "61.31%"},
{"OrderListHash", "35d406df401e5b27244e20f5ec57346e"}

View File

@@ -112,7 +112,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 471124;
public long DataPoints => 15130;
/// <summary>
/// Data Points count of the algorithm history
@@ -152,7 +152,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$543.40"},
{"Estimated Strategy Capacity", "$3000.00"},
{"Estimated Strategy Capacity", "$4000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZFMEBBB2E|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "338.60%"},
{"OrderListHash", "301c15063f6e269023d144ca69a765da"}

View File

@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 471124;
public long DataPoints => 15012;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -34,21 +34,21 @@ namespace QuantConnect.Algorithm.CSharp
/// <meta name="tag" content="filter selection" />
public class BasicTemplateOptionsDailyAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private const string UnderlyingTicker = "GOOG";
private const string UnderlyingTicker = "AAPL";
private Symbol _optionSymbol;
private bool _optionExpired;
public override void Initialize()
{
SetStartDate(2015, 12, 23);
SetEndDate(2016, 1, 20);
SetStartDate(2015, 12, 15);
SetEndDate(2016, 2, 1);
SetCash(100000);
var equity = AddEquity(UnderlyingTicker, Resolution.Daily);
var option = AddOption(UnderlyingTicker, Resolution.Daily);
_optionSymbol = option.Symbol;
option.SetFilter(x => x.CallsOnly().Strikes(0, 1).Expiration(0, 30));
option.SetFilter(x => x.CallsOnly().Expiration(0, 60));
// use the underlying equity as the benchmark
SetBenchmark(equity.Symbol);
@@ -122,7 +122,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 36834;
public long DataPoints => 308;
/// <summary>
/// Data Points count of the algorithm history
@@ -141,31 +141,31 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-1.31%"},
{"Compounding Annual Return", "-15.304%"},
{"Drawdown", "1.300%"},
{"Average Loss", "-1.16%"},
{"Compounding Annual Return", "-8.351%"},
{"Drawdown", "1.200%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},
{"End Equity", "98689"},
{"Net Profit", "-1.311%"},
{"Sharpe Ratio", "-3.607"},
{"Sortino Ratio", "-1.188"},
{"Probabilistic Sharpe Ratio", "0.035%"},
{"End Equity", "98844"},
{"Net Profit", "-1.156%"},
{"Sharpe Ratio", "-4.04"},
{"Sortino Ratio", "-2.422"},
{"Probabilistic Sharpe Ratio", "0.099%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0.034"},
{"Annual Variance", "0.001"},
{"Information Ratio", "-3.31"},
{"Tracking Error", "0.034"},
{"Treynor Ratio", "0"},
{"Alpha", "-0.058"},
{"Beta", "0.021"},
{"Annual Standard Deviation", "0.017"},
{"Annual Variance", "0"},
{"Information Ratio", "1.49"},
{"Tracking Error", "0.289"},
{"Treynor Ratio", "-3.212"},
{"Total Fees", "$1.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV W78ZFMML01JA|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "0.05%"},
{"OrderListHash", "e188868e048fab6b6a0481b4479e97f9"}
{"Estimated Strategy Capacity", "$72000.00"},
{"Lowest Capacity Asset", "AAPL W78ZEO2985GM|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.02%"},
{"OrderListHash", "b3125e0af79da0f5eea4cfda09806324"}
};
}
}

View File

@@ -14,7 +14,6 @@
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
@@ -100,7 +99,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1252633;
public long DataPoints => 12290;
/// <summary>
/// Data Points count of the algorithm history
@@ -120,7 +119,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-0.40%"},
{"Compounding Annual Return", "-21.622%"},
{"Compounding Annual Return", "-20.338%"},
{"Drawdown", "0.300%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},

View File

@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1847643;
public long DataPoints => 17486;
/// <summary>
/// Data Points count of the algorithm history
@@ -157,32 +157,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "0.14%"},
{"Average Loss", "-0.28%"},
{"Compounding Annual Return", "-47.543%"},
{"Average Win", "0.13%"},
{"Average Loss", "-0.30%"},
{"Compounding Annual Return", "-46.395%"},
{"Drawdown", "1.600%"},
{"Expectancy", "0.502"},
{"Expectancy", "0.429"},
{"Start Equity", "100000"},
{"End Equity", "99178.50"},
{"Net Profit", "-0.821%"},
{"Sharpe Ratio", "-4.136"},
{"End Equity", "99149.50"},
{"Net Profit", "-0.850%"},
{"Sharpe Ratio", "-4.298"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "17.155%"},
{"Probabilistic Sharpe Ratio", "15.319%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0.50"},
{"Alpha", "-0.855"},
{"Beta", "1.047"},
{"Annual Standard Deviation", "0.099"},
{"Profit-Loss Ratio", "0.43"},
{"Alpha", "-0.84"},
{"Beta", "0.986"},
{"Annual Standard Deviation", "0.098"},
{"Annual Variance", "0.01"},
{"Information Ratio", "-9.141"},
{"Information Ratio", "-9.299"},
{"Tracking Error", "0.091"},
{"Treynor Ratio", "-0.392"},
{"Treynor Ratio", "-0.428"},
{"Total Fees", "$4.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "13.49%"},
{"OrderListHash", "2722fee93126736e03d66d7ab880b537"}
{"Portfolio Turnover", "13.50%"},
{"OrderListHash", "cf14a7ce9c86e6844051820fd4c9394c"}
};
}
}

View File

@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 32351;
public long DataPoints => 9504;
/// <summary>
/// Data Points count of the algorithm history
@@ -129,7 +129,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "5"},
{"Average Win", "0%"},
{"Average Loss", "-0.07%"},
{"Compounding Annual Return", "-12.496%"},
{"Compounding Annual Return", "-11.517%"},
{"Drawdown", "0.200%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},

View File

@@ -43,14 +43,12 @@ namespace QuantConnect.Algorithm.CSharp
SetEndDate(2021, 1, 10);
SetCash(1000000);
var spx = AddIndex("SPX").Symbol;
// regular option SPX contracts
var spxOptions = AddIndexOption(spx);
var spxOptions = AddIndexOption("SPX");
spxOptions.SetFilter(u => u.Strikes(0, 1).Expiration(0, 30));
// weekly option SPX contracts
var spxw = AddIndexOption(spx, "SPXW");
var spxw = AddIndexOption("SPX", "SPXW");
spxw.SetFilter(u => u.Strikes(0, 1)
// single week ahead since there are many SPXW contracts and we want to preserve performance
.Expiration(0, 7)
@@ -105,7 +103,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 57869;
public virtual long DataPoints => 21467;
/// <summary>
/// Data Points count of the algorithm history
@@ -123,31 +121,31 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "0%"},
{"Average Loss", "-0.69%"},
{"Compounding Annual Return", "59.804%"},
{"Average Win", "0.63%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "54.478%"},
{"Drawdown", "0.400%"},
{"Expectancy", "-0.5"},
{"Expectancy", "23.219"},
{"Start Equity", "1000000"},
{"End Equity", "1006025"},
{"Net Profit", "0.602%"},
{"Sharpe Ratio", "3.01"},
{"Sharpe Ratio", "2.62"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "62.865%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.249"},
{"Beta", "-0.033"},
{"Probabilistic Sharpe Ratio", "63.221%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "23.22"},
{"Alpha", "0.067"},
{"Beta", "-0.013"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-99.414"},
{"Tracking Error", "0.072"},
{"Treynor Ratio", "-0.382"},
{"Information Ratio", "-50.808"},
{"Tracking Error", "0.086"},
{"Treynor Ratio", "-0.725"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$580000.00"},
{"Lowest Capacity Asset", "SPXW 31K54PVWHUJHQ|SPX 31"},
{"Portfolio Turnover", "0.48%"},
{"Portfolio Turnover", "0.40%"},
{"OrderListHash", "07a085baedb37bb7c8d460558ea77e88"}
};
}

View File

@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 40968;
public virtual long DataPoints => 16680;
/// <summary>
/// Data Points count of the algorithm history
@@ -127,11 +127,11 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "10"},
{"Average Win", "0.47%"},
{"Average Win", "0.46%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "101.998%"},
{"Drawdown", "0.100%"},
{"Expectancy", "24.484"},
{"Expectancy", "24.137"},
{"Start Equity", "1000000"},
{"End Equity", "1009050"},
{"Net Profit", "0.905%"},
@@ -140,7 +140,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Probabilistic Sharpe Ratio", "95.546%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "49.97"},
{"Profit-Loss Ratio", "49.27"},
{"Alpha", "-2.01"},
{"Beta", "0.307"},
{"Annual Standard Deviation", "0.021"},

View File

@@ -15,6 +15,7 @@
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
@@ -68,8 +69,8 @@ namespace QuantConnect.Algorithm.CSharp.Benchmarks
return topFine.Select(x => x.Symbol);
}
//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
public void OnData(TradeBars data)
//Data Event Handler: New data arrives here.
public override void OnData(Slice slice)
{
// if we have no changes, do nothing
if (_changes == SecurityChanges.None) return;

View File

@@ -16,6 +16,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
@@ -58,7 +59,7 @@ namespace QuantConnect.Algorithm.CSharp.Benchmarks
}).ToArray();
}
public void OnData(TradeBars data)
public override void OnData(Slice slice)
{
// wait for our entire ribbon to be ready
if (!_ribbon.All(x => x.IsReady)) return;

View File

@@ -93,33 +93,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "14"},
{"Average Win", "0%"},
{"Average Loss", "-0.23%"},
{"Compounding Annual Return", "63.336%"},
{"Total Orders", "22"},
{"Average Win", "0.00%"},
{"Average Loss", "-0.14%"},
{"Compounding Annual Return", "71.152%"},
{"Drawdown", "1.100%"},
{"Expectancy", "-1"},
{"Expectancy", "-0.797"},
{"Start Equity", "100000"},
{"End Equity", "100674.37"},
{"Net Profit", "0.674%"},
{"Sharpe Ratio", "3.986"},
{"End Equity", "100738.86"},
{"Net Profit", "0.739%"},
{"Sharpe Ratio", "4.46"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "58.892%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.595"},
{"Beta", "0.57"},
{"Probabilistic Sharpe Ratio", "60.106%"},
{"Loss Rate", "80%"},
{"Win Rate", "20%"},
{"Profit-Loss Ratio", "0.02"},
{"Alpha", "-0.552"},
{"Beta", "0.579"},
{"Annual Standard Deviation", "0.133"},
{"Annual Variance", "0.018"},
{"Information Ratio", "-13.918"},
{"Tracking Error", "0.104"},
{"Treynor Ratio", "0.93"},
{"Total Fees", "$40.20"},
{"Estimated Strategy Capacity", "$4400000.00"},
{"Information Ratio", "-13.953"},
{"Tracking Error", "0.099"},
{"Treynor Ratio", "1.024"},
{"Total Fees", "$46.24"},
{"Estimated Strategy Capacity", "$2600000.00"},
{"Lowest Capacity Asset", "AIG R735QTJ8XC9X"},
{"Portfolio Turnover", "64.47%"},
{"OrderListHash", "fa0af3b345296ccc41e25c0b6c30fc96"}
{"Portfolio Turnover", "69.06%"},
{"OrderListHash", "44a85134cd1c91c9720549bc0e007f80"}
};
}
}

View File

@@ -14,6 +14,7 @@
*/
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Orders;
using QuantConnect.Securities;
@@ -58,8 +59,8 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">TradeBars IDictionary object with your stock data</param>
public void OnData(TradeBars data)
/// <param name="slice">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{

View File

@@ -116,9 +116,9 @@ namespace QuantConnect.Algorithm.CSharp
}
/// <summary>
/// New TradeBar data for our assets.
/// New data for our assets.
/// </summary>
public void OnData(TradeBars data)
public override void OnData(Slice slice)
{
try
{

View File

@@ -0,0 +1,167 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using QuantConnect.Commands;
using QuantConnect.Interfaces;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting the behavior of different callback commands call
/// </summary>
public class CallbackCommandRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 07);
SetEndDate(2013, 10, 11);
AddEquity("SPY");
AddEquity("BAC");
AddEquity("IBM");
AddCommand<BoolCommand>();
AddCommand<VoidCommand>();
var potentialCommand = new VoidCommand
{
Target = new[] { "BAC" },
Quantity = 10,
Parameters = new() { { "tag", "Signal X" } }
};
var commandLink = Link(potentialCommand);
Notify.Email("email@address", "Trade Command Event", $"Signal X trade\nFollow link to trigger: {commandLink}");
var commandLink2 = Link(new { Symbol = "SPY", Parameters = new Dictionary<string, int>() { { "Quantity", 10 } } });
Notify.Email("email@address", "Untyped Command Event", $"Signal Y trade\nFollow link to trigger: {commandLink2}");
// We need to create a project on QuantConnect to test the BroadcastCommand method
// and use the ProjectId in the BroadcastCommand call
ProjectId = 21805137;
// All live deployments receive the broadcasts below
var broadcastResult = BroadcastCommand(potentialCommand);
var broadcastResult2 = BroadcastCommand(new { Symbol = "SPY", Parameters = new Dictionary<string, int>() { { "Quantity", 10 } } });
}
/// <summary>
/// Handle generic command callback
/// </summary>
public override bool? OnCommand(dynamic data)
{
Buy(data.Symbol, data.parameters["quantity"]);
return true;
}
private class VoidCommand : Command
{
public DateTime TargetTime { get; set; }
public string[] Target { get; set; }
public decimal Quantity { get; set; }
public Dictionary<string, string> Parameters { get; set; }
public override bool? Run(IAlgorithm algorithm)
{
if (TargetTime != algorithm.Time)
{
return null;
}
((QCAlgorithm)algorithm).Order(Target[0], Quantity, tag: Parameters["tag"]);
return null;
}
}
private class BoolCommand : Command
{
public bool? Result { get; set; }
public override bool? Run(IAlgorithm algorithm)
{
var shouldTrade = MyCustomMethod();
if (shouldTrade.HasValue && shouldTrade.Value)
{
((QCAlgorithm)algorithm).Buy("IBM", 1);
}
return shouldTrade;
}
private bool? MyCustomMethod()
{
return Result;
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; }
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 3943;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "271.453%"},
{"Drawdown", "2.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101691.92"},
{"Net Profit", "1.692%"},
{"Sharpe Ratio", "8.854"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "67.609%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.005"},
{"Beta", "0.996"},
{"Annual Standard Deviation", "0.222"},
{"Annual Variance", "0.049"},
{"Information Ratio", "-14.565"},
{"Tracking Error", "0.001"},
{"Treynor Ratio", "1.97"},
{"Total Fees", "$3.44"},
{"Estimated Strategy Capacity", "$56000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "19.93%"},
{"OrderListHash", "3da9fa60bf95b9ed148b95e02e0cfc9e"}
};
}
}

View File

@@ -15,6 +15,7 @@
using QuantConnect.Interfaces;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
@@ -71,7 +72,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// We're doing our analysis in the OnRenkoBar method, but the framework verifies that this method exists, so we define it.
/// </summary>
public void OnData(TradeBars data)
public override void OnData(Slice slice)
{
}
@@ -134,7 +135,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "29"},
{"Average Win", "1.85%"},
{"Average Loss", "-1.49%"},
{"Compounding Annual Return", "7.817%"},
{"Compounding Annual Return", "7.824%"},
{"Drawdown", "6.800%"},
{"Expectancy", "0.281"},
{"Start Equity", "100000"},
@@ -154,10 +155,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0.083"},
{"Treynor Ratio", "0.118"},
{"Total Fees", "$129.34"},
{"Estimated Strategy Capacity", "$1000000000.00"},
{"Estimated Strategy Capacity", "$2500000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "7.91%"},
{"OrderListHash", "cb118f22e33089e9ab4af8514e4f2b5f"}
{"OrderListHash", "2668157409450ab9949a71716a5dbc2e"}
};
}
}

View File

@@ -15,6 +15,7 @@
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
@@ -80,8 +81,8 @@ namespace QuantConnect.Algorithm.CSharp
return topFine.Select(x => x.Symbol);
}
//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
public void OnData(TradeBars data)
//Data Event Handler: New data arrives here.
public override void OnData(Slice slice)
{
// if we have no changes, do nothing
if (_changes == SecurityChanges.None) return;

View File

@@ -177,32 +177,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "1.16%"},
{"Average Win", "1.39%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "32.505%"},
{"Compounding Annual Return", "40.025%"},
{"Drawdown", "1.400%"},
{"Expectancy", "0"},
{"Start Equity", "50000"},
{"End Equity", "50581.67"},
{"Net Profit", "1.163%"},
{"Sharpe Ratio", "2.666"},
{"Sortino Ratio", "19.179"},
{"Probabilistic Sharpe Ratio", "64.748%"},
{"End Equity", "50696.56"},
{"Net Profit", "1.393%"},
{"Sharpe Ratio", "3.192"},
{"Sortino Ratio", "4.952"},
{"Probabilistic Sharpe Ratio", "68.664%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.272"},
{"Beta", "0.436"},
{"Annual Standard Deviation", "0.086"},
{"Annual Variance", "0.007"},
{"Information Ratio", "3.572"},
{"Tracking Error", "0.092"},
{"Treynor Ratio", "0.523"},
{"Alpha", "0.328"},
{"Beta", "0.474"},
{"Annual Standard Deviation", "0.088"},
{"Annual Variance", "0.008"},
{"Information Ratio", "4.219"},
{"Tracking Error", "0.09"},
{"Treynor Ratio", "0.59"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$49000000.00"},
{"Estimated Strategy Capacity", "$81000000.00"},
{"Lowest Capacity Asset", "IBM R735QTJ8XC9X"},
{"Portfolio Turnover", "6.64%"},
{"OrderListHash", "69614ad86028ebc190bff5fb42795a3f"}
{"Portfolio Turnover", "6.65%"},
{"OrderListHash", "4eaacdd341a5be0d04cb32647d931471"}
};
}
}

View File

@@ -48,7 +48,12 @@ namespace QuantConnect.Algorithm.CSharp
UniverseSettings.Resolution = Resolution.Minute;
SetStartDate(2014, 06, 04);
SetEndDate(2014, 06, 06);
// TWX is selected the 4th and 5th and aapl after that.
// If the algo ends on the 6th, TWX subscriptions will not be removed before OnEndOfAlgorithm is called:
// - 6th: AAPL is selected, TWX is removed but subscriptions are not removed because the securities are invested.
// - TWX and its options are liquidated.
// - 7th: Since options universe selection is daily now, TWX subscriptions are removed the next day (7th)
SetEndDate(2014, 06, 07);
var selectionUniverse = AddUniverse(enumerable => new[] { Time.Date <= new DateTime(2014, 6, 5) ? _twx : _aapl },
enumerable => new[] { Time.Date <= new DateTime(2014, 6, 5) ? _twx : _aapl });
@@ -157,7 +162,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 998464;
public long DataPoints => 18993;
/// <summary>
/// Data Points count of the algorithm history
@@ -197,8 +202,8 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0.048"},
{"Treynor Ratio", "0.172"},
{"Total Fees", "$16.10"},
{"Estimated Strategy Capacity", "$3100000.00"},
{"Lowest Capacity Asset", "AOL VRKS95ENLBYE|AOL R735QTJ8XC9X"},
{"Estimated Strategy Capacity", "$5000000.00"},
{"Lowest Capacity Asset", "AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "17.64%"},
{"OrderListHash", "a8605c1f5a9c67f60f1ddc963ec45542"}
};

View File

@@ -111,7 +111,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 35405;
public long DataPoints => 35402;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -118,7 +118,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 78091;
public long DataPoints => 78088;
/// <summary>
/// Data Points count of the algorithm history
@@ -136,32 +136,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "12"},
{"Average Win", "0.55%"},
{"Average Loss", "-0.26%"},
{"Compounding Annual Return", "16.717%"},
{"Drawdown", "1.700%"},
{"Expectancy", "0.850"},
{"Average Win", "0.63%"},
{"Average Loss", "-0.49%"},
{"Compounding Annual Return", "-35.851%"},
{"Drawdown", "2.700%"},
{"Expectancy", "-0.542"},
{"Start Equity", "50000"},
{"End Equity", "50318.65"},
{"Net Profit", "0.637%"},
{"Sharpe Ratio", "1.024"},
{"Sortino Ratio", "2.169"},
{"Probabilistic Sharpe Ratio", "50.223%"},
{"Loss Rate", "40%"},
{"Win Rate", "60%"},
{"Profit-Loss Ratio", "2.08"},
{"Alpha", "0.196"},
{"Beta", "0.741"},
{"Annual Standard Deviation", "0.118"},
{"Annual Variance", "0.014"},
{"Information Ratio", "2.294"},
{"Tracking Error", "0.097"},
{"Treynor Ratio", "0.163"},
{"Total Fees", "$27.94"},
{"Estimated Strategy Capacity", "$200000000.00"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "26.69%"},
{"OrderListHash", "82ca991c660ecefbcbdf0b4cc90ddd67"}
{"End Equity", "49096.01"},
{"Net Profit", "-1.808%"},
{"Sharpe Ratio", "-1.989"},
{"Sortino Ratio", "-3.359"},
{"Probabilistic Sharpe Ratio", "23.898%"},
{"Loss Rate", "80%"},
{"Win Rate", "20%"},
{"Profit-Loss Ratio", "1.29"},
{"Alpha", "-0.172"},
{"Beta", "1.068"},
{"Annual Standard Deviation", "0.141"},
{"Annual Variance", "0.02"},
{"Information Ratio", "-1.865"},
{"Tracking Error", "0.096"},
{"Treynor Ratio", "-0.263"},
{"Total Fees", "$26.72"},
{"Estimated Strategy Capacity", "$630000000.00"},
{"Lowest Capacity Asset", "FB V6OIPNZEM8V9"},
{"Portfolio Turnover", "24.59%"},
{"OrderListHash", "90b57d40d047eedbff7111d2a73a1290"}
};
}
}

View File

@@ -92,7 +92,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 70952;
public long DataPoints => 70951;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -13,12 +13,11 @@
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using System.Collections.Generic;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
@@ -30,7 +29,7 @@ namespace QuantConnect.Algorithm.CSharp
public class CoarseSelectionTimeRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _spy;
private decimal _historyCoarseSpyPrice;
private decimal _spyPrice;
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
@@ -53,7 +52,12 @@ namespace QuantConnect.Algorithm.CSharp
.Where(fundamental => fundamental.Symbol != _spy) // ignore spy
.Take(1);
_historyCoarseSpyPrice = History(_spy, 1).First().Close;
var historyCoarseSpyPrice = History(_spy, 1).First().Close;
if (_spyPrice != 0 && (historyCoarseSpyPrice == 0 || historyCoarseSpyPrice != _spyPrice))
{
throw new RegressionTestException($"Unexpected SPY price: {historyCoarseSpyPrice}");
}
_spyPrice = 0;
return top.Select(x => x.Symbol);
}
@@ -72,12 +76,9 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected ActiveSecurities count: {ActiveSecurities.Count}");
}
// the price obtained by the previous coarse selection should be the same as the current price
if (_historyCoarseSpyPrice != 0 && _historyCoarseSpyPrice != Securities[_spy].Price)
{
throw new RegressionTestException($"Unexpected SPY price: {_historyCoarseSpyPrice}");
}
_historyCoarseSpyPrice = 0;
// we get the data at 4PM, selection happening at midnight
_spyPrice = Securities[_spy].Price;
if (!Portfolio.Invested)
{
SetHoldings(_spy, 1);
@@ -98,7 +99,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 49662;
public long DataPoints => 49660;
/// <summary>
/// Data Points count of the algorithm history
@@ -118,30 +119,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "57.657%"},
{"Drawdown", "1.000%"},
{"Compounding Annual Return", "36.033%"},
{"Drawdown", "1.300%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101002.81"},
{"Net Profit", "1.003%"},
{"Sharpe Ratio", "5.273"},
{"Sortino Ratio", "7.973"},
{"Probabilistic Sharpe Ratio", "69.521%"},
{"End Equity", "100676.75"},
{"Net Profit", "0.677%"},
{"Sharpe Ratio", "2.646"},
{"Sortino Ratio", "2.77"},
{"Probabilistic Sharpe Ratio", "58.013%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "1.003"},
{"Annual Standard Deviation", "0.087"},
{"Annual Variance", "0.007"},
{"Information Ratio", "6.477"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0.455"},
{"Total Fees", "$3.08"},
{"Estimated Strategy Capacity", "$720000000.00"},
{"Alpha", "-0.264"},
{"Beta", "1.183"},
{"Annual Standard Deviation", "0.103"},
{"Annual Variance", "0.011"},
{"Information Ratio", "-8.158"},
{"Tracking Error", "0.022"},
{"Treynor Ratio", "0.231"},
{"Total Fees", "$3.07"},
{"Estimated Strategy Capacity", "$930000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "12.54%"},
{"OrderListHash", "472e90ba189aaf55e0edab9087c3d8e7"}
{"Portfolio Turnover", "12.65%"},
{"OrderListHash", "87438e51988f37757a2d7f97389483ea"}
};
}
}

View File

@@ -49,13 +49,13 @@ namespace QuantConnect.Algorithm.CSharp
private bool _firstCall = true;
private PortfolioTarget[] _targets = new PortfolioTarget[4];
/// <summary>
/// Symbols accepted by Collective2. Collective2 accepts stock,
/// future, forex and US stock option symbols
/// </summary>
private List<Symbol> _symbols = new()
{
{
QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA, null, null),
QuantConnect.Symbol.Create("EURUSD", SecurityType.Forex, Market.Oanda, null, null),
QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15), null),
@@ -95,15 +95,19 @@ namespace QuantConnect.Algorithm.CSharp
// Initialize this flag, to check when the ema indicators crosses between themselves
_emaFastIsNotSet = true;
// Set Collective2 signal export provider
// Set Collective2 signal export provider.
// If using the Collective2 white-label API, you can specify it in the constructor with the optional parameter `useWhiteLabelApi`:
// e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId, useWhiteLabelApi: true)
// The API url can also be overridden by setting the Destination property:
// e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId) { Destination = new Uri("your url") }
SignalExport.AddSignalExportProviders(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
SetWarmUp(100);
}
/// <summary>
/// Reduce the quantity of holdings for SPY or increase it, depending the case,
/// when the EMA's indicators crosses between themselves, then send a signal to
/// Reduce the quantity of holdings for SPY or increase it, depending the case,
/// when the EMA's indicators crosses between themselves, then send a signal to
/// Collective2 API
/// </summary>
/// <param name="slice"></param>

View File

@@ -70,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 471135;
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -136,7 +136,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 471135;
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -52,7 +52,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 471135;
public override long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history
@@ -92,7 +92,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$70000.00"},
{"Estimated Strategy Capacity", "$69000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "30.35%"},
{"OrderListHash", "615c795b0c450cb8e4c3cba803ebb180"}

View File

@@ -331,7 +331,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 471135;
public long DataPoints => 15023;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -86,33 +86,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "14"},
{"Average Win", "0.00%"},
{"Average Loss", "-0.23%"},
{"Compounding Annual Return", "-36.885%"},
{"Drawdown", "1.800%"},
{"Expectancy", "-0.549"},
{"Total Orders", "16"},
{"Average Win", "0.01%"},
{"Average Loss", "-0.18%"},
{"Compounding Annual Return", "-35.728%"},
{"Drawdown", "1.700%"},
{"Expectancy", "-0.690"},
{"Start Equity", "100000"},
{"End Equity", "99413.33"},
{"Net Profit", "-0.587%"},
{"Sharpe Ratio", "-2.494"},
{"Sortino Ratio", "-3.393"},
{"Probabilistic Sharpe Ratio", "34.321%"},
{"Loss Rate", "56%"},
{"Win Rate", "44%"},
{"Profit-Loss Ratio", "0.01"},
{"Alpha", "-0.888"},
{"Beta", "0.349"},
{"Annual Standard Deviation", "0.08"},
{"Annual Variance", "0.006"},
{"Information Ratio", "-14.897"},
{"Tracking Error", "0.146"},
{"Treynor Ratio", "-0.568"},
{"Total Fees", "$37.79"},
{"End Equity", "99436.42"},
{"Net Profit", "-0.564%"},
{"Sharpe Ratio", "-2.767"},
{"Sortino Ratio", "-3.388"},
{"Probabilistic Sharpe Ratio", "32.568%"},
{"Loss Rate", "70%"},
{"Win Rate", "30%"},
{"Profit-Loss Ratio", "0.03"},
{"Alpha", "-0.771"},
{"Beta", "0.296"},
{"Annual Standard Deviation", "0.068"},
{"Annual Variance", "0.005"},
{"Information Ratio", "-13.734"},
{"Tracking Error", "0.157"},
{"Treynor Ratio", "-0.632"},
{"Total Fees", "$39.85"},
{"Estimated Strategy Capacity", "$4700000.00"},
{"Lowest Capacity Asset", "AIG R735QTJ8XC9X"},
{"Portfolio Turnover", "60.65%"},
{"OrderListHash", "d84db24a398d074200c5ed979c4410f3"}
{"Portfolio Turnover", "60.79%"},
{"OrderListHash", "7a65de0f613e5c6161e410d499f45445"}
};
}
}

View File

@@ -0,0 +1,131 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the functionality of the CompositeIndicator,
/// using either a lambda expression or a method reference.
/// </summary>
public class CompositeIndicatorWorksAsExpectedRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private CompositeIndicator _compositeMinDirect;
private CompositeIndicator _compositeMinMethod;
private bool _dataReceived;
public override void Initialize()
{
SetStartDate(2013, 10, 4);
SetEndDate(2013, 10, 5);
AddEquity("SPY", Resolution.Minute);
var closePrice = Identity("SPY", Resolution.Minute, Field.Close);
var lowPrice = MIN("SPY", 420, Resolution.Minute, Field.Low);
_compositeMinDirect = new CompositeIndicator("CompositeMinDirect", closePrice, lowPrice, (l, r) => new IndicatorResult(Math.Min(l.Current.Value, r.Current.Value)));
_compositeMinMethod = new CompositeIndicator("CompositeMinMethod", closePrice, lowPrice, Composer);
_dataReceived = false;
}
private IndicatorResult Composer(IndicatorBase l, IndicatorBase r)
{
return new IndicatorResult(Math.Min(l.Current.Value, r.Current.Value));
}
public override void OnData(Slice data)
{
_dataReceived = true;
if (_compositeMinDirect.Current.Value != _compositeMinMethod.Current.Value)
{
throw new RegressionTestException($"Values of indicators differ: {_compositeMinDirect.Current.Value} | {_compositeMinMethod.Current.Value}");
}
}
public override void OnEndOfAlgorithm()
{
if (!_dataReceived)
{
throw new RegressionTestException("No data was processed during the algorithm execution.");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 795;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -0,0 +1,166 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
using System;
using System.Collections.Generic;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This regression algorithm asserts the consolidated US equity daily bars from the hour bars exactly matches
/// the daily bars returned from the database
/// </summary>
public class ConsolidateHourBarsIntoDailyBarsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _spy;
private RelativeStrengthIndex _rsi;
private RelativeStrengthIndex _rsiTimeDelta;
private Dictionary<DateTime, decimal> _values = new();
private int _count;
private bool _indicatorsCompared;
public override void Initialize()
{
SetStartDate(2020, 5, 1);
SetEndDate(2020, 6, 5);
_spy = AddEquity("SPY", Resolution.Hour).Symbol;
// We will use these two indicators to compare the daily consolidated bars equals
// the ones returned from the database. We use this specific type of indicator as
// it depends on its previous values. Thus, if at some point the bars received by
// the indicators differ, so will their final values
_rsi = new RelativeStrengthIndex("FIRST", 15, MovingAverageType.Wilders);
RegisterIndicator(_spy, _rsi, Resolution.Daily, selector: (bar) =>
{
var tradeBar = (TradeBar)bar;
return (tradeBar.Close + tradeBar.Open) / 2;
});
// We won't register this indicator as we will update it manually at the end of the
// month, so that we can compare the values of the indicator that received consolidated
// bars and the values of this one
_rsiTimeDelta = new RelativeStrengthIndex("SECOND" ,15, MovingAverageType.Wilders);
}
public override void OnData(Slice slice)
{
if (IsWarmingUp) return;
if (slice.ContainsKey(_spy) && slice[_spy] != null)
{
if (Time.Month == EndDate.Month)
{
var history = History(_spy, _count, Resolution.Daily);
foreach (var bar in history)
{
var time = bar.EndTime.Date;
var average = (bar.Close + bar.Open) / 2;
_rsiTimeDelta.Update(bar.EndTime, average);
if (_rsiTimeDelta.Current.Value != _values[time])
{
throw new RegressionTestException($"Both {_rsi.Name} and {_rsiTimeDelta.Name} should have the same values, but they differ. {_rsi.Name}: {_values[time]} | {_rsiTimeDelta.Name}: {_rsiTimeDelta.Current.Value}");
}
}
_indicatorsCompared = true;
Quit();
}
else
{
_values[Time.Date] = _rsi.Current.Value;
// Since the symbol resolution is hour and the symbol is equity, we know the last bar received in a day will
// be at the market close, this is 16h. We need to count how many daily bars were consolidated in order to know
// how many we need to request from the history
if (Time.Hour == 16)
{
_count++;
}
}
}
}
public override void OnEndOfAlgorithm()
{
if (!_indicatorsCompared)
{
throw new RegressionTestException($"Indicators {_rsi.Name} and {_rsiTimeDelta.Name} should have been compared, but they were not. Please make sure the indicators are getting SPY data");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 290;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 20;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "-5.215"},
{"Tracking Error", "0.159"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -22,6 +22,7 @@ using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
@@ -31,69 +32,83 @@ namespace QuantConnect.Algorithm.CSharp
public class ConsolidateRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private List<int> _consolidationCounts;
private List<int> _expectedConsolidationCounts;
private List<SimpleMovingAverage> _smas;
private List<DateTime> _lastSmaUpdates;
private int _expectedConsolidations;
private int _customDataConsolidator;
private Symbol _symbol;
private int _customDataConsolidatorCount;
private Future _future;
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 08);
SetEndDate(2013, 10, 20);
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 20);
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
_symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
var security = AddFutureContract(_symbol);
var symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
_future = AddFutureContract(symbol);
_consolidationCounts = Enumerable.Repeat(0, 9).ToList();
var tradableDatesCount = QuantConnect.Time.EachTradeableDayInTimeZone(_future.Exchange.Hours,
StartDate,
EndDate,
_future.Exchange.TimeZone,
false).Count();
_expectedConsolidationCounts = new(10);
Consolidate<QuoteBar>(symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
bar => UpdateQuoteBar(bar, 0));
// The consolidator will respect the full 1 day bar span and will not consolidate the last tradable date,
// since scan will not be called at 202/01/21 12am
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
Consolidate<QuoteBar>(symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
TickType.Quote, bar => UpdateQuoteBar(bar, 1));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
Consolidate<QuoteBar>(symbol, TimeSpan.FromDays(1), bar => UpdateQuoteBar(bar, 2));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
Consolidate(symbol, Resolution.Daily, TickType.Quote, (Action<QuoteBar>)(bar => UpdateQuoteBar(bar, 3)));
_expectedConsolidationCounts.Add(tradableDatesCount);
Consolidate(symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 4));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
Consolidate<TradeBar>(symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 5));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
// Test using abstract T types, through defining a 'BaseData' handler
Consolidate(symbol, Resolution.Daily, null, (Action<BaseData>)(bar => UpdateBar(bar, 6)));
_expectedConsolidationCounts.Add(tradableDatesCount);
Consolidate(symbol, TimeSpan.FromDays(1), null, (Action<BaseData>)(bar => UpdateBar(bar, 7)));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
Consolidate(symbol, TimeSpan.FromDays(1), (Action<BaseData>)(bar => UpdateBar(bar, 8)));
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
_consolidationCounts = Enumerable.Repeat(0, _expectedConsolidationCounts.Count).ToList();
_smas = _consolidationCounts.Select(_ => new SimpleMovingAverage(10)).ToList();
_lastSmaUpdates = _consolidationCounts.Select(_ => DateTime.MinValue).ToList();
Consolidate<QuoteBar>(_symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
bar => UpdateQuoteBar(bar, 0));
Consolidate<QuoteBar>(_symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
TickType.Quote, bar => UpdateQuoteBar(bar, 1));
Consolidate<QuoteBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateQuoteBar(bar, 2));
Consolidate(_symbol, Resolution.Daily, TickType.Quote, (Action<QuoteBar>)(bar => UpdateQuoteBar(bar, 3)));
Consolidate(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 4));
Consolidate<TradeBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 5));
// custom data
var symbol = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute).Symbol;
Consolidate<TradeBar>(symbol, TimeSpan.FromDays(1), bar => _customDataConsolidator++);
var customSecurity = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute);
Consolidate<TradeBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => _customDataConsolidatorCount++);
try
{
Consolidate<QuoteBar>(symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(bar, -1); });
Consolidate<QuoteBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(bar, -1); });
throw new RegressionTestException($"Expected {nameof(ArgumentException)} to be thrown");
}
catch (ArgumentException)
{
// will try to use BaseDataConsolidator for which input is TradeBars not QuoteBars
}
// Test using abstract T types, through defining a 'BaseData' handler
Consolidate(_symbol, Resolution.Daily, null, (Action<BaseData>)(bar => UpdateBar(bar, 6)));
Consolidate(_symbol, TimeSpan.FromDays(1), null, (Action<BaseData>)(bar => UpdateBar(bar, 7)));
Consolidate(_symbol, TimeSpan.FromDays(1), (Action<BaseData>)(bar => UpdateBar(bar, 8)));
_expectedConsolidations = QuantConnect.Time.EachTradeableDayInTimeZone(security.Exchange.Hours,
StartDate,
EndDate,
security.Exchange.TimeZone,
false).Count();
}
private void UpdateBar(BaseData tradeBar, int position)
{
if (!(tradeBar is TradeBar))
@@ -119,16 +134,27 @@ namespace QuantConnect.Algorithm.CSharp
public override void OnEndOfAlgorithm()
{
if (_consolidationCounts.Any(i => i != _expectedConsolidations) || _customDataConsolidator == 0)
for (var i = 0; i < _consolidationCounts.Count; i++)
{
throw new RegressionTestException("Unexpected consolidation count");
var consolidationCount = _consolidationCounts[i];
var expectedConsolidationCount = _expectedConsolidationCounts[i];
if (consolidationCount != expectedConsolidationCount)
{
throw new RegressionTestException($"Expected {expectedConsolidationCount} consolidations for consolidator {i} but received {consolidationCount}");
}
}
if (_customDataConsolidatorCount == 0)
{
throw new RegressionTestException($"Unexpected custom data consolidation count: {_customDataConsolidatorCount}");
}
for (var i = 0; i < _smas.Count; i++)
{
if (_smas[i].Samples != _expectedConsolidations)
if (_smas[i].Samples != _expectedConsolidationCounts[i])
{
throw new RegressionTestException($"Expected {_expectedConsolidations} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
throw new RegressionTestException($"Expected {_expectedConsolidationCounts} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
}
if (_smas[i].Current.Time != _lastSmaUpdates[i])
@@ -144,9 +170,9 @@ namespace QuantConnect.Algorithm.CSharp
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
if (!Portfolio.Invested && _future.HasData)
{
SetHoldings(_symbol, 0.5);
SetHoldings(_future.Symbol, 0.5);
}
}
@@ -163,7 +189,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 12244;
public long DataPoints => 14228;
/// <summary>
/// Data Points count of the algorithm history
@@ -183,30 +209,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "6636.699%"},
{"Drawdown", "15.900%"},
{"Compounding Annual Return", "665.524%"},
{"Drawdown", "1.500%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "116177.7"},
{"Net Profit", "16.178%"},
{"Sharpe Ratio", "640.313"},
{"End Equity", "109332.4"},
{"Net Profit", "9.332%"},
{"Sharpe Ratio", "9.805"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "99.824%"},
{"Probabilistic Sharpe Ratio", "93.474%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "636.164"},
{"Beta", "5.924"},
{"Annual Standard Deviation", "1.012"},
{"Annual Variance", "1.024"},
{"Information Ratio", "696.123"},
{"Tracking Error", "0.928"},
{"Treynor Ratio", "109.404"},
{"Total Fees", "$23.65"},
{"Estimated Strategy Capacity", "$210000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "81.19%"},
{"OrderListHash", "dfd9a280d3c6470b305c03e0b72c234e"}
{"Alpha", "3.164"},
{"Beta", "0.957"},
{"Annual Standard Deviation", "0.383"},
{"Annual Variance", "0.146"},
{"Information Ratio", "8.29"},
{"Tracking Error", "0.379"},
{"Treynor Ratio", "3.917"},
{"Total Fees", "$15.05"},
{"Estimated Strategy Capacity", "$2100000000.00"},
{"Lowest Capacity Asset", "ES XCZJLC9NOB29"},
{"Portfolio Turnover", "64.34%"},
{"OrderListHash", "d814db6d5a9c97ee6de477ea06cd3834"}
};
}
}

View File

@@ -52,9 +52,10 @@ namespace QuantConnect.Algorithm.CSharp
SetHoldings("SPY", 1);
}
});
_consolidationDaily.Enqueue(new DateTime(2013, 10, 8, 0, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 9, 0, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 10, 0, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 7, 16, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 8, 16, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 9, 16, 0, 0));
_consolidationDaily.Enqueue(new DateTime(2013, 10, 10, 16, 0, 0));
Consolidate("SPY", TimeSpan.FromHours(3), (TradeBar bar) =>
{
@@ -153,7 +154,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$130000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "25.24%"},
{"OrderListHash", "faeb006f6e2015131523994ae78d4eb7"}
{"OrderListHash", "bbda6d0a04ae0b87b2fa10e036296cbb"}
};
}
}

View File

@@ -29,10 +29,11 @@ namespace QuantConnect.Algorithm.CSharp
public class ConsolidatorAnIdentityIndicatorRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private readonly Dictionary<DateTime, decimal> _expectedValues = new Dictionary<DateTime, decimal> {
{ new DateTime(2013, 10, 8), 144.75578537200m },
{ new DateTime(2013, 10, 9), 143.07840976800m },
{ new DateTime(2013, 10, 10), 143.15622616200m },
{ new DateTime(2013, 10, 11), 146.32940578400m }
{ new DateTime(2013, 10, 7, 16, 0, 0), 144.75578537200m },
{ new DateTime(2013, 10, 8, 16, 0, 0), 143.07840976800m },
{ new DateTime(2013, 10, 9, 16, 0, 0), 143.15622616200m },
{ new DateTime(2013, 10, 10, 16, 0, 0), 146.32940578400m },
{ new DateTime(2013, 10, 11, 16, 0, 0), 147.24590998000m }
};
private Identity _identity;
private int _assertCount;
@@ -80,9 +81,9 @@ namespace QuantConnect.Algorithm.CSharp
public override void OnEndOfAlgorithm()
{
if (_assertCount != 12)
if (_assertCount != 15)
{
throw new RegressionTestException($"IUnexpected assertiong count: {_assertCount}");
throw new RegressionTestException($"Unexpected asserting count: {_assertCount}");
}
}

View File

@@ -113,23 +113,12 @@ namespace QuantConnect.Algorithm.CSharp
throw new RegressionTestException($"Unexpected data count, step: {_step}");
}
}
else if (_step == 5)
{
if (!slice.ContainsKey(_fb)
|| !slice.ContainsKey(_spy))
{
throw new RegressionTestException($"Unexpected symbols found, step: {_step}");
}
if (slice.Count != 2)
{
throw new RegressionTestException($"Unexpected data count, step: {_step}");
}
}
}
public override void OnEndOfAlgorithm()
{
if (_step != 5)
// First selection is on the midnight of the 8th, start getting data from the 8th to the 11th
if (_step != 4)
{
throw new RegressionTestException($"Unexpected step count: {_step}");
}
@@ -139,12 +128,12 @@ namespace QuantConnect.Algorithm.CSharp
{
foreach (var added in changes.AddedSecurities)
{
Log($"AddedSecurities {added}");
Log($"{Time} AddedSecurities {added}");
}
foreach (var removed in changes.RemovedSecurities)
{
Log($"RemovedSecurities {removed} {_step}");
Log($"{Time} RemovedSecurities {removed} {_step}");
// we are currently notifying the removal of AAPl twice,
// when deselected and when finally removed (since it stayed pending)
if (removed.Symbol == _appl && _step != 1 && _step != 2
@@ -168,7 +157,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 52;
public long DataPoints => 50;
/// <summary>
/// Data Points count of the algorithm history
@@ -186,32 +175,32 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-0.54%"},
{"Compounding Annual Return", "-32.671%"},
{"Drawdown", "0.900%"},
{"Expectancy", "-1"},
{"Average Win", "0.68%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "70.501%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "99459.59"},
{"Net Profit", "-0.540%"},
{"Sharpe Ratio", "-3.436"},
{"End Equity", "100684.53"},
{"Net Profit", "0.685%"},
{"Sharpe Ratio", "13.41"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "25.715%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Probabilistic Sharpe Ratio", "99.997%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.73"},
{"Beta", "0.22"},
{"Annual Standard Deviation", "0.086"},
{"Annual Variance", "0.007"},
{"Information Ratio", "-12.125"},
{"Tracking Error", "0.187"},
{"Treynor Ratio", "-1.338"},
{"Total Fees", "$32.32"},
{"Estimated Strategy Capacity", "$95000000.00"},
{"Alpha", "0.235"},
{"Beta", "0.15"},
{"Annual Standard Deviation", "0.04"},
{"Annual Variance", "0.002"},
{"Information Ratio", "-7.587"},
{"Tracking Error", "0.19"},
{"Treynor Ratio", "3.546"},
{"Total Fees", "$32.77"},
{"Estimated Strategy Capacity", "$230000000.00"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "20.06%"},
{"OrderListHash", "2271d307c23224ed7abc7fc852a51f24"}
{"Portfolio Turnover", "20.15%"},
{"OrderListHash", "d269ebced0796dde34f9eb775772e027"}
};
}
}

View File

@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 713369;
public long DataPoints => 713371;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -155,7 +155,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 723496;
public long DataPoints => 723498;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -120,7 +120,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 9956;
public virtual long DataPoints => 9953;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -34,6 +34,6 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 15820;
public override long DataPoints => 15813;
}
}

View File

@@ -184,7 +184,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 596356;
public long DataPoints => 596358;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 19886;
public long DataPoints => 19888;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -0,0 +1,237 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm reproducing GH issue #8386 and other related bugs.
/// It asserts that open positions are liquidated when a contract is delisted, even if the contract was added as an internal subscription.
/// It also asserts that the contract is not tradable after being delisted.
/// </summary>
public class ContinuousFutureOpenPositionsLiquidationOnDelistingRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Future _continuousContract;
private Symbol _prevContractSymbol;
private bool _traded;
private bool _mapped;
private bool _delistedContractChecked;
private DateTime _firstMappedContractRemovalTime;
private int _removalCount;
public override void Initialize()
{
SetStartDate(2013, 10, 08);
SetEndDate(2013, 12, 30);
_continuousContract = AddFuture(Futures.Indices.SP500EMini,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.OpenInterest,
contractDepthOffset: 0
);
}
public override void OnData(Slice slice)
{
if (!_traded && _continuousContract.HasData)
{
var ticket = MarketOrder(_continuousContract.Mapped, 1);
if (ticket.Status == OrderStatus.Invalid)
{
throw new RegressionTestException($"Order should be valid: {ticket}");
}
_traded = true;
}
if (slice.SymbolChangedEvents.Count > 0)
{
foreach (var change in slice.SymbolChangedEvents.Values)
{
Debug($"[{Time}] :: Mapping: {change}");
_prevContractSymbol = Symbol(change.OldSymbol);
_mapped = true;
}
}
if (!_delistedContractChecked &&
_prevContractSymbol != null &&
Time.Date > _prevContractSymbol.ID.Date &&
IsMarketOpen(_prevContractSymbol))
{
_delistedContractChecked = true;
var delistedContract = Securities.Total.Single(sec => sec.Symbol == _prevContractSymbol);
if (delistedContract.Invested)
{
throw new RegressionTestException($"Position should be closed when {_prevContractSymbol} got delisted {_prevContractSymbol.ID.Date}");
}
if (!delistedContract.IsDelisted)
{
throw new RegressionTestException($"Contract should be delisted: {delistedContract.Symbol}");
}
if (delistedContract.IsTradable)
{
throw new RegressionTestException($"Contract should not be tradable: {delistedContract.Symbol}");
}
var ticket = MarketOrder(_prevContractSymbol, 1);
if (ticket.Status != OrderStatus.Invalid)
{
throw new RegressionTestException($"Delisted contract order should be invalid: {ticket}");
}
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (_prevContractSymbol != null)
{
if (changes.RemovedSecurities.Any(x => x.Symbol == _prevContractSymbol))
{
throw new RegressionTestException($"Previous contract symbol {_prevContractSymbol} should not be removed as a non-internal security");
}
changes.FilterInternalSecurities = false;
if (!changes.RemovedSecurities.Any(x => x.Symbol == _prevContractSymbol))
{
throw new RegressionTestException($"Previous contract symbol {_prevContractSymbol} should be removed as an internal security");
}
_firstMappedContractRemovalTime = Time;
_removalCount++;
}
changes.FilterInternalSecurities = false;
Debug($"[{Time}] :: {changes}");
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
Debug($"[{Time}] :: Order event: {orderEvent}");
}
public override void OnEndOfAlgorithm()
{
if (!_traded)
{
throw new RegressionTestException("No trades have been made");
}
if (!_mapped)
{
throw new RegressionTestException("No mapping events have been fired");
}
if (!_delistedContractChecked)
{
throw new RegressionTestException("No delisted contract has been checked");
}
if (_prevContractSymbol == null)
{
throw new RegressionTestException("No previous contract symbol has been set");
}
var tradedContract = Securities.Total.Single(sec => sec.Symbol == _prevContractSymbol);
if (tradedContract.Invested)
{
throw new RegressionTestException($"Position should be closed when {_prevContractSymbol} got delisted on {_prevContractSymbol.ID.Date}");
}
if (_firstMappedContractRemovalTime == default || _firstMappedContractRemovalTime >= _prevContractSymbol.ID.Date)
{
throw new RegressionTestException($"First mapped contract should have been removed before it's expiry date");
}
if (_removalCount != 1)
{
throw new RegressionTestException($"The mapped contract should have been removed once only");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 396945;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "7.02%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "34.386%"},
{"Drawdown", "1.500%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "107016.6"},
{"Net Profit", "7.017%"},
{"Sharpe Ratio", "3.217"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "99.828%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.227"},
{"Beta", "0.109"},
{"Annual Standard Deviation", "0.084"},
{"Annual Variance", "0.007"},
{"Information Ratio", "-1.122"},
{"Tracking Error", "0.112"},
{"Treynor Ratio", "2.49"},
{"Total Fees", "$2.15"},
{"Estimated Strategy Capacity", "$1700000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.01%"},
{"OrderListHash", "838e662caaa5a385c43ef27df1efbaf4"}
};
}
}

View File

@@ -19,7 +19,6 @@ using QuantConnect.Data;
using QuantConnect.Orders;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using QuantConnect.Data.Market;
using System.Collections.Generic;
using QuantConnect.Securities.Future;
using QuantConnect.Data.UniverseSelection;
@@ -31,7 +30,7 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public class ContinuousFutureRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private List<SymbolChangedEvent> _mappings = new();
private List<Symbol> _previousMappedContractSymbols = new();
private Symbol _currentMappedSymbol;
private Future _continuousContract;
private DateTime _lastMonth;
@@ -77,7 +76,7 @@ namespace QuantConnect.Algorithm.CSharp
{
if (changedEvent.Symbol == _continuousContract.Symbol)
{
_mappings.Add(changedEvent);
_previousMappedContractSymbols.Add(Symbol(changedEvent.OldSymbol));
Log($"{Time} - SymbolChanged event: {changedEvent}");
if (_currentMappedSymbol == _continuousContract.Mapped)
@@ -144,15 +143,20 @@ namespace QuantConnect.Algorithm.CSharp
public override void OnEndOfAlgorithm()
{
var expectedMappingCounts = 2;
if (_mappings.Count != expectedMappingCounts)
if (_previousMappedContractSymbols.Count != expectedMappingCounts)
{
throw new RegressionTestException($"Unexpected symbol changed events: {_mappings.Count}, was expecting {expectedMappingCounts}");
throw new RegressionTestException($"Unexpected symbol changed events: {_previousMappedContractSymbols.Count}, was expecting {expectedMappingCounts}");
}
var securities = Securities.Total.Where(sec => !sec.IsTradable && !sec.Symbol.IsCanonical() && sec.Symbol.SecurityType == SecurityType.Future).ToList();
if (securities.Count != 1)
var delistedSecurities = _previousMappedContractSymbols
.Select(x => Securities.Total.Single(sec => sec.Symbol == x))
.Where(x => x.Symbol.ID.Date < Time)
.ToList();
var markedDelistedSecurities = delistedSecurities.Where(x => x.IsDelisted && !x.IsTradable).ToList();
if (markedDelistedSecurities.Count != delistedSecurities.Count)
{
throw new RegressionTestException($"We should have a single non tradable future contract security! found: {securities.Count}");
throw new RegressionTestException($"Not all delisted contracts are properly market as delisted and non-tradable: " +
$"only {markedDelistedSecurities.Count} are marked, was expecting {delistedSecurities.Count}");
}
}
@@ -169,7 +173,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 713369;
public long DataPoints => 713375;
/// <summary>
/// Data Points count of the algorithm history
@@ -186,18 +190,18 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "3"},
{"Average Win", "1.50%"},
{"Total Orders", "4"},
{"Average Win", "0.84%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "3.337%"},
{"Compounding Annual Return", "3.380%"},
{"Drawdown", "1.600%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101666.4"},
{"Net Profit", "1.666%"},
{"Sharpe Ratio", "0.594"},
{"Sortino Ratio", "0.198"},
{"Probabilistic Sharpe Ratio", "44.801%"},
{"End Equity", "101687.3"},
{"Net Profit", "1.687%"},
{"Sharpe Ratio", "0.605"},
{"Sortino Ratio", "0.202"},
{"Probabilistic Sharpe Ratio", "45.198%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
@@ -205,14 +209,14 @@ namespace QuantConnect.Algorithm.CSharp
{"Beta", "0.134"},
{"Annual Standard Deviation", "0.027"},
{"Annual Variance", "0.001"},
{"Information Ratio", "-2.69"},
{"Information Ratio", "-2.687"},
{"Tracking Error", "0.075"},
{"Treynor Ratio", "0.119"},
{"Treynor Ratio", "0.121"},
{"Total Fees", "$6.45"},
{"Estimated Strategy Capacity", "$8000000000.00"},
{"Estimated Strategy Capacity", "$2600000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "1.39%"},
{"OrderListHash", "40c1137e0bc83b2bc920495af119c8fc"}
{"Portfolio Turnover", "1.88%"},
{"OrderListHash", "1287c3b983c5bac6491bb5ac296c4b55"}
};
}
}

View File

@@ -0,0 +1,262 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using QuantConnect.Data;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
using System;
using QuantConnect.Util;
using System.Linq;
using NodaTime;
using QuantConnect.Interfaces;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data, regardless of the
/// offset between the exchange time zone and the data time zone.
/// </summary>
public abstract class ContinuousFutureRolloverBaseRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
const string Ticker = Futures.Indices.SP500EMini;
private Future _continuousContract;
private DateTime _rolloverTime;
private MarketHoursDatabase.Entry _originalMhdbEntry;
protected abstract Resolution Resolution { get; }
protected abstract Offset ExchangeToDataTimeZoneOffset { get; }
private DateTimeZone DataTimeZone => TimeZones.Utc;
private DateTimeZone ExchangeTimeZone => DateTimeZone.ForOffset(ExchangeToDataTimeZoneOffset);
private bool RolloverHappened => _rolloverTime != DateTime.MinValue;
public override void Initialize()
{
SetStartDate(2013, 10, 8);
SetEndDate(2013, 12, 20);
_originalMhdbEntry = MarketHoursDatabase.GetEntry(Market.CME, Ticker, SecurityType.Future);
var exchangeHours = new SecurityExchangeHours(ExchangeTimeZone,
_originalMhdbEntry.ExchangeHours.Holidays,
_originalMhdbEntry.ExchangeHours.MarketHours.ToDictionary(),
_originalMhdbEntry.ExchangeHours.EarlyCloses,
_originalMhdbEntry.ExchangeHours.LateOpens);
MarketHoursDatabase.SetEntry(Market.CME, Ticker, SecurityType.Future, exchangeHours, DataTimeZone);
SetTimeZone(ExchangeTimeZone);
_continuousContract = AddFuture(Ticker,
Resolution,
extendedMarketHours: true,
dataNormalizationMode: DataNormalizationMode.Raw,
dataMappingMode: DataMappingMode.OpenInterest,
contractDepthOffset: 0
);
SetBenchmark(x => 0);
}
public override void OnData(Slice slice)
{
try
{
var receivedRollover = false;
foreach (var (symbol, symbolChangedEvent) in slice.SymbolChangedEvents)
{
if (RolloverHappened)
{
throw new RegressionTestException($"[{Time}] -- Unexpected symbol changed event for {symbol}. Expected only one mapping.");
}
receivedRollover = true;
_rolloverTime = symbolChangedEvent.EndTime;
var oldSymbol = symbolChangedEvent.OldSymbol;
var newSymbol = symbolChangedEvent.NewSymbol;
Debug($"[{Time}] -- Rollover: {oldSymbol} -> {newSymbol}");
if (symbol != _continuousContract.Symbol)
{
throw new RegressionTestException($"[{Time}] -- Unexpected symbol changed event for {symbol}");
}
var expectedMappingDate = new DateTime(2013, 12, 18);
if (_rolloverTime != expectedMappingDate)
{
throw new RegressionTestException($"[{Time}] -- Unexpected date {_rolloverTime}. Expected {expectedMappingDate}");
}
var expectedMappingOldSymbol = "ES VMKLFZIH2MTD";
var expectedMappingNewSymbol = "ES VP274HSU1AF5";
if (symbolChangedEvent.OldSymbol != expectedMappingOldSymbol || symbolChangedEvent.NewSymbol != expectedMappingNewSymbol)
{
throw new RegressionTestException($"[{Time}] -- Unexpected mapping. " +
$"Expected {expectedMappingOldSymbol} -> {expectedMappingNewSymbol} " +
$"but was {symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.NewSymbol}");
}
}
var mappedFuture = Securities[_continuousContract.Mapped];
var mappedFuturePrice = mappedFuture.Price;
var otherFuture = Securities.Values.SingleOrDefault(x => !x.Symbol.IsCanonical() && x.Symbol != _continuousContract.Mapped);
var otherFuturePrice = otherFuture?.Price;
var continuousContractPrice = _continuousContract.Price;
Debug($"[{Time}] Contracts prices:\n" +
$" -- Mapped future: {mappedFuture.Symbol} :: {mappedFuture.Price} :: {mappedFuture.GetLastData()}\n" +
$" -- Other future: {otherFuture?.Symbol} :: {otherFuture?.Price} :: {otherFuture?.GetLastData()}\n" +
$" -- Mapped future from continuous contract: {_continuousContract.Symbol} :: {_continuousContract.Mapped} :: " +
$"{_continuousContract.Price} :: {_continuousContract.GetLastData()}\n");
if (receivedRollover)
{
if (continuousContractPrice != otherFuturePrice)
{
var continuousContractLastData = _continuousContract.GetLastData();
throw new RegressionTestException($"[{Time}] -- Prices do not match. " +
$"At the time of the rollover, expected continuous future price to be the same as " +
$"the previously mapped contract since no data for the new mapped contract has been received:\n" +
$" Continuous contract ({_continuousContract.Symbol}) price: " +
$"{continuousContractPrice} :: {continuousContractLastData.Symbol.Underlying} :: " +
$"{continuousContractLastData.Time} - {continuousContractLastData.EndTime} :: {continuousContractLastData}. \n" +
$" Mapped contract ({mappedFuture.Symbol}) price: {mappedFuturePrice} :: {mappedFuture.GetLastData()}. \n" +
$" Other contract ({otherFuture?.Symbol}) price: {otherFuturePrice} :: {otherFuture?.GetLastData()}\n");
}
}
else if (mappedFuturePrice != 0 || !RolloverHappened)
{
if (continuousContractPrice != mappedFuturePrice)
{
var continuousContractLastData = _continuousContract.GetLastData();
throw new RegressionTestException($"[{Time}] -- Prices do not match. " +
$"Expected continuous future price to be the same as the mapped contract:\n" +
$" Continuous contract ({_continuousContract.Symbol}) price: {continuousContractPrice} :: " +
$"{continuousContractLastData.Symbol.Underlying} :: {continuousContractLastData}. \n" +
$" Mapped contract ({mappedFuture.Symbol}) price: {mappedFuturePrice} :: {mappedFuture.GetLastData()}. \n" +
$" Other contract ({otherFuture?.Symbol}) price: {otherFuturePrice} :: {otherFuture?.GetLastData()}\n");
}
}
// No data for the mapped future yet after rollover
else
{
if (otherFuture == null)
{
throw new RegressionTestException($"[{Time}] --" +
$" Mapped future price is 0 (no data has arrived) so the previous mapped contract is expected to be there");
}
var continuousContractLastData = _continuousContract.GetLastData();
if (continuousContractLastData.EndTime > _rolloverTime)
{
throw new RegressionTestException($"[{Time}] -- Expected continuous future contract last data to be from the previously " +
$"mapped contract until the new mapped contract gets data:\n" +
$" Rollover time: {_rolloverTime}\n" +
$" Continuous contract ({_continuousContract.Symbol}) last data: " +
$"{continuousContractLastData.Symbol.Underlying} :: " +
$"{continuousContractLastData.Time} - {continuousContractLastData.EndTime} :: {continuousContractLastData}.");
}
}
}
catch (Exception ex)
{
ResetMarketHoursDatabase();
throw;
}
}
public override void OnEndOfAlgorithm()
{
ResetMarketHoursDatabase();
if (!RolloverHappened)
{
throw new RegressionTestException($"[{Time}] -- Rollover did not happen.");
}
}
private void ResetMarketHoursDatabase()
{
MarketHoursDatabase.SetEntry(Market.CME, Ticker, SecurityType.Future, _originalMhdbEntry.ExchangeHours, _originalMhdbEntry.DataTimeZone);
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 0;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
}
}

View File

@@ -0,0 +1,38 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using NodaTime;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data.
/// The algorithms asserts the behavior for the case when the exchange time zone is ahead of the data time zone.
/// </summary>
public class ContinuousFutureRolloverDailyExchangeTimeZoneAheadOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Daily;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1014;
}
}

View File

@@ -0,0 +1,38 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using NodaTime;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data.
/// The algorithms asserts the behavior for the case when the exchange time zone is behind of the data time zone.
/// </summary>
public class ContinuousFutureRolloverDailyExchangeTimeZoneBehindOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Daily;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1004;
}
}

View File

@@ -0,0 +1,38 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using NodaTime;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data.
/// The algorithms asserts the behavior for the case when the data time zone is the same as the exchange time zone.
/// </summary>
public class ContinuousFutureRolloverDailyExchangeTimeZoneSameAsDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Daily;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1007;
}
}

View File

@@ -0,0 +1,38 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using NodaTime;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data.
/// The algorithms asserts the behavior for the case when the exchange time zone is ahead of the data time zone.
/// </summary>
public class ContinuousFutureRolloverHourExchangeTimeZoneAheadOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Hour;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 18850;
}
}

View File

@@ -0,0 +1,38 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using NodaTime;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Base class for regression algorithms testing that when a continuous future rollover happens,
/// the continuous contract is updated correctly with the new contract data.
/// The algorithms asserts the behavior for the case when the exchange time zone is behind of the data time zone.
/// </summary>
public class ContinuousFutureRolloverHourExchangeTimeZoneBehindOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Hour;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 18844;
}
}

Some files were not shown because too many files have changed in this diff Show More