Compare commits

..

166 Commits
16632 ... 17006

Author SHA1 Message Date
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
626 changed files with 73823 additions and 8486 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

@@ -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

@@ -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

@@ -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

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(option);
foreach (var symbol in new[] { option.Symbol, option.Underlying.Symbol })
foreach (var symbol in new[] { option.Symbol, option.UnderlyingSymbol })
{
var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList();

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

@@ -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

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

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

@@ -56,7 +56,7 @@ namespace QuantConnect.Algorithm.CSharp
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
_mappedSymbol = _continuousContract.Mapped;
var benchmark = AddIndex("SX5E", market: Market.EUREX);
var benchmark = AddIndex("SX5E");
SetBenchmark(benchmark.Symbol);
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
@@ -190,7 +190,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 133945;
public long DataPoints => 133947;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -176,7 +176,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1190;
public long DataPoints => 1185;
/// <summary>
/// Data Points count of the algorithm history
@@ -219,7 +219,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "0.13%"},
{"OrderListHash", "273dd05b937c075b75baf8af46d3c7de"}
{"OrderListHash", "7c8700a9baa24f6f76d866e7d88cc19c"}
};
}
}

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 12452;
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", "32"},
{"Total Orders", "34"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Compounding Annual Return", "0.106%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.184"},
{"Expectancy", "0.178"},
{"Start Equity", "1000000"},
{"End Equity", "1001108"},
{"Net Profit", "0.111%"},
{"Sharpe Ratio", "-1.688"},
{"Sortino Ratio", "-0.772"},
{"Probabilistic Sharpe Ratio", "14.944%"},
{"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", "8.47"},
{"Profit-Loss Ratio", "9.01"},
{"Alpha", "-0.007"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Treynor Ratio", "-4.112"},
{"Total Fees", "$76.30"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "168731c8f3a19f230cc1410818b3b573"}
{"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,7 +41,7 @@ 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

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 => 14790;
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", "36"},
{"Total Orders", "32"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "0.102%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.171"},
{"Expectancy", "0.184"},
{"Start Equity", "1000000"},
{"End Equity", "1001024.4"},
{"Net Profit", "0.102%"},
{"Sharpe Ratio", "-1.702"},
{"Sortino Ratio", "-0.836"},
{"Probabilistic Sharpe Ratio", "14.653%"},
{"Loss Rate", "89%"},
{"Win Rate", "11%"},
{"Profit-Loss Ratio", "9.54"},
{"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.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-4.126"},
{"Total Fees", "$80.60"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.97%"},
{"OrderListHash", "52c852d720692fab1e12212b2aba03d4"}
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "ea6fdf3133bde7063e4fc0fa809ae260"}
};
}
}

View File

@@ -41,7 +41,7 @@ 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

View File

@@ -70,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}");
}
@@ -106,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
@@ -126,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

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

View File

@@ -121,20 +121,20 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "0%"},
{"Average Loss", "-0.69%"},
{"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", "2.62"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "63.221%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "23.22"},
{"Alpha", "0.067"},
{"Beta", "-0.013"},
{"Annual Standard Deviation", "0.004"},

View File

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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 => 9951;
public virtual long DataPoints => 9953;
/// <summary>
/// Data Points count of the algorithm history

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;
}
}

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 ContinuousFutureRolloverHourExchangeTimeZoneSameAsDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Hour;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 18846;
}
}

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 ContinuousFutureRolloverMinuteExchangeTimeZoneAheadOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Minute;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1127376;
}
}

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 ContinuousFutureRolloverMinuteExchangeTimeZoneBehindOfDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Minute;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1127374;
}
}

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 ContinuousFutureRolloverMinuteExchangeTimeZoneSameAsDataRegressionAlgorithm
: ContinuousFutureRolloverBaseRegressionAlgorithm
{
protected override Resolution Resolution => Resolution.Minute;
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1127488;
}
}

View File

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

View File

@@ -0,0 +1,134 @@
/*
* 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.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Compares two correlation types and asserts they are not equal during the algorithm's execution.
/// </summary>
public class CorrelationTypeComparisonRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Correlation _correlationPearson;
private Correlation _correlationSpearman;
/// <summary>
/// Initialise the data and resolution required, as well as the start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 08); //Set Start Date
SetEndDate(2013, 10, 17); //Set End Date
var symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
var spy = AddEquity("SPY", Resolution.Daily).Symbol;
_correlationPearson = C(symbol, spy, 5, CorrelationType.Pearson);
_correlationSpearman = C(symbol, spy, 5, CorrelationType.Spearman);
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (_correlationPearson.IsReady && _correlationSpearman.IsReady)
{
var pearsonValue = _correlationPearson.Current.Value;
var spearmanValue = _correlationSpearman.Current.Value;
// Check that the correlation values are not the same
if (pearsonValue == spearmanValue)
{
// Throw an exception if the correlation values are equal
throw new RegressionTestException($"Error: Pearson and Spearman correlation values are the same: Pearson = {pearsonValue}, Spearman = {spearmanValue}. This should not happen.");
}
}
}
/// <summary>
/// End of algorithm run event handler. This method is called at the end of a backtest or live trading operation. Intended for closing out logs.
/// </summary>
public override void OnEndOfAlgorithm()
{
if (!_correlationPearson.IsReady || !_correlationSpearman.IsReady)
{
throw new RegressionTestException("Error: Both correlation values should be ready at the end of the algorithm.");
}
}
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <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 => 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 long DataPoints => 80;
/// <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", "-19.184"},
{"Tracking Error", "0.138"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -40,8 +40,8 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public override void Initialize()
{
SetStartDate(2011, 9, 13);
SetEndDate(2015, 12, 01);
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 10);
//Set the cash for the strategy:
SetCash(100000);
@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 10491;
public long DataPoints => 57;
/// <summary>
/// Data Points count of the algorithm history
@@ -129,30 +129,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "155.211%"},
{"Drawdown", "84.800%"},
{"Compounding Annual Return", "34781.071%"},
{"Drawdown", "4.300%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "5223241.65"},
{"Net Profit", "5123.242%"},
{"Sharpe Ratio", "2.058"},
{"Sortino Ratio", "2.492"},
{"Probabilistic Sharpe Ratio", "68.833%"},
{"End Equity", "110102.2"},
{"Net Profit", "10.102%"},
{"Sharpe Ratio", "283.719"},
{"Sortino Ratio", "1123.876"},
{"Probabilistic Sharpe Ratio", "81.716%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "1.724"},
{"Beta", "0.043"},
{"Annual Standard Deviation", "0.841"},
{"Annual Variance", "0.707"},
{"Information Ratio", "1.902"},
{"Tracking Error", "0.848"},
{"Treynor Ratio", "40.293"},
{"Alpha", "184.11"},
{"Beta", "-6.241"},
{"Annual Standard Deviation", "0.635"},
{"Annual Variance", "0.403"},
{"Information Ratio", "260.511"},
{"Tracking Error", "0.689"},
{"Treynor Ratio", "-28.849"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
{"Portfolio Turnover", "0.06%"},
{"OrderListHash", "999305e00ec9861f5ff261794e81213d"}
{"Portfolio Turnover", "16.73%"},
{"OrderListHash", "b890a8e73bf118e943ad2f2e712f12d0"}
};
/// <summary>
@@ -168,6 +168,7 @@ namespace QuantConnect.Algorithm.CSharp
public decimal High { get; set; }
[JsonProperty("low")]
public decimal Low { get; set; }
public decimal Mid { get; set; }
[JsonProperty("last")]
public decimal Close { get; set; }
[JsonProperty("bid")]
@@ -217,7 +218,10 @@ namespace QuantConnect.Algorithm.CSharp
//return "http://my-ftp-server.com/futures-data-" + date.ToString("Ymd") + ".zip";
// OR simply return a fixed small data file. Large files will slow down your backtest
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/quandl/api/v3/datasets/BCHARTS/BITSTAMPUSD.csv?order=asc&api_key=WyAazVXnq7ATy_fefTqm", SubscriptionTransportMedium.RemoteFile);
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=WyAazVXnq7ATy_fefTqm")
{
Sort = true
};
}
/// <summary>
@@ -248,20 +252,20 @@ namespace QuantConnect.Algorithm.CSharp
}
//Example Line Format:
//Date Open High Low Close Volume (BTC) Volume (Currency) Weighted Price
//2011-09-13 5.8 6.0 5.65 5.97 58.37138238, 346.0973893944 5.929230648356
// code date high low mid last bid ask volume
// BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 5.929230648356
try
{
string[] data = line.Split(',');
coin.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture);
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
coin.EndTime = coin.Time.AddDays(1);
coin.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture);
coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
coin.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture);
coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
coin.VolumeUSD = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
coin.WeightedPrice = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
coin.Mid = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
coin.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
coin.Bid = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
coin.Ask = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
coin.VolumeBTC = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture);
coin.Value = coin.Close;
}
catch { /* Do nothing, skip first title row */ }

View File

@@ -33,15 +33,15 @@ namespace QuantConnect.Algorithm.CSharp
/// <meta name="tag" content="regression test" />
public class CustomDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private bool _warmedUpChecked = false;
private bool _warmedUpChecked;
/// <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(2011, 9, 14);
SetEndDate(2015, 12, 01);
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 10);
//Set the cash for the strategy:
SetCash(100000);
@@ -110,7 +110,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 8943;
public long DataPoints => 50;
/// <summary>
/// Data Points count of the algorithm history
@@ -130,30 +130,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "155.365%"},
{"Drawdown", "84.800%"},
{"Compounding Annual Return", "27587.925%"},
{"Drawdown", "4.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "5223170.23"},
{"Net Profit", "5123.170%"},
{"Sharpe Ratio", "2.094"},
{"Sortino Ratio", "2.535"},
{"Probabilistic Sharpe Ratio", "69.967%"},
{"End Equity", "109685"},
{"Net Profit", "9.685%"},
{"Sharpe Ratio", "238.834"},
{"Sortino Ratio", "945.079"},
{"Probabilistic Sharpe Ratio", "81.660%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "1.753"},
{"Beta", "0.055"},
{"Annual Standard Deviation", "0.84"},
{"Annual Variance", "0.706"},
{"Information Ratio", "1.942"},
{"Tracking Error", "0.848"},
{"Treynor Ratio", "32.18"},
{"Alpha", "149.482"},
{"Beta", "-6.002"},
{"Annual Standard Deviation", "0.61"},
{"Annual Variance", "0.371"},
{"Information Ratio", "218.36"},
{"Tracking Error", "0.664"},
{"Treynor Ratio", "-24.253"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
{"Portfolio Turnover", "0.06%"},
{"OrderListHash", "e69e78cd6fe7bc4627da2f51e25539d0"}
{"Portfolio Turnover", "16.03%"},
{"OrderListHash", "dde8821614d33c89e6e75c536447b7da"}
};
/// <summary>
@@ -169,6 +169,8 @@ namespace QuantConnect.Algorithm.CSharp
public decimal High { get; set; }
[JsonProperty("low")]
public decimal Low { get; set; }
public decimal Mid { get; set; }
[JsonProperty("last")]
public decimal Close { get; set; }
[JsonProperty("bid")]
@@ -179,7 +181,6 @@ namespace QuantConnect.Algorithm.CSharp
public decimal WeightedPrice { get; set; }
[JsonProperty("volume")]
public decimal VolumeBTC { get; set; }
public decimal VolumeUSD { get; set; }
/// <summary>
/// The end time of this data. Some data covers spans (trade bars)
@@ -218,7 +219,10 @@ namespace QuantConnect.Algorithm.CSharp
//return "http://my-ftp-server.com/futures-data-" + date.ToString("Ymd") + ".zip";
// OR simply return a fixed small data file. Large files will slow down your backtest
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/quandl/api/v3/datasets/BCHARTS/BITSTAMPUSD.csv?order=asc&api_key=WyAazVXnq7ATy_fefTqm", SubscriptionTransportMedium.RemoteFile);
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=qAWKpUfmSVFnU3bRQwKy")
{
Sort = true
};
}
/// <summary>
@@ -249,20 +253,20 @@ namespace QuantConnect.Algorithm.CSharp
}
//Example Line Format:
//Date Open High Low Close Volume (BTC) Volume (Currency) Weighted Price
//2011-09-13 5.8 6.0 5.65 5.97 58.37138238, 346.0973893944 5.929230648356
// code date high low mid last bid ask volume
// BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 477.91102114
try
{
string[] data = line.Split(',');
coin.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture);
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
coin.EndTime = coin.Time.AddDays(1);
coin.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture);
coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
coin.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture);
coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
coin.VolumeUSD = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
coin.WeightedPrice = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
coin.Mid = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
coin.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
coin.Bid = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
coin.Ask = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
coin.VolumeBTC = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture);
coin.Value = coin.Close;
}
catch { /* Do nothing, skip first title row */ }

View File

@@ -0,0 +1,130 @@
/*
* 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.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
/// Reproduces GH issue #8421.
/// </summary>
public class DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _symbol;
private List<decimal> _openInterests = new();
public virtual bool DailyPreciseEndTime => true;
public override void Initialize()
{
Settings.DailyPreciseEndTime = DailyPreciseEndTime;
SetStartDate(2014, 06, 01);
SetEndDate(2014, 07, 06);
var option = AddOption("AAPL", Resolution.Daily);
option.SetFilter(-5, +5, 0, 365);
_symbol = option.Symbol;
}
public override void OnData(Slice slice)
{
if (slice.OptionChains.TryGetValue(_symbol, out var chain) && chain.Contracts.Count > 0)
{
var openInterest = chain.Sum(x => x.OpenInterest);
_openInterests.Add(openInterest);
Debug($"[{Time}] Sum of open interest: {openInterest}");
}
}
public override void OnEndOfAlgorithm()
{
if (_openInterests.Count == 0)
{
throw new RegressionTestException("No option chain data was received by the algorithm.");
}
if (_openInterests.All(x => x == 0))
{
throw new RegressionTestException("Contracts received didn't have valid open interest values.");
}
}
/// <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 => 47132;
/// <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", "-5.732"},
{"Tracking Error", "0.05"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.
*/
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
/// Reproduces GH issue #8421.
/// </summary>
public class DailyOptionChainOpenInterestDataWithoutStrictDailyEndTimesRegressionAlgorithm : DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm
{
public override bool DailyPreciseEndTime => false;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 46264;
}
}

View File

@@ -28,7 +28,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 1679;
public override long DataPoints => 1690;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
@@ -38,7 +38,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "2"},
{"Average Win", "7.78%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "38.564%"},
{"Compounding Annual Return", "38.609%"},
{"Drawdown", "0.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

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

View File

@@ -0,0 +1,211 @@
/*
* 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.Linq;
using QuantConnect.Data;
using System.Globalization;
using QuantConnect.Interfaces;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// The regression algorithm showcases the utilization of a custom data source with the Sort flag set to true.
/// This means that the source initially provides data in descending order, which is then organized into ascending order and returned in the <see cref="OnData(Slice)"/> function.
/// </summary>
public class DescendingCustomDataObjectStoreRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
protected virtual string CustomDataKey => "CustomData/SortCustomData";
protected readonly static string[] descendingCustomData = new string[]
{
"2024-10-03 19:00:00,173.5,176.0,172.0,175.2,120195681,4882.29",
"2024-10-02 18:00:00,174.0,177.0,173.0,175.8,116275729,4641.97",
"2024-10-01 17:00:00,175.0,178.0,172.5,174.5,127707078,6591.27",
"2024-09-30 11:00:00,174.8,176.5,172.8,175.0,127707078,6591.27",
"2024-09-27 10:00:00,172.5,175.0,171.5,173.5,120195681,4882.29",
"2024-09-26 09:00:00,171.0,172.5,170.0,171.8,117516350,4820.53",
"2024-09-25 08:00:00,169.5,172.0,169.0,171.0,110427867,4661.55",
"2024-09-24 07:00:00,170.0,171.0,168.0,169.5,127624733,4823.52",
"2024-09-23 06:00:00,172.0,173.5,169.5,171.5,123586417,4303.93",
"2024-09-20 05:00:00,168.0,171.0,167.5,170.5,151929179,5429.87",
"2024-09-19 04:00:00,170.5,171.5,166.0,167.0,160523863,5219.24",
"2024-09-18 03:00:00,173.0,174.0,169.0,172.0,145721790,5163.09",
"2024-09-17 02:00:00,171.0,173.5,170.0,172.5,144794030,5405.72",
"2024-09-16 01:00:00,168.0,171.0,167.0,170.0,214402430,8753.33",
"2024-09-13 16:00:00,173.5,176.0,172.0,175.2,120195681,4882.29",
"2024-09-12 15:00:00,174.5,177.5,173.5,176.5,171728134,7774.83",
"2024-09-11 14:00:00,175.0,178.0,174.0,175.5,191516153,8349.59",
"2024-09-10 13:00:00,174.5,176.0,173.0,174.0,151162819,5915.8",
"2024-09-09 12:00:00,176.0,178.0,175.0,177.0,116275729,4641.97"
};
private Symbol _customSymbol;
private List<SortCustomData> _receivedData = new();
public override void Initialize()
{
SetStartDate(2024, 09, 09);
SetEndDate(2024, 10, 03);
SetCash(100000);
SetBenchmark(x => 0);
SortCustomData.CustomDataKey = CustomDataKey;
_customSymbol = AddData<SortCustomData>("SortCustomData", Resolution.Daily).Symbol;
// Saving data here for demonstration and regression testing purposes.
// In real scenarios, data has to be saved to the object store before the algorithm starts.
ObjectStore.Save(CustomDataKey, string.Join("\n", descendingCustomData));
}
public override void OnData(Slice slice)
{
if (slice.ContainsKey(_customSymbol))
{
var sortCustomData = slice.Get<SortCustomData>(_customSymbol);
if (sortCustomData.Open == 0 || sortCustomData.High == 0 || sortCustomData.Low == 0 || sortCustomData.Close == 0 || sortCustomData.Price == 0)
{
throw new RegressionTestException("One or more custom data fields (Open, High, Low, Close, Price) are zero.");
}
_receivedData.Add(sortCustomData);
}
}
public override void OnEndOfAlgorithm()
{
if (_receivedData.Count == 0)
{
throw new RegressionTestException("Custom data was not fetched");
}
var history = History<SortCustomData>(_customSymbol, StartDate, EndDate, Resolution.Hour).ToList();
if (history.Count != _receivedData.Count)
{
throw new RegressionTestException("History request returned different data than expected");
}
// Iterate through the history collection, checking if the EndTime is in ascending order.
for (int i = 0; i < history.Count - 1; i++)
{
if (history[i].EndTime > history[i + 1].EndTime)
{
throw new RegressionTestException($"Order failure: {history[i].EndTime} > {history[i + 1].EndTime} at index {i}.");
}
}
}
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <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 => true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages => new() { Language.CSharp, Language.Python };
/// <summary>
/// Data Points count of all TimeSlices of algorithm
/// </summary>
public long DataPoints => 20;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 19;
/// <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 ()
{
{"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 class SortCustomData : BaseData
{
public static string CustomDataKey { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
{
return new SubscriptionDataSource(CustomDataKey, SubscriptionTransportMedium.ObjectStore, FileFormat.Csv)
{
// Indicate that the data from the subscription will be returned in descending order.
Sort = true
};
}
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
{
var csv = line.Split(",");
var data = new SortCustomData()
{
Symbol = config.Symbol,
Time = DateTime.ParseExact(csv[0], DateFormat.DB, CultureInfo.InvariantCulture),
Value = csv[4].ToDecimal(),
Open = csv[1].ToDecimal(),
High = csv[2].ToDecimal(),
Low = csv[3].ToDecimal(),
Close = csv[4].ToDecimal()
};
return data;
}
}
}

View File

@@ -117,6 +117,16 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException("Expected to try to exercise option before and on expiry");
}
var optionHoldings = Securities[_contract.Symbol].Holdings;
if (optionHoldings.NetProfit != Portfolio.TotalNetProfit)
{
throw new RegressionTestException($"Unexpected holdings profit result {optionHoldings.Profit}");
}
if (Portfolio.Cash != (Portfolio.TotalNetProfit + 200000))
{
throw new RegressionTestException($"Unexpected portfolio cash {Portfolio.Cash}");
}
}
/// <summary>
@@ -150,8 +160,8 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-4.10%"},
{"Average Win", "0.68%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "24.075%"},
{"Drawdown", "1.900%"},
{"Expectancy", "0"},

View File

@@ -25,21 +25,25 @@ namespace QuantConnect.Algorithm.CSharp
{
protected override bool ExtendedMarketHours => true;
protected override List<DateTime> AfterMarketOpen => new List<DateTime>() {
new DateTime(2020, 02, 04, 18, 0, 0), // Tuesday
new DateTime(2020, 02, 05, 18, 0, 0),
new DateTime(2020, 02, 06, 18, 0, 0),
new DateTime(2020, 02, 09, 18, 0, 0),
new DateTime(2020, 02, 10, 18, 0, 0),
new DateTime(2020, 02, 11, 18, 0, 0)
new DateTime(2020, 02, 04, 0, 0, 0), // Tuesday
new DateTime(2020, 02, 05, 0, 0, 0),
new DateTime(2020, 02, 06, 0, 0, 0),
new DateTime(2020, 02, 07, 0, 0, 0),
new DateTime(2020, 02, 09, 18, 0, 0), // sunday
new DateTime(2020, 02, 10, 0, 0, 0),
new DateTime(2020, 02, 11, 0, 0, 0),
new DateTime(2020, 02, 12, 0, 0, 0)
};
protected override List<DateTime> BeforeMarketClose => new List<DateTime>()
{
new DateTime(2020, 02, 04, 17, 0, 0),
new DateTime(2020, 02, 05, 17, 0, 0),
new DateTime(2020, 02, 06, 17, 0, 0),
new DateTime(2020, 02, 07, 17, 0, 0),
new DateTime(2020, 02, 10, 17, 0, 0),
new DateTime(2020, 02, 11, 17, 0, 0)
new DateTime(2020, 02, 04, 0, 0, 0),
new DateTime(2020, 02, 05, 0, 0, 0),
new DateTime(2020, 02, 06, 0, 0, 0),
new DateTime(2020, 02, 07, 0, 0, 0),
new DateTime(2020, 02, 07, 17, 0, 0), // friday
new DateTime(2020, 02, 10, 0, 0, 0),
new DateTime(2020, 02, 11, 0, 0, 0),
new DateTime(2020, 02, 12, 0, 0, 0)
};
/// <summary>
@@ -50,7 +54,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 41466;
public override long DataPoints => 41467;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm

View File

@@ -57,6 +57,7 @@ namespace QuantConnect.Algorithm.CSharp
SetStartDate(2013, 10, 06);
SetEndDate(2013, 10, 14);
Settings.DailyConsolidationUseExtendedMarketHours = true;
var es = AddSecurity(SecurityType.Future, "ES", extendedMarketHours: ExtendedMarketHours);
_expectedOpensQueue = new Queue<DateTime>(ExpectedOpens);
@@ -93,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 32071;
public virtual long DataPoints => 32073;
/// </summary>
/// Data Points count of the algorithm history

View File

@@ -29,19 +29,24 @@ namespace QuantConnect.Algorithm.CSharp
protected override bool ExtendedMarketHours => true;
protected override List<DateTime> ExpectedOpens => new List<DateTime>(){
new DateTime(2013, 10, 06, 18, 0, 0), // Sunday
new DateTime(2013, 10, 07, 18, 0, 0),
new DateTime(2013, 10, 08, 18, 0, 0),
new DateTime(2013, 10, 09, 18, 0, 0),
new DateTime(2013, 10, 10, 18, 0, 0),
// market is open for the whole day, so goes from midnight to midnight
new DateTime(2013, 10, 07, 0, 0, 0),
new DateTime(2013, 10, 08, 0, 0, 0),
new DateTime(2013, 10, 09, 0, 0, 0),
new DateTime(2013, 10, 10, 0, 0, 0),
new DateTime(2013, 10, 11, 0, 0, 0),
new DateTime(2013, 10, 13, 18, 0, 0),
new DateTime(2013, 10, 14, 0, 0, 0),
};
protected override List<DateTime> ExpectedCloses => new List<DateTime>(){
new DateTime(2013, 10, 07, 17, 0, 0),
new DateTime(2013, 10, 08, 17, 0, 0),
new DateTime(2013, 10, 09, 17, 0, 0),
new DateTime(2013, 10, 10, 17, 0, 0),
new DateTime(2013, 10, 11, 17, 0, 0),
new DateTime(2013, 10, 14, 17, 0, 0),
new DateTime(2013, 10, 07, 0, 0, 0),
new DateTime(2013, 10, 08, 0, 0, 0),
new DateTime(2013, 10, 09, 0, 0, 0),
new DateTime(2013, 10, 10, 0, 0, 0),
new DateTime(2013, 10, 11, 0, 0, 0),
new DateTime(2013, 10, 11, 17, 0, 0), // friday
new DateTime(2013, 10, 14, 0, 0, 0),
new DateTime(2013, 10, 15, 0, 0, 0),
};
/// <summary>
@@ -52,7 +57,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 103816;
public override long DataPoints => 103818;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm

View File

@@ -112,7 +112,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 309280;
public long DataPoints => 309282;
/// <summary>
/// Data Points count of the algorithm history
@@ -150,7 +150,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.005"},
{"Information Ratio", "-0.134"},
{"Tracking Error", "0.385"},
{"Treynor Ratio", "3.784"},
{"Treynor Ratio", "3.785"},
{"Total Fees", "$2.84"},
{"Estimated Strategy Capacity", "$120000000.00"},
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},

View File

@@ -200,7 +200,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -238,7 +238,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.004"},
{"Information Ratio", "-0.226"},
{"Tracking Error", "0.378"},
{"Treynor Ratio", "-21.838"},
{"Treynor Ratio", "-21.841"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$120000000.00"},
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},

View File

@@ -165,7 +165,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -203,7 +203,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.098"},
{"Information Ratio", "-0.649"},
{"Tracking Error", "0.483"},
{"Treynor Ratio", "-18.589"},
{"Treynor Ratio", "-18.59"},
{"Total Fees", "$7.10"},
{"Estimated Strategy Capacity", "$24000000.00"},
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},

View File

@@ -176,7 +176,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -214,7 +214,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.003"},
{"Information Ratio", "-0.198"},
{"Tracking Error", "0.377"},
{"Treynor Ratio", "-23.06"},
{"Treynor Ratio", "-23.065"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$180000000.00"},
{"Lowest Capacity Asset", "ES XFH59UPHGV9G|ES XFH59UK0MYO1"},

View File

@@ -22,7 +22,7 @@ namespace QuantConnect.Algorithm.CSharp
{
public class FutureOptionIndicatorsRegressionAlgorithm : OptionIndicatorsRegressionAlgorithm
{
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.14008,Delta: 0.63466,Gamma: 0.00209,Vega: 5.61442,Theta: -0.48254,Rho: 0.03098";
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.13941,Delta: 0.63509,Gamma: 0.00209,Vega: 5.64129,Theta: -0.47731,Rho: 0.03145";
public override void Initialize()
{

View File

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

View File

@@ -201,7 +201,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -239,7 +239,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.003"},
{"Information Ratio", "-0.248"},
{"Tracking Error", "0.377"},
{"Treynor Ratio", "-36.295"},
{"Treynor Ratio", "-36.3"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$79000000.00"},
{"Lowest Capacity Asset", "ES 31EL5FAOOQON8|ES XFH59UK0MYO1"},

View File

@@ -174,7 +174,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -212,7 +212,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.003"},
{"Information Ratio", "-0.249"},
{"Tracking Error", "0.377"},
{"Treynor Ratio", "-32.551"},
{"Treynor Ratio", "-32.556"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$290000000.00"},
{"Lowest Capacity Asset", "ES 31EL5FBZBMXES|ES XFH59UK0MYO1"},

View File

@@ -185,7 +185,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -223,7 +223,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.002"},
{"Information Ratio", "0.064"},
{"Tracking Error", "0.378"},
{"Treynor Ratio", "-13.132"},
{"Treynor Ratio", "-13.127"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$13000000.00"},
{"Lowest Capacity Asset", "ES XFH59UP5K75W|ES XFH59UK0MYO1"},

View File

@@ -168,7 +168,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -194,7 +194,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Start Equity", "100000"},
{"End Equity", "101736.08"},
{"Net Profit", "1.736%"},
{"Sharpe Ratio", "0.597"},
{"Sharpe Ratio", "0.596"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "49.736%"},
{"Loss Rate", "0%"},
@@ -206,7 +206,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.001"},
{"Information Ratio", "0.009"},
{"Tracking Error", "0.375"},
{"Treynor Ratio", "-11.057"},
{"Treynor Ratio", "-11.048"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$100000000.00"},
{"Lowest Capacity Asset", "ES XFH59UPNF7B8|ES XFH59UK0MYO1"},

View File

@@ -182,7 +182,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -220,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.001"},
{"Information Ratio", "0.058"},
{"Tracking Error", "0.375"},
{"Treynor Ratio", "-41.846"},
{"Treynor Ratio", "-41.831"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$12000000.00"},
{"Lowest Capacity Asset", "ES 31EL5FAOUP0P0|ES XFH59UK0MYO1"},

View File

@@ -167,7 +167,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212195;
public long DataPoints => 212196;
/// <summary>
/// Data Points count of the algorithm history
@@ -193,7 +193,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Start Equity", "100000"},
{"End Equity", "103423.58"},
{"Net Profit", "3.424%"},
{"Sharpe Ratio", "1.089"},
{"Sharpe Ratio", "1.088"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "73.287%"},
{"Loss Rate", "0%"},
@@ -205,7 +205,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0.001"},
{"Information Ratio", "0.075"},
{"Tracking Error", "0.377"},
{"Treynor Ratio", "-24.083"},
{"Treynor Ratio", "-24.076"},
{"Total Fees", "$1.42"},
{"Estimated Strategy Capacity", "$110000000.00"},
{"Lowest Capacity Asset", "ES 31EL5FAJQ6SBO|ES XFH59UK0MYO1"},

View File

@@ -113,7 +113,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all time slices of algorithm
/// </summary>
public long DataPoints => 75960;
public long DataPoints => 75961;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -178,7 +178,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 212941;
public long DataPoints => 212942;
/// <summary>
/// Data Points count of the algorithm history
@@ -204,7 +204,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Start Equity", "100000"},
{"End Equity", "98233.93"},
{"Net Profit", "-1.766%"},
{"Sharpe Ratio", "-1.14"},
{"Sharpe Ratio", "-1.141"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0.020%"},
{"Loss Rate", "50%"},
@@ -216,7 +216,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Annual Variance", "0"},
{"Information Ratio", "-0.602"},
{"Tracking Error", "0.291"},
{"Treynor Ratio", "-16.64"},
{"Treynor Ratio", "-16.65"},
{"Total Fees", "$3.57"},
{"Estimated Strategy Capacity", "$16000000.00"},
{"Lowest Capacity Asset", "ES XFH59UK0MYO1"},

View File

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

View File

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

View File

@@ -0,0 +1,80 @@
/*
* 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.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm using and testing HSI futures and index
/// </summary>
public class HSIFutureDailyRegressionAlgorithm : HSIFutureHourRegressionAlgorithm
{
/// <summary>
/// The data resolution
/// </summary>
protected override Resolution Resolution => Resolution.Daily;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 177;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 12;
/// <summary>
/// Final status of the algorithm
/// </summary>
public override 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 override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "15"},
{"Average Win", "0%"},
{"Average Loss", "-0.33%"},
{"Compounding Annual Return", "-55.187%"},
{"Drawdown", "2.400%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},
{"End Equity", "97610"},
{"Net Profit", "-2.390%"},
{"Sharpe Ratio", "-15.799"},
{"Sortino Ratio", "-19.207"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0.029"},
{"Annual Variance", "0.001"},
{"Information Ratio", "-15.544"},
{"Tracking Error", "0.029"},
{"Treynor Ratio", "0"},
{"Total Fees", "$600.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "HSI VL6DN7UV65S9"},
{"Portfolio Turnover", "1590.77%"},
{"OrderListHash", "42cd8e3b58361b181c911a603f69d2f7"}
};
}
}

View File

@@ -0,0 +1,210 @@
/*
* 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.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using System.Collections.Generic;
using QuantConnect.Securities.Future;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm using and testing HSI futures and index
/// </summary>
public class HSIFutureHourRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private int _symbolChangeEvent;
private Symbol _contractSymbol;
private Symbol _index;
private Symbol _futureSymbol;
/// <summary>
/// The data resolution
/// </summary>
protected virtual Resolution Resolution => Resolution.Hour;
/// <summary>
/// Initialize your algorithm and add desired assets.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 20);
SetEndDate(2013, 10, 30);
SetAccountCurrency("HKD");
SetTimeZone(TimeZones.HongKong);
UniverseSettings.Resolution = Resolution;
_index = AddIndex("HSI", Resolution).Symbol;
var future = AddFuture(Futures.Indices.HangSeng, Resolution);
future.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(182));
_futureSymbol = future.Symbol;
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(security => seeder.SeedSecurity(security));
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
Debug($"{Time} - SymbolChanged event: {changedEvent}");
if (Time.TimeOfDay != TimeSpan.Zero)
{
throw new RegressionTestException($"{Time} unexpected symbol changed event {changedEvent}!");
}
_symbolChangeEvent++;
}
if (!Portfolio.Invested)
{
foreach (var chain in slice.FutureChains)
{
// find the front contract expiring no earlier than in 90 days
var contract = (
from futuresContract in chain.Value.OrderBy(x => x.Expiry)
select futuresContract
).FirstOrDefault();
// if found, trade it
if (contract != null)
{
_contractSymbol = contract.Symbol;
MarketOrder(_contractSymbol, 1);
}
}
}
else
{
Liquidate();
}
}
public override void OnEndOfAlgorithm()
{
if (_symbolChangeEvent != 1)
{
throw new RegressionTestException($"Got no expected symbol changed event count {_symbolChangeEvent}!");
}
// Get the margin requirements
var buyingPowerModel = Securities[_contractSymbol].BuyingPowerModel;
var futureMarginModel = buyingPowerModel as FutureMarginModel;
if (buyingPowerModel == null)
{
throw new RegressionTestException($"Invalid buying power model. Found: {buyingPowerModel.GetType().Name}. Expected: {nameof(FutureMarginModel)}");
}
var initialOvernight = futureMarginModel.InitialOvernightMarginRequirement;
var maintenanceOvernight = futureMarginModel.MaintenanceOvernightMarginRequirement;
var initialIntraday = futureMarginModel.InitialIntradayMarginRequirement;
var maintenanceIntraday = futureMarginModel.MaintenanceIntradayMarginRequirement;
var lastDataFuture = Securities[_futureSymbol].GetLastData();
if (lastDataFuture == null || (lastDataFuture.EndTime - lastDataFuture.Time) != TimeSpan.FromHours(Resolution == Resolution.Hour ? 1 : 7.25)
|| lastDataFuture.EndTime.Date != lastDataFuture.Time.Date)
{
throw new RegressionTestException($"Unexpected data for symbol {_futureSymbol}!");
}
var lastDataIndex = Securities[_index].GetLastData();
if (lastDataIndex == null || (lastDataIndex.EndTime - lastDataIndex.Time) != TimeSpan.FromHours(Resolution == Resolution.Hour ? 1 : 6.5)
|| lastDataFuture.EndTime.Date != lastDataFuture.Time.Date)
{
throw new RegressionTestException($"Unexpected data for symbol {_index}!");
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
foreach (var addedSecurity in changes.AddedSecurities)
{
if (addedSecurity.Symbol.SecurityType == SecurityType.Future
&& !addedSecurity.Symbol.IsCanonical()
&& !addedSecurity.HasData)
{
throw new RegressionTestException($"Future contracts did not work up as expected: {addedSecurity.Symbol}");
}
}
}
/// <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 => 823;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public virtual int AlgorithmHistoryDataPoints => 25;
/// <summary>
/// Final status of the algorithm
/// </summary>
public virtual 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", "57"},
{"Average Win", "1.83%"},
{"Average Loss", "-1.31%"},
{"Compounding Annual Return", "-99.930%"},
{"Drawdown", "23.000%"},
{"Expectancy", "-0.572"},
{"Start Equity", "100000"},
{"End Equity", "80330"},
{"Net Profit", "-19.670%"},
{"Sharpe Ratio", "-1.298"},
{"Sortino Ratio", "-1.254"},
{"Probabilistic Sharpe Ratio", "1.073%"},
{"Loss Rate", "82%"},
{"Win Rate", "18%"},
{"Profit-Loss Ratio", "1.40"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0.772"},
{"Annual Variance", "0.596"},
{"Information Ratio", "-1.288"},
{"Tracking Error", "0.772"},
{"Treynor Ratio", "0"},
{"Total Fees", "$2280.00"},
{"Estimated Strategy Capacity", "$120000000.00"},
{"Lowest Capacity Asset", "HSI VL6DN7UV65S9"},
{"Portfolio Turnover", "7099.25%"},
{"OrderListHash", "174bdb031f17212dc9d92372f4fb75c2"}
};
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,119 @@
/*
* 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.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using System;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm to test ImmediateExecutionModel places orders with the
/// correct quantity (taking into account the fee's) so that the fill quantity
/// is the expected one.
/// </summary>
public class ImmediateExecutionModelWorksWithBinanceFeeModel: QCAlgorithm, IRegressionAlgorithmDefinition
{
public override void Initialize()
{
SetStartDate(2022, 12, 13);
SetEndDate(2022, 12, 14);
SetAccountCurrency("BUSD");
SetCash("BUSD", 100000, 1);
UniverseSettings.Resolution = Resolution.Minute;
var symbols = new List<Symbol>() { QuantConnect.Symbol.Create("BTCBUSD", SecurityType.Crypto, Market.Binance) };
SetUniverseSelection(new ManualUniverseSelectionModel(symbols));
SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromMinutes(20), 0.025, null));
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(Resolution.Minute));
SetExecution(new ImmediateExecutionModel());
SetBrokerageModel(Brokerages.BrokerageName.Binance, AccountType.Margin);
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
if (orderEvent.Status == OrderStatus.Filled)
{
if (Math.Abs(orderEvent.Quantity - 5.8m) > 0.01m)
{
throw new RegressionTestException($"The expected quantity was {5.8m} but the quantity from the order was {orderEvent.Quantity}");
}
}
}
public bool CanRunLocally => 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 => 2882;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 60;
/// <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", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000.00"},
{"End Equity", "103411.39"},
{"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", "BUSD99.75"},
{"Estimated Strategy Capacity", "BUSD600000.00"},
{"Lowest Capacity Asset", "BTCBUSD 18N"},
{"Portfolio Turnover", "48.18%"},
{"OrderListHash", "2ad07f12d7c80fd4a904269d62794e9e"}
};
}
}

View File

@@ -38,7 +38,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 194;
public override long DataPoints => 195;
/// <summary>
/// Data Points count of the algorithm history
@@ -51,8 +51,8 @@ namespace QuantConnect.Algorithm.CSharp
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-49.28%"},
{"Average Win", "10.27%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "301.565%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0"},

View File

@@ -188,8 +188,8 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-50.48%"},
{"Average Win", "9.07%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "243.722%"},
{"Drawdown", "2.500%"},
{"Expectancy", "0"},

View File

@@ -174,8 +174,8 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-54.58%"},
{"Average Win", "4.97%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "99.378%"},
{"Drawdown", "7.600%"},
{"Expectancy", "0"},

View File

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

View File

@@ -0,0 +1,40 @@
/*
* 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.Securities.Option;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that the option chain APIs return consistent values for index options
/// See <see cref="QCAlgorithm.OptionChain(Symbol)"/> and <see cref="QCAlgorithm.OptionChainProvider"/>
/// </summary>
public class IndexOptionChainApisConsistencyRegressionAlgorithm : OptionChainApisConsistencyRegressionAlgorithm
{
protected override DateTime TestDate => new DateTime(2021, 1, 4);
protected override Option GetOption()
{
return AddIndexOption("SPX");
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 2862;
}
}

View File

@@ -20,7 +20,7 @@ namespace QuantConnect.Algorithm.CSharp
{
public class IndexOptionIndicatorsRegressionAlgorithm : OptionIndicatorsRegressionAlgorithm
{
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.17702,Delta: 0.19195,Gamma: 0.00247,Vega: 1.69043,Theta: -1.41571,Rho: 0.01686";
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.17406,Delta: 0.19196,Gamma: 0.00247,Vega: 1.72195,Theta: -1.3689,Rho: 0.01744";
public override void Initialize()
{

View File

@@ -204,18 +204,18 @@ namespace QuantConnect.Algorithm.CSharp
{
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "-50.30%"},
{"Average Loss", "-9.85%"},
{"Compounding Annual Return", "-77.114%"},
{"Drawdown", "12.500%"},
{"Expectancy", "-1"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "90146"},
{"Net Profit", "-9.854%"},
{"Sharpe Ratio", "-1.957"},
{"Sortino Ratio", "-0.569"},
{"Probabilistic Sharpe Ratio", "0.709%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.64"},
{"Beta", "0.196"},

View File

@@ -110,11 +110,11 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "4"},
{"Average Win", "0%"},
{"Average Loss", "-20.04%"},
{"Average Win", "174.10%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "79228162514264337593543950335%"},
{"Drawdown", "2.100%"},
{"Expectancy", "-0.5"},
{"Expectancy", "2901.176"},
{"Start Equity", "100000"},
{"End Equity", "274018.3"},
{"Net Profit", "174.018%"},
@@ -123,7 +123,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Probabilistic Sharpe Ratio", "95.428%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0"},
{"Profit-Loss Ratio", "5803.35"},
{"Alpha", "7.922816251426434E+28"},
{"Beta", "4.566"},
{"Annual Standard Deviation", "11.741"},

View File

@@ -201,8 +201,8 @@ namespace QuantConnect.Algorithm.CSharp
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "2"},
{"Average Win", "5.00%"},
{"Average Loss", "0%"},
{"Average Win", "0%"},
{"Average Loss", "-0.95%"},
{"Compounding Annual Return", "-12.719%"},
{"Drawdown", "1.200%"},
{"Expectancy", "-1"},

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