Compare commits

...

195 Commits

Author SHA1 Message Date
Martin-Molinero
31e247689f Allow specifying PositionSize wolverine order properties (#9257) 2026-01-30 16:56:17 -03:00
Roman Yavnikov
297207badb feat: add MappedSynchronizingHistoryProvider base class (#9256)
* feat: add MappedSynchronizingHistoryProvider base class

Introduces an abstract class for history providers that handle symbol mapping and time-aligned data slices. Uses IMapFileProvider to resolve ticker changes, provides an abstract method for mapped history retrieval, and overrides GetHistory to synchronize results. Enables nullable reference types and adds documentation.

* Minor tweaks

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2026-01-30 16:55:10 -03:00
Jhonathan Abreu
ecb8e8da41 Fix trades drawdown calculation (#9249)
* Fix trade drawdown calculation

* Cleanup

* Disable MAE. MFE and Drawdown calculation for FlatToFlat and FlatToReduced trade grouping methods

* Minor test fixes
2026-01-30 15:46:41 -04:00
Martin-Molinero
c6c4c1edec Fix fundamental security direct access timestamp (#9255)
- Fix the date used by fundamental data accessed directly through security.
  Updating regression algorithm asserting behavior
2026-01-30 11:41:24 -03:00
Martin-Molinero
c02a8faedb Improve Wolverine brokerage model limitations (#9252) 2026-01-29 14:36:12 -03:00
JosueNina
e620d3fd7b Replace ':' with '-' in backtest names for API CI (#9251) 2026-01-29 14:03:58 -03:00
Martin-Molinero
4b6643312e Allow emtpy BNFCR cash through (#9247) 2026-01-28 10:53:19 -03:00
Martin-Molinero
4b2f203322 Fix USDC binance crypto future and stable pairs (#9246)
- Minor fix for stable pairs handling without a pair, adding unit tests
- Fix for USDC it's a USD-M crypto future not coin
2026-01-28 09:49:28 -03:00
JosueNina
7eefdebae5 Update signal when rangeBand is zero (#9245) 2026-01-28 09:47:53 -03:00
Jhonathan Abreu
7f17838ad0 Fix crypto future margin model to reflect margin used (#9235)
* Fix crypto future margin model to reflect margin used

* Minor tests fixes

* Cleanup

* Cleanup
2026-01-27 13:40:36 -04:00
Martin-Molinero
5a1ebcbaad Fix LeanDataWriter Compression method so it supports unicode filenames (#9244) 2026-01-27 14:31:46 -03:00
Martin-Molinero
552511ef58 Fix dydx holdings value (#9243)
- dYdX crypto futures holdings value behaves like normal positions qtty
  * price
2026-01-26 16:29:19 -03:00
Jared
8f2fd3d64a Redact local lean error message (#9232)
Redact message in local user's CLI's
2026-01-26 12:56:19 -03:00
JosueNina
609deb2b03 Logging only once price rounding warnings (#9238) 2026-01-26 12:54:33 -03:00
Jhonathan Abreu
7fb246511a Add total performance statistics to live result files (#9224)
* Add total performance statistics to live result files

* Truncate closed trades in live results

* Avoid adding totalPerformance to live minute result file

* Deprecated Trade.Symbol in favor of new Trade.Symbols

* Fixes for Trade serialization

* Add trades json serialization tests

* Cleanup
2026-01-16 15:41:35 -04:00
Martin-Molinero
745292c15a Add Async for submit request to string (#9228) 2026-01-16 13:44:16 -03:00
JosueNina
22e0e5ddf5 Prevent SessionBar EndTime overflow when Time is DateTime.MaxValue (#9215)
* Fix SessionBar EndTime overflow

* Fix broken tests

* Update python regression tests

* Solve review comments

* Revert changes

* Prevent overflow from Time + Period
2026-01-16 12:07:41 -03:00
Adalyat Nazirov
ef94b5affc Add dYdX IoC Time In Force (#9226)
* Add `IoC` and update `PostOnly` in `dYdXOrderProperties` with validation logic; add corresponding unit tests.

* change case to use IOC

* more IOC
2026-01-15 17:20:11 -03:00
Martin-Molinero
61e8c63acd Fix dydx camel case (#9223) 2026-01-14 11:55:29 -03:00
Adalyat Nazirov
1ca7320f2f Add dYdXFutureMarginInterestRateModel (#9221)
* Add `dYdXFutureMarginInterestRateModel` and update `GetMarginInterestRateModel` to support CryptoFuture funding rates

* missing import
2026-01-13 18:00:26 -03:00
JosueNina
5b8e54f272 Reduce excessive debug logging in live trading (#9220)
* Reduce excessive logs

* Revert unnecesary log changes
2026-01-13 14:19:40 -03:00
Jhonathan Abreu
26584c2fd0 Stop and delete unused threads in tests (#9219) 2026-01-13 13:13:37 -03:00
Roman Yavnikov
48fd4eccff Feat: override ToString() in several Event Args (#9217)
* feat: override ToString() in several Event Args

* fix: typo
2026-01-13 10:00:48 -03:00
JosueNina
75d5cbcf2a Fix: RandomDataGenerator crashes when algorithm is null (#9211)
* Fix NullReferenceException in SecurityService

* Simplify the unit test

* Add unit test for RandomDataGenerator

* Improve unit test name

* Solve review comments
2026-01-12 14:50:01 -04:00
Jhonathan Abreu
d702587ad8 Fix SecurityIdentifier properties lazy initialization (#9214) 2026-01-09 18:07:26 -03:00
Jhonathan Abreu
c99a9dab32 Update CNH future quote currency (#9213) 2026-01-09 15:44:29 -03:00
JosueNina
8196d0b557 HistoryRequest parameters now defaults to the security configuration (#9209)
* Fix HistoryRequest DataMappingMode default to use security configuration

* Solve review comments

* Make HistoryRequest inherit existing subscription configuration values generically

* Exclude any class that inherits from BaseChainUniverseData

* Reuse existing filter for user configuration

* Solve review comments

* Normalize DataMappingMode

* Minor fix
2026-01-09 15:43:46 -03:00
Ricardo Andrés Marino Rojas
3ee941f329 Remove wrong holidays in MHDB (#9205)
Remove wrong holidays in CME group Dairy, Livestock and Lumber products.
There was also a wrong holidays in Future-cbot-KE
2026-01-07 16:13:28 -03:00
Ricardo Andrés Marino Rojas
286353b763 Remove duplicated dates (#9207) 2026-01-07 16:13:19 -03:00
Ricardo Andrés Marino Rojas
d5f298c235 Add missing Oanda, SGX and Cfd-InteractiveBrokers 2026 holidays to MHDB (#9204)
* Add 2026 Oanda holidays

* Add 2026 new year holiday SGX

* Add Cfd-interactivebrokers 2026 holidays

* Remove wrong holidays in Forex-oanda-[*]

* Nit change
2026-01-07 13:08:40 -03:00
Ricardo Andrés Marino Rojas
f2c5551b1e Remove dates present in generic entry Index-usa and others (#9202) 2026-01-06 17:19:07 -03:00
Ricardo Andrés Marino Rojas
f86a51ac3f Remove dates in generic Interactive Brokers entry part 10 (#9201)
* Remove dates present in IB generic entry part 9

* Remove dates in IB generic entry part 10
2026-01-06 16:14:25 -03:00
Ricardo Andrés Marino Rojas
1253cc73bd Remove dates present in IB generic entry part 9 (#9200) 2026-01-06 16:12:19 -03:00
Ricardo Andrés Marino Rojas
6506ff53a3 Remove dates in generic Interactive Brokers entry part 8 (#9199)
* Remove dates present in IB generic entry part 7

* Remove dates present in IB generic entry part 8
2026-01-06 14:32:01 -03:00
Ricardo Andrés Marino Rojas
713785157e Remove dates present in IB generic entry part 7 (#9198) 2026-01-06 14:30:07 -03:00
Ricardo Andrés Marino Rojas
fd7048d2d1 Remove dates present in IB generic entry part 6 (#9197) 2026-01-06 13:27:45 -03:00
Ricardo Andrés Marino Rojas
1b66aeede1 Remove dates present in IB generic entry part 5 (#9196) 2026-01-06 13:10:04 -03:00
Ricardo Andrés Marino Rojas
2f80a2a6b9 Remove dates in generic Interactive Brokers entry part 4 (#9193)
* Remove dates present in generic entries

* Remove dates present in IB generic entry
2026-01-06 12:45:59 -03:00
Ricardo Andrés Marino Rojas
68d4da8e76 Remove dates present in generic entries (#9192) 2026-01-06 12:22:20 -03:00
Ricardo Andrés Marino Rojas
538405d152 Remove dates present in generic interactivebrokers (#9191) 2026-01-06 11:59:37 -03:00
Ricardo Andrés Marino Rojas
1f3fd6edbb Reduce (part of) dates already present in generic entries from MHDB (#9190)
* Remove dates present in cme generic entry

* Remove dates present in cbot generic entry

* Remove dates present in nymex generic entry

* Remove dates present in comex generic entry

* Remove dates present in oanda generic entry

* Remove dates present in SGX and HKFE generic entries
2026-01-06 11:52:15 -03:00
Adalyat Nazirov
e3783ed477 Override GetBuyingPowerModel to support USDC collaterla in dYdX brokerage (#9187) 2026-01-05 09:55:46 -03:00
Ricardo Andrés Marino Rojas
1171e4fe52 Add 2026 Future EUREX, CFE and ICE Holidays (#9183)
* rebase Add 2026 EUREX, CFE and ICE Holidays

* Remove entries present in generic entry

For some ICE Future entries, there were holidays that were already
present in their generic entry (Future-ice-[*]), so those dates were
removed from the entry
2026-01-02 16:05:36 -03:00
Martin-Molinero
a66f279852 Fix some incorrect future expirations (#9184)
- Some future expiry functions were missing to account for holidays,
  adding unit test reproducing issue
2026-01-02 12:58:29 -03:00
Martin-Molinero
6575b57146 Fix future expiration year calculation (#9182) 2026-01-02 10:21:02 -03:00
yyxxddjj
3fa700e450 New Feature: Implement Covariance Indicator #6982 (#9144)
* Implements Covariance as Lean Indicator

* Add COV helper method and fix AcceptsVolumeRenkoBarsAsInput test

* Fix AcceptsRenkoBarsAsInput test to use smaller period for faster execution

* Fix slow Renko tests by limiting data processed to 50 rows
2025-12-31 16:02:03 -03:00
Adalyat Nazirov
7735917c83 Prioritize CryptoFuture data feeds for dYdX (#9178)
* Prioritize CryptoFuture data feeds for dYdX

* revert changes for existing crypto subscriptions

* use Concat instead of adding into list
2025-12-31 13:19:58 -03:00
Jhonathan Abreu
67489eef57 Add GetInt64 StreamReader extension method (#9177)
* Add GetInt64 StreamReader extension method

* Minor change

* Cleanup

* Add unit tests
2025-12-31 11:58:51 -04:00
JosueNina
241306275a Replace external dataset with mock data in sweetviz test (#9176) 2025-12-31 12:18:22 -03:00
Ricardo Andrés Marino Rojas
773bd53525 Add 2026 CME Future & HKFE Holidays, early closes, late opens and bank holidays (#9174)
* Add 2026 HKFE Future holidays & early closes

* rebase Add 2026 Future-cme-equity Holidays, Early closes, late opens

* Add (again) HKFE 2026 Holidays and early closes

* Add Future-cme-interest 2026 holidays

* Add 2026 CME Fx 2026 holidays"

- Add 2026 CME Fx holidays, early closes, late opens, bank holidays
- Exclude CNH, MNH and MIR as they expire rules don't consider US
  Holidays
- Fix wrong early close on 12/24/2025 from 12:15 to 12:45

* Add CME Future crypto 2026 Holidays, EC, LO & BH

* Add CME Future Energy 2026 holidays, EC, LO, BH

* Add CME Futures metals holidays, ec, lo, bh

* Add CME Futures grains 2026 holidays, ec, lo, bh

* Add CME Futures Dairy 2026 holidays, ec, lo, bh

* Add CME Futures livestock holidays, ec, lo, bh

* Add CME Future Lumber holidays, ec, lo, bh

* Add CME Futures Softs holidays, ec, lo, bh

* Add CME Futures Oilseeds holidays, ec, lo, bh

* Add CME Futures AW, GD Holidays, EC, LO and BH

* Move repeated bank holidays to generic entries

* Nit change

* Solve bug

Since 11/26/2026 is a bank holiday for CME energy futures, the expiry
date is moved to 11/25/2026 as the expiry date for HH is the third last
business day of the month prior to the contract month
2025-12-31 11:33:59 -03:00
JosueNina
0854ab82da Default option filter now includes weeklies to prevent empty chains (#9162)
* Return weekly contracts if no standard contracts exist

* Fix unit and regression tests

* Centralize default expiration type flags

* Add ExcludeWeeklys() method

* Mark IncludeWeeklys() as obsolete since weeklies are now default
2025-12-31 10:11:46 -03:00
JosueNina
2c0390fde3 Change Config.Get logging from Trace to Debug level (#9171)
* Change Config.Get logs from Trace to Debug level to reduce noise

* Wrap Config.Get logs with DebuggingEnabled check
2025-12-31 10:09:37 -03:00
JosueNina
32fcd94abc Exclude Period property from WindowIndicator (#9172) 2025-12-31 10:08:37 -03:00
Martin-Molinero
090ffebd03 Minor ApiConnection improvement (#9173) 2025-12-30 18:48:27 -03:00
JosueNina
914d0810af Make Collaborator.Uid nullable to fix JSON deserialization error (#9170) 2025-12-30 15:40:22 -03:00
Martin-Molinero
10902f95dd net10 fix: Update clr-loader (#9166) 2025-12-29 19:07:35 -03:00
Martin-Molinero
2e67b9ad4f Feature net10 update (#9161)
* Feature update to net10

* Update to net10

* Update pythonnet to 2.0.51

* Remove dotnet config

* Remove net9

* Minor cleanup
2025-12-29 09:53:37 -03:00
Ricardo Andrés Marino Rojas
7adf27aa61 Add 2026 CME Future Holidays, EC, LP, BH (#9163)
- Add 2026 CME Future Holidays, Early closes, Late opens and bank holidays
- Exclude MIR, CNH, MNH as they expire rules don't follow US holidays
2025-12-27 10:52:23 -03:00
Martin-Molinero
7ea0f60905 Add SGX futures holidays (#9160) 2025-12-26 15:24:55 -03:00
Martin-Molinero
d9c71e3d34 Adding Forex-Oanda & Cfd-IB 2026 new years holiday. Removing duplication (#9159) 2025-12-26 12:10:19 -03:00
Martin-Molinero
b040518d52 Minor foundation update reverts (#9156) 2025-12-24 17:02:49 -03:00
Roman Yavnikov
725737610a fix: several Futures Currencies: 6B, 6M, 6J, 6E, 6C (#9155) 2025-12-24 17:39:50 +02:00
Martin-Molinero
37ccee4937 Update foundation image (#9154) 2025-12-24 11:17:50 -03:00
Jhonathan Abreu
0ab0abd1ca Clean up after removing RestSharp (#9153) 2025-12-23 13:45:31 -03:00
Jhonathan Abreu
c565f4cfd0 Refactor optimization statistics serialization (#8984)
* Refactor optimization result stats serialization

* Handle custom optimization statistics serialization

* Support custom statistics

* Support newest Lean statistics

Address peer review

* Add more tests

* Make indices reserved statistic names

* Minor fixes and cleanup
2025-12-22 17:08:24 -04:00
Ricardo Andrés Marino Rojas
f804b8f0ca Add 2026 Index holidays to MHDB (#9152)
* Add index-usa-[*] holidays and early closes

* Add Index-spx 2026-2027 holidays & early closes

* Add 2026 Index-ndx holidays & early closes

* Add 2026 Index-VIX holidays and early closes

* Add EUREX Index holidays 2026-2030

* Add index HKFE 2026 holidays and early closes

* Add 2026 Index-OSE holidays and early closes

* Add missing 2026 Index-India NSE holidays

* Address suggested changes
2025-12-22 16:42:25 -03:00
Jhonathan Abreu
ef1cf8e4df Replace RestShap with HttpClient (#9143)
* Replace RestShap with HttpClient

* Address peer review

* Minor fixes
2025-12-22 09:50:25 -04:00
Ricardo Andrés Marino Rojas
661356e33e Add missing USA equity holidays and early closes (#9148)
* Add 2025-2027 USA equity holidays

* Address reviews
2025-12-19 17:18:42 -03:00
Martin-Molinero
5842f50b03 Trigger initial selection for a yearly schedule (#9149)
- Trigger initial selection for a yearly scheduled universe. Adding
  regression algorithm.
2025-12-19 16:45:37 -03:00
Martin-Molinero
0f80591f51 Fix null reference un future contract. Adding tests (#9147) 2025-12-19 13:51:45 -03:00
JosueNina
0622f43a0f Fix issues with the IchimokuKinkoHyo indicator (#9135)
* Fix issues with IchimokuKinkoHyo indicator

* Use indicator extension methods for automatic updates
2025-12-19 12:48:49 -03:00
JosueNina
8f0224feb6 Fix StopLimit validation bug (#9142) 2025-12-19 12:35:19 -03:00
Jhonathan Abreu
781897984e Detect serialized json payload in CreateJsonPostRequest (#9145) 2025-12-19 11:24:03 -04:00
Roman Yavnikov
340b40c6ce Fix: AUD(6A) FOP expiration (#9139)
* fix: AUD(6A) FOP expiration

* feat: add 6A to FOP expiry delta
refactor: rename variable to project pattern naming

* remove: AUD fop expiry delta
test:fix: use flexible reference data in  FutureAndOptionMapping

* test:fix: AUD in GetUnderlyingSymbolFromFutureOption
2025-12-19 15:52:06 +02:00
Jhonathan Abreu
58ce899b5d Add Api helper methods for POST requests (#9134)
* Add Api helper methods for POST requests

* Support json serializer setting for json requests

* Minor changes and cleanup

* Make ApiConnection disposable
2025-12-16 18:08:28 -04:00
Martin Nemček
ead8335c84 #8356 Implemention of NHNL indicators (#9109)
* #8356 Implemented NHNL indicators

* #8356 Formatting cleanup

* #8356 Review changes

* #8356 use of var

* #8356 Refactoring of tests classes

---------

Co-authored-by: Martin Nemček <nemcek@metaapp.sk>
2025-12-16 14:24:00 -03:00
Aibek Minbaev
84ee81b35b Feat 8909 add python env support in report generation (#9128)
* Added python-venv to ReportArgumentParser, getting python-venv in Program class

* Added venv activation and python initialization to Report class

* Resolve review comments. Move python init and env addition to Report/Program.cs
2025-12-16 13:42:23 -03:00
JosueNina
03be232f31 Fix issues with IgnoresInsightsWithInvalidMagnitudeValue tests (#9131) 2025-12-15 18:24:11 -03:00
Martin-Molinero
e568162bff Minor slice.AllData api change (#9130) 2025-12-15 10:25:00 -03:00
Derek Melchin
e395892b8e Fix camelCase constructor args (#9127) 2025-12-11 15:15:17 -03:00
Jared
3483fee766 Remove debug message for daily precise end time (#9126)
Removed debug message regarding daily precise end times.
2025-12-11 15:14:22 -03:00
Jhonathan Abreu
6cba915950 Fix minor bug with restsharp auth header (#9125)
* Fix minor bug with restsharp auth header

* Minor fix
2025-12-11 15:13:37 -03:00
Martin-Molinero
046df38be8 Fix log timestamp & minor cleanup (#9124) 2025-12-11 13:44:30 -03:00
Jhonathan Abreu
c7e96b837d Minor fix for json to stream serialization extension (#9123) 2025-12-10 18:29:57 -04:00
Martin-Molinero
2f23c89307 Avoid FF enumerator error warning (#9122) 2025-12-10 18:18:08 -03:00
Jhonathan Abreu
67d19d88d7 Add ApiConnection constructor for backwards compatibility (#9121) 2025-12-10 16:16:38 -04:00
Jhonathan Abreu
b4401db512 Refactor ApiClient to use HttpClient (#9114)
* Refactor ApiClient to use HttpClient

* Minor fix

* Refactor and cleanup in ApiConnection

* Add normalized extension methods for string and stream json serialization

* Minor fixes

* Address peer review

* Minor fixes

* Minor fixes and peer review

* Race condition fix

* Minor changes

* Cleanup

* Minor fixes

* Minor fix
2025-12-10 15:40:46 -04:00
Jhonathan Abreu
bc646c974a Use proper extended dictionary types for public properties (#9119) 2025-12-09 13:01:29 -03:00
Adalyat Nazirov
857a950e23 dYdX Brokerage Essentials (#9116)
* add dYdX market constant

* Add dYdX market constant and update symbol properties database

* get Gaz limit from order properties or default value

* wip

* add symbol properties

* add more dydx order props

* update symbol properties

* Add dYdX brokerage and fee model

* Update dYdX configuration fields

* undone meta files

* minor tweaks

* fix file ending

* Add dYdX brokerage support to BrokerageName and IBrokerageModel

* Refine dYdX fee model integration and update configuration defaults

* Replace custom order size validation in dYdXBrokerageModel with DefaultBrokerageModel implementation

* undone changes

* Add market hours for dYdX CryptoFuture
2025-12-09 09:58:06 -03:00
JosueNina
888752fa0a Avoid unnecessary Python wrapper creation for pure C# models (#9106)
* Centralize Python/C# model detection logic

* Improve helper method

* Remove unnecessary conditionals

* Fix unit tests

* Refactor QCAlgorithm.python.cs to use the new helper method for models

* Solve review comments

* Clean up Python wrapper exception

* Update XML comments to better describe T and TWrapper in CreateModelOrWrapper

* Join unit tests in TestCases

* Solve review comments

* Replace manual TryConvert checks with CreateInstanceOrWrapper helper
2025-12-08 18:01:31 -03:00
Martin-Molinero
14427129c7 Minor fix to handle all tick security updates (#9117) 2025-12-08 17:41:28 -03:00
Jhonathan Abreu
683bfe007a Avoid emitting overlapping fill forwarded data (#9107)
* Avoid emitting overlapping fill forward data

* Cleanup
2025-12-05 10:05:40 -04:00
Jhonathan Abreu
263a9099ed Add TryDownloadData extension method (#9111) 2025-12-05 10:03:27 -04:00
JosueNina
a78004a1e6 Add default values to ConstantAlphaModel (#9104)
* Initial solution

* Add unit tests

* Fix constructor parameter mismatch in ConstantAlphaModel

* Delete unused constructor
2025-12-01 13:49:17 -03:00
Jhonathan Abreu
9acd30c355 Make DataDictionary ordered by key (symbol) (#9105)
* Make DataDictionary ordered by key (symbol)

* Cache DataDictionary sorted items

* Minor tests fixes

* Minor changes

* Minor changes
2025-12-01 12:44:22 -04:00
JosueNina
441ba1a7b5 Add ExtendedDictionary implementations (#9096)
* Add ExtendedDictionary implementations

- Add DefaultExtendedDictionary<TKey, TValue> class
- Add ReadOnlyExtendedDictionary<TKey, TValue> class
- Refactor exposed dictionaries

* Make DataDictionary inherits from DefaultExtendedDictionary

* Refactor UniverseManager

* Return ReadOnlyExtendedDictionary in GetParameters()

* Solve review comments

* Remove unnecesary property, no longer required

* Reduce code duplication

* Solve new review comments

* Remove unnecesary constraints

* Replace BaseExtendedDictionary with DataDictionary in GetLastKnownPrices method

* Remove unused extensions
2025-11-28 16:03:02 -04:00
JosueNina
52b788d9de Fix inclusive loop upper bound (#9102) 2025-11-28 12:39:09 -04:00
Jhonathan Abreu
16fdf61903 Track securities addition and removal notifications (#9097)
* Track security addition and removal sent notifications

* Minor regression algorithm fixes

* Fix regression algorithms data points count

* Add description to new regression algorithms

* Simplify tracking removal notifications

* Cleanup
2025-11-28 10:37:31 -04:00
Roman Yavnikov
59990573c2 Fix: Use decimal option strike precision (#9099)
* fix: use decimal instead long in Scale's LeanData
test:feat: validate naming with large precision

* feat: use normalization in Scale's LeanData
test:fix: strike precisions

* fix: use str normalization in Scale's LeanData
2025-11-25 20:32:06 +02:00
yyxxddjj
acb787e8f6 Docs(Algorithm): Add XML code references (#9077)
* Docs(Algorithm): Add XML code references

Adds XML documentation tags (<see/>, <paramref/>) to code
references within the Algorithm folder. This improves code
navigation, IntelliSense, and helps the stubs generator tool
to correctly map C# elements.

Resolves #9016

* Fix missing newline at end of QCAlgorithm.cs

* Update print statement from 'Hello' to 'Goodbye'

* Fix documentation for market parameter in crypto methods
2025-11-24 17:51:42 -04:00
JosueNina
6260b2f7e0 Replace /// with <summary> (#9095) 2025-11-24 17:09:39 -04:00
Martin-Molinero
95739b8a58 Increase option strike digits precision to 6 (#9086)
* Increase option strike digits precision to 6

- Increase option strike digits precision to 6. Adding unit test

* test:fix: couple of build tests

* fix:test: Asset CUSIP and OrderListHash in Regression Algorithms

* test:fix: several regression algos

* test:fix: old Symbol CUSIPs to new ones

---------

Co-authored-by: Romazes <romazes20@gmail.com>
2025-11-18 16:23:29 -03:00
Jhonathan Abreu
c81f5d7d1a Seed securities by default (#9045)
* Add SeedInitialPrices algorithm setting

This is true by default and indicates that the engine will seed initial prices right after the security is added or selected

* Update regression algorithms

* Update regression algorithms

* Update regression algorithms

* Refactor default securities seeding

* Minor fix

* Minro fixes

* Cleanup

* Updated and add regression algorithms

* Address peer review

* Centralize logic to get last known data for multiple securities

* Some cleanup

* Minor build fix

* Minor fixes

* More logic centralization

* Some more cleanup

* Cleanup

* Update regression algorithms and minor fixes

* Update regression algorithms

* Minor fix

* More minor fixes

* Update regression algorithms

* Cleanup

* Minor test fix

* Address peer review

* Minor fix and performance improvement

* Fix to seed open interest data

* Minor test fixes

* Address peer review

* Minor change

* Minor revert

* Minor fixes and improvements

* Disable initial seeding by default

* Minor fixes

* Cleanup

* Cleanup

* Minor fix
2025-11-18 13:05:56 -04:00
Martin-Molinero
4961844f82 Refactor user define universe handling (#9088)
* Refactor user define universe handling

- Normalize user define universe additions and removals to behave like
  other subscriptions without requiting special handling

* Minor fixes
2025-11-18 12:29:05 -03:00
Martin-Molinero
afca923cd9 Fix history provider equity skip (#9090) 2025-11-18 12:28:17 -03:00
Roman Yavnikov
a31436bc6d Test:Feat: parse different future option file name csv (#9084)
* test:feat: parse different future option file name csv

* test:refactor: ReadSymbolFromZipEntry
2025-11-14 15:45:46 +02:00
JosueNina
ebaa355bf1 Fix Python inheritance issue with SelectionModels (#9069)
* Initial solution

* Solve review comments

* Add PythonSelectionModelHandler to reduce code duplication

* Refactor universe selection models

* Add python instance to Selection Models with virtual/override methods

* Add python instance to Alpha Models

* Add python instance to Execution models

* Solve review comments

* Solve new review comments

* Fix calling SetPythonInstance only when method exists and is callable

* Use unit test instead of regression algorithms

* Solve review comments

* Set python instance to the models

* Initialize Python containers only when instance is set

* Replace try-catch with explicit method existence check

* Initialize containers in BasePythonWrapper only when needed

* Add null instance check before method invocation

* Refactor TryExecuteMethod

* Refactor Python wrappers which inherit from BasePythonWrapper<>

* Solve review comments

* Remove ununsed methods

* Solve review comments
2025-11-13 17:21:55 -03:00
Derek Melchin
46639fc4ec Update deprecation message in Top method (#9081) 2025-11-12 15:29:22 -03:00
Alexandre Catarino
2052a86351 Renames File Stochastics.cs -> Stochastic.cs (#9079)
Match the class name: `Stochastic`.
Fixes summaries.
2025-11-12 09:30:12 -03:00
JosueNina
7a5ff8054b Prevent adding zero quantity currencies to CashBook (#9076)
* Prevent adding zero quantity currencies to CashBook

* Solve review comments

* Solve new review comments

* Add unit test
2025-11-10 09:33:38 -03:00
Roman Yavnikov
a3d6e24741 Test:Feat: Updating process in TrailingStopOrderTestParameters (#9072)
* feat: implement ModifyOrderToFill in TrailingStopOrderTestParameters

* feat: prevent update TrailingOrder not equal SecurityType.Equity

* Revert "feat: prevent update TrailingOrder not equal SecurityType.Equity"

This reverts commit 35548dcfb7.

* rename: variable in TrailingStopOrderTestParameters
2025-11-04 18:25:08 +02:00
Martin-Molinero
6c5b577b46 Update HistoryProviderManagerTests.cs
Remove no longer valid unit test
2025-11-03 09:36:59 -03:00
Jhonathan Abreu
f4bab98b00 Update Pythonnet version to 2.0.50 (#9070) 2025-10-31 16:38:26 -04:00
Martin-Molinero
733be65148 Simplify history request handling for equities (#9068)
- For equity history requests, we will only ask the first provider which
  returns a valid reply, improvements thought for live trading QC+IB
2025-10-30 18:29:41 -03:00
Alexandre Catarino
2c26e9fc26 Adds Missing Indicator Constructor Overloads Without name Parameter (#9062)
* Adds Missing Indicator Constructor Overloads with name Parameter

* Fix Typoes
2025-10-30 18:08:34 -03:00
Martin-Molinero
2faf921731 FixComposer Assembly Resolution (#9066) 2025-10-28 09:26:12 -03:00
Martin-Molinero
89f3968eef Fix performance degradation on expirying assets (#9065)
* Fix performance degradation on expirying assets

- Options would expire and get removed, when the universe removed the
  security it would never be reseted on universe selection, causing
  leaks
- Minor improvement for composer assembly loading
- Minor improvement for loading exception interepreters, so it uses
  composer

* Minor regression test fix

* Add new benchmark algorithm
2025-10-27 18:17:53 -03:00
JosueNina
9c7d633b41 Throw exceptions when ObjectStore limits are exceeded in Research mode (#9060)
* Throw exception in Research mode when storage limits are exceeded

* Solve review comments
2025-10-27 10:16:25 -05:00
Martin-Molinero
cfba82e17a Minor composer improvements (#9064)
- Avoid loading unrequired assemblies and correctly handle assembly
  loading errors
2025-10-27 12:11:59 -03:00
Martin-Molinero
6811b93d6a Add performance tracking tool (#9063)
- Add optional performance tracking tool
2025-10-27 11:31:14 -03:00
Martin-Molinero
6916636e8e Remove Future expiry date from data & use Bank Holidays For Expirations (#8580)
* Use Futures Bank Holidays For Expirations

* Minor improvements

- Futures will be stored by their contract month, not expiry

* Delete dairy future products

* Minor test fixes
2025-10-24 17:18:20 -03:00
JosueNina
0a4c19527b Support index options (#9061) 2025-10-24 13:29:48 -05:00
JosueNina
f807d62b18 Improve cash assignment event message (#9051)
* Improve cash assignment event message

* Fix broken tests

* Solve review comments

* Solve new review comments

* Add P&L message to option exercise order events in portfolio model

* Solve review comments
2025-10-23 11:54:00 -05:00
JosueNina
f5c5c5a3b0 Add configurable initialization timeout via config.json (#9056)
* Add configurable initialization timeout via config.json

* Solve review comments
2025-10-22 12:49:39 -03:00
Ryan Crowley
553bd3993a Add optional strict parameter to PivotPointsHighLow indicator (#9033)
* Add optional strict parameter to PivotPointsHighLow indicator for relaxed comparison

- Added bool strict parameter (default true) to PivotPointsHighLow constructors
- When strict=true: Uses strict inequalities (> and <) - existing behavior
- When strict=false: Uses relaxed inequalities (>= and <=) - allows equal values
- Updated comparison logic in FindNextLowPivotPoint and FindNextHighPivotPoint
- Added new PPHL overload in QCAlgorithm.Indicators.cs with strict parameter
- Added 5 comprehensive unit tests using TestCase attributes
- All tests pass (19/19 relevant tests)
- Backwards compatible: default behavior unchanged

Addresses #8881

* Fix PPHL method signature to resolve overload ambiguity and maintain API consistency

- Remove wrapper overload to eliminate compilation ambiguity
- Reorder parameters: strict parameter now before resolution
- Keep selector as last parameter (consistent with other indicator helpers)
- Add unit tests verifying no overload ambiguity and correct strict parameter behavior

Addresses PR review feedback on #9033

* Implement backward-compatible PPHL overloads to support strict parameter

Added a second overload to maintain backward compatibility while introducing
the strict parameter. This prevents breaking changes for existing code that
uses positional arguments with the PPHL helper method.

Changes:
- Added backward-compatible overload that accepts (symbol, lengthHigh, lengthLow,
  lastStoredValues, resolution, selector) and delegates to the new implementation
  with strict: true
- Kept the new overload with strict parameter as the primary implementation
- Added comprehensive test (QCAlgorithmHelperOverloadResolution) documenting all
  9 valid call patterns to prevent future regressions

This approach ensures:
- Existing calls like PPHL(symbol, 3, 3, 100, Resolution.Minute) continue to work
- New calls like PPHL(symbol, 3, 3, strict: false) are supported
- No ambiguity in overload resolution
- All 23 PPHL tests pass successfully

* Clean up some test duplication

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-10-22 09:26:24 -03:00
JosueNina
e74bfeb7f9 Update SPDB - Binance Exchanges (#9054)
* Update SPDB with Binance

* Update SPDB with BinanceUS

* Update SPDB - BinanceUS to solve issues with the unit tests
2025-10-22 09:26:00 -03:00
Martin-Molinero
9ab9fe5f2b Python performance improvement (#9052)
* Minor tweak to cache liquidation fees

* Result handler cleanup

* Update pythonnet version to 2.0.49
2025-10-21 12:34:52 -03:00
Jhonathan Abreu
93e7e3edb4 Fix setting brokerage model after adding security initializer (#9048)
* Fix settting brokerage model after adding security initializer

* Minor fix

* Minor change

* Minor change

* Send warning for calling SetBrokerageModel before setting or adding security initializer

* Send warning for calling SetBrokerageModel before setting or adding security initializer

* Minor change

* Minor change

* Cleanup
2025-10-20 16:32:59 -04:00
JosueNina
49fe020b84 Add ObjectStore limit properties (#9043)
* Initial solution

* Add Unit tests

* Solve review comments

* Fix broken tests

* Solve review comments

* Updated property names
2025-10-20 17:21:31 -03:00
Martin-Molinero
6c95372d27 Disable OHLC session tracking by default (#9046)
* Disable OHLC session tracking by default

* Minor test fix
2025-10-17 15:59:50 -03:00
Jhonathan Abreu
cfd46cf63f Add QCAlgorithm.AddSecurityInitializer method (#9042)
* Add new QCAlgorithm.AddSecurityInitializer method

This allows to add multiple security initializers without manually creating an instance of a CompositeSecurityInitializer

* Add Python support

* Cleanup
2025-10-16 09:51:18 -04:00
JosueNina
ff1638f653 Support CustomData in SecurityCache.GetData(PyObject type) method (#9036)
* Initial Solution

* Add regression algorithms

* Solve review comments

* Update CustomDataSecurityCacheGetDataRegressionAlgorithm.py

---------

Co-authored-by: Martin-Molinero <martin.molinero1@gmail.com>
2025-10-16 10:37:00 -03:00
Lorenzo Vagliano
0dff60442e Fix: Add obsolete flag to AddUniverse coarse+fine (#9031)
* Fix: Add obsolete flag to AddUniverse coarse+fine

Added obsolete flag to AddUniverse(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector, Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> fineSelector), added one time logging and altered docs accordingly.

* Update QCAlgorithm.Universe.cs

---------

Co-authored-by: Martin-Molinero <martin.molinero1@gmail.com>
2025-10-16 10:24:22 -03:00
Martin-Molinero
d8d6deb675 Add support for Brokerage ActionRequired message type (#9040)
* Add support for Brokerage ActionRequired message type

* Minor syntax check typo fix
2025-10-15 13:05:14 -03:00
Martin-Molinero
81b2d45440 Add Consolidator Optional Start time (#9034)
- Add consolidators optional start time. Adding tests
2025-10-14 11:04:21 -03:00
JosueNina
fda4859b5a Support Future Options for Continuous Futures (#9022)
* Support Future Options for continuous futures

* Solve review comments

* Resolve review comments

* Improve regression algorithms

* Use canonical symbols in OptionChains lookups

* Solve review comments
2025-10-13 18:20:12 -03:00
Martin-Molinero
9fa2630dc8 Add implicit security to symbol (#9032)
- Add implicit conversion from security to symbol. Adding regression
  algorithms
2025-10-13 17:58:57 -03:00
Ryan Crowley
b27e9e67dd ProcessSplitSymbols crashes during live/paper trading warmup with InvalidOperationException #9029 (#9030)
* Fix ProcessSplitSymbols crash during live mode warmup

Fixes InvalidOperationException when CancelOpenOrders is called during warmup in live/paper trading mode.

When historical splits are replayed during live mode warmup, ProcessSplitSymbols attempts to cancel open orders for option contracts, but CancelOpenOrders throws an exception during warmup.

The fix adds an early return when algorithm.LiveMode && algorithm.IsWarmingUp. This is safe because in live/paper trading, current positions already reflect historical splits.

Includes unit tests validating the fix.

* Some improvements and more tests

- Ignore splits during warmup for backtesting and live trading. Adding a
  regression algorithm reproducing issue

* Minor fix

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-10-13 13:21:09 -03:00
Martin-Molinero
afa7cce46a Add ShortMarginInterestRateModel (#9028)
* Add ShortMarginInterestRateModel

- Add new ShortMarginInterestRateModel, and regression algorithms
  asserting the behavior

* Minor syntax check fix
2025-10-13 12:35:03 -03:00
Martin-Molinero
e9c15b2806 Minor refactor to use lazy timer schedling (#9027)
- RateGate, TimeMonitor and ObjectStore won't schedule timer unless
  required
2025-10-13 09:21:27 -03:00
Martin-Molinero
8ee7a190c6 Minor fix for negative rolling window index (#9026)
* Minor fix for negative rolling window index

- Minor fix for negative rolling window index when partially full,
  adding unit test

* Reduce RefreshesSymbolProperties test runtime
2025-10-10 17:47:58 -03:00
Martin-Molinero
ec3b7a8e6a Remove CFD IB MOC and MOO restriction (#9025) 2025-10-10 15:20:27 -03:00
Martin-Molinero
58b422976a Skip langchain from syntax check (#9023) 2025-10-10 11:46:09 -03:00
Martin-Molinero
ee0cf7b3d3 Update virtual-environments.yml 2025-10-10 11:34:26 -03:00
Martin-Molinero
ebda5dba93 Minor api CI fix (#9024) 2025-10-10 10:54:24 -03:00
Martin-Molinero
89110aa9f6 Update PythonVirtualEnvironmentTests.cs 2025-10-09 16:29:06 -03:00
Martin-Molinero
6f94d765fc Update readme.md 2025-10-09 13:14:08 -03:00
Martin-Molinero
fd940463b5 Foundation update oct 2025 (#9020)
* Freeze autoray version to 0.7.2 in foundation image

Required for compatibility with pennylane package

* Update foundation image

- Updating foundation image libraries and new libraries and tests

* Some more foundation tweaks

---------

Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
2025-10-09 12:54:03 -03:00
Roman Yavnikov
3f8fd6ac3d Feature: support ComboLimit Order type in TastyTrade and refactor BrokerageTests (#9003)
* feat: support new OrderType in TastytradeBrokerageModel

* feat: extension GetGroupQuantity

* refactor: WaitOneAssertFail to return bool

* refactor: GetOpenOrders in BrokerageTests

* feat: display holdings when begin/end test run

* refactor: brokerageTest class to support handle combo order
feat: comboOrderTestParameters
feat: tastytrade option strategy algo

* refactor: Tastytrade Algo BullCallSpread

* feat: Bull/Bear-CallSpread test cases in BrokerageTests
feat: ComboLimitOrderTestParameters

* fix: remove static in ComboLimitOrderTestParameters of ExpectedStatus

* feat: restrict submit combo limit cross zero orders in Tastytrade
test:feat: submit combo limit cross zero test cases in tastytrade

* test:fix: missed test helper to c9907b23

* refactor: GetGroupQuantityByEachLegQuantity
feat: overload GreatestCommonDivisor
test:feat: GetGroupQuantityByEachLegQuantity

* test:feat: extra test cases to GetGroupQuantity to 925c214a

* test:refactor: take out Cancel Status update in HandleEvents()

* feat: prop Direction in Leg

* Revert "feat: prop Direction in Leg"

This reverts commit 4f92f97b63.

* refactor: ComboLimitOrderTestParameters

* test:refactor: CancelOrders

* test:feat: add missed xml description

* test:feat: support ModifyUntilFilled Combo orders

* test:feat: Long/Short-Combo unit tests

* test:fix: compare all status if it is combo order type

* test:refactor: applyOrderUpdate in gracefully way in LimitOrderTestParameters

* remover: Tastytrade algo

* test:feat: create new BaseOrderTestParameters with helper methods
test:rename: method in ComboOrderTestParameters
test:remove: duplication
2025-10-06 23:42:30 +03:00
Martin-Molinero
758c1704b5 Minor fix for backtesting stremaing portfolio margin (#9012) 2025-10-03 19:26:10 -03:00
Martin-Molinero
0e5b6ce91e Improve portfolio margin chart (#9011)
- Add StackedBar Series type
- Minor improvements for portfolio margin chart
2025-10-03 17:56:27 -03:00
Jhonathan Abreu
ccf32d3b4f Remove unnecessary constructors from Python models (#9008) 2025-10-02 12:40:29 -04:00
Martin-Molinero
0026cca422 Fix 6N, LBS also ES,EMD,YM,NQ (older) FOP expirations (#9006) 2025-10-01 12:33:46 -03:00
Jhonathan Abreu
633833e3c7 Fix data normalization mode requirement for adding FOP contracts (#9002)
* Fix data normalization mode requirement for adding fop contracts

* Minor change

* Minor fix

* Minor fix
2025-09-30 14:54:04 -04:00
Jhonathan Abreu
be64cdffa0 Minor fix for period history api (#9001)
* Fix extended hours only days period history

Don't include extended hours only days in date range calculated fro period history request

* Add comments

* Cleanup

* Revert some changes

* Cleanup
2025-09-30 09:51:40 -04:00
Martin-Molinero
9670a6684f Fix more FOP expirations (#8998) 2025-09-29 11:42:14 -03:00
Jhonathan Abreu
8447137a3f Add algorithm as parameter to IExecutionModel.OnOrderEvent (#8996) 2025-09-26 17:01:00 -04:00
Martin-Molinero
e75bbf9615 Fix soybean meal & oil FOP expiration (#8995)
* Fix soybean meanl FOP expiration

* Fix Soybean oil FOPs
2025-09-26 17:58:36 -03:00
Jhonathan Abreu
68af7ec15d Expose order ids related to statistics closed trades (#8989)
* Expose related order IDs in closed trades

TradeBuilder.ClosedTrades[*].OrderIds now have the order ids related to each trade

* Minor fix
2025-09-26 11:52:37 -04:00
Jhonathan Abreu
f08ac5bcce Add OnOrderEvent method to IExecutionModel (#8987)
* Add OnOrderEvent to IExecutionModel

Feed order events to execution models

* Minor Python fix
2025-09-26 11:52:28 -04:00
Martin-Molinero
ff2d749d61 Minor performance improvement for session tracking (#8990) 2025-09-25 18:58:41 -03:00
vb-vlb
4cc1dec80b Add VBaseSignalExport (#8954)
* Add VBaseSignalExport

* Add a VBaseSignalExport feature that allows signals to be stamped with the help of the ValidityBase REST API.

* Addressing review comments

* Create DefaultApiBaseUrl  const in VBaseSignalExport

* Add vbase signal export demonstration algorithm

* Set initial parameters for VBaseSignalExportDemonstrationAlgorithm

* Refactor VBaseSignalExport and demonstration algorithm: update symbol list, extend end date, and improve API base URL handling

* Initialize allowed security types in VBaseSignalExport and fix symbol reference in CSV generation

* Adjust rate limiter for vBase signal export to allow 6 requests per hour for better performance

* Minor tweaks

---------

Co-authored-by: Volodymyr Bobko <volodymyr.bobko@un.org>
Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-09-24 12:47:32 -03:00
Roman Yavnikov
75993cd021 Feat: Validation for Market On Open Submission Time (#8969) 2025-09-22 20:40:33 +03:00
JosueNina
f7ce35ae82 Track OHLCV for Current Trading Day (#8922)
* Implement Session class

* Use MarketHourAwareConsolidator inside Session

* Delete SecurityCacheSessionConfig

* Refactor session class

* Solve review comments

* Fix regression algorithms

* Add null check to AvailableDataTypes

* Update session class

* Solve new review comments

* Add new test for futures and update regression test to PEP8

* Add new regression algorithm for Session with futures

* Resolve review comments

* Add local time keeper to SecurityCache

* Scan on consolidator updates and time updates

* Add new regression algorithms and unit tests

* Add unit tests and improve comments

* Fix syntax test

* Solve review comments

* Add regression algorithms

* Resolve review comments

* Make SessionConsolidator implement IDataConsolidator

* Add caching to avoid recreating SessionBar instances on every access

* Solve review comments

* Make SessionConsolidator inherit from MarketHourAwareConsolidator

* Add unit test to verify Session preserves previous day values

* Update regression algorithms

* Solve review comments

* Resolve review comments

* Solve new review comments

* Add unit test for Session class

* Refactor SessionBar properties and Update method

* Use WorkingDataInstance reference instead of _workingData.Clone()

* Use a delegate to get the workingBar instance

* Fix bug in MarketHourAwareConsolidator

* Solve review comments

* Handle OI values

* Add regression algorithms for future contracts and options

* Solve review comments

* Refactor SessionConsolidator to inherit PeriodCountConsolidatorBase

* Prevent overlapping higher resolution data

* Update tests

* Solve review comments

* Minor tweaks
2025-09-19 12:25:24 -05:00
Jhonathan Abreu
36404a6187 Adjust async orders handling in backtesting (#8979)
Submit (and fill in case of market orders) in the same time step even if orders are asynchronous in backtesting since it's data driven instead of real time driven.
2025-09-18 11:53:28 -04:00
Jhonathan Abreu
496f210116 Fix start time calculation for daily requests (#8975)
* Fix start time calculation for daily request

* Minor regression algorithm fix
2025-09-15 18:35:25 -03:00
Jhonathan Abreu
b25d53ed6d Minor config fix (#8974) 2025-09-15 12:48:35 -03:00
Jhonathan Abreu
ee7be1a233 Enable concurrency for live paper brokerage (#8972)
* Enable concurrency for paper brokerage.

Implement PaperBrokerageTransactionHandler to handle concurrency for live paper trading transaction handler

* Remove PaperTradingBrokerageTransaction handler

Favor existing BacktestingTransactionHandler

* Minor fixes and cleanup

* Minor unit tests fix
2025-09-15 09:25:49 -04:00
Jhonathan Abreu
5644520545 Refactor some unit and regression tests for speed improvements (#8970)
* Reduce history unit tests duration

* Unit and regression tests speed improvements

* Minor change

* Fix unit test race condition
2025-09-12 10:15:09 -04:00
Roman Yavnikov
5b465216f9 feat: support StopLimit in CharlesSchwabBrokerageModel (#8968) 2025-09-10 20:15:02 +03:00
Jhonathan Abreu
d82d70dacf Support asynchronous non-market orders (#8946)
* Add 'asynchronous' parameter to trading api

* Add regression algorithms

* More fixes for asynchronous orders

* Fix failing unit tests

* Fix failing unit tests

* Add multiple orders requests in transaction handler

Make each transaction thread handle requests corresponding to the same order

* Refactor order state machine in BrokerageTransactionHandler

Now using a single dictionary to hold orders and their state, either pending for submission, open or closed.

* Revert: remove complete orders from new state machine in BTH

* Add order ticket to new BTH open orders state machine

* Run syn in Backtesting transaction handler for new orders submission

* Remove OpenOrderState.SubmissionPending property

* Add Security to OpenOrderState

* Minor fix

* Cleanup

* Some cleanup in BTH

* Cleanup

* Minor fix

* Minor unit test fix

* Minor fix

* Make Brokerage.ConcurrencyEnable property virtual

* Minor change

* Cleanup

* Add 'asynchronous' parameter to SetHoldings api

* Improve regression algorithms
2025-09-10 08:29:50 -04:00
Roman Yavnikov
23afff13fc Feature: new property AccountType (#8967)
* feat: new prop AccountType

* refactor: change data type use string instead of int for AccountType

* feat: add init of AccountType in ctor
2025-09-09 11:11:16 -03:00
Jhonathan Abreu
d7b4fb002f Make Brokerage.ConcurrencyEnabled virtual (#8966) 2025-09-09 09:39:37 -04:00
Roman Yavnikov
85fe39e31b Fix: prevent use CrossZeroOrder with MOO and MOC (#8959)
* feat: not use CrossZeroOrder for MOO and MOC

* Revert "feat: not use CrossZeroOrder for MOO and MOC"

This reverts commit 1a71c5fe90.

* feat: Not support crossZeroOrderTypes
test:feat: cross zero orders

* Revert "feat: Not support crossZeroOrderTypes"

This reverts commit 16785b5d2f.

* feat: not support CrossZeroOrder in TradeStation

* feat: not allow to place MOO and MOC with CrossZeroOrder

* test:feat: MOO and MOC CrossZeroOrder reject
2025-09-08 22:44:13 +03:00
Martin-Molinero
690eb7fc9f Fix python packages CI tests (#8962)
* Fix python packages CI tests

* Remove failing onnx related tests
2025-09-08 11:57:32 -03:00
Martin-Molinero
e44f8cd498 Minor fix for lean data writer merge policy (#8952)
* Minor fix for lean data writer merge policy

- Fix typo in lean data writer merge policy. Enhancing existing unit
  tests

* Minor unit test fix
2025-09-03 12:25:18 -03:00
Roman Yavnikov
ceb52c1b9b feat: make virtual Subscribe() in DataQueueHandlerSubscriptionManager 2025-08-29 18:36:11 +03:00
Jhonathan Abreu
dea1d2eac3 Update Python syntax check rate script accepted success rate (#8944)
* Update Python syntax check script

* Update python syntax check script accepted success rate
2025-08-27 17:28:46 -04:00
Martin-Molinero
f448ab7372 Update run_syntax_check.py 2025-08-27 10:28:49 -03:00
Martin-Molinero
fd9c29c87c Add US futures market halt (#8943) 2025-08-27 10:27:17 -03:00
Jhonathan Abreu
0b62fefb10 Add CFE futures 2026 holidays to MHDB (#8942)
* Add CFE futures 2026 holidays to MHDB

* Fix typo
2025-08-26 12:51:39 -04:00
Jhonathan Abreu
e13214135a Add support for some CME currencies FOPs (#8939)
* Add support for some CME currencies FOPs

Support ADU (6A), GBU (6B), CAU (6C), EUU (6E), JPU (6J), CHU (6S)

* Cleanup

* Consider holidays in FOPs expiry function
2025-08-25 18:02:07 -04:00
Roman Yavnikov
c2fdfb235a feat: global OrderProperties property in abstract Brokerage class to liquidate positions with specific properties (#8938)
fix: missed OrderStatus in ...OrderTestParameters classes
feat: override ToString() in ...OrderTestParameters classes
2025-08-21 19:13:15 -03:00
Jhonathan Abreu
50f8633e90 More Python syntax checks and improvements (#8937)
* More python syntax checks

* More changes

* More changes

* Make PythonConsolidator derive from IDataConsolidator

* More changes

* More changes

* Update python syntax check accepted rate

* Update Update python syntax check accepted rate

* Cleanup

* Cleanup
2025-08-21 12:47:38 -04:00
Martin-Molinero
a3ad12e7e0 Fix tick resolution continuous contract history request (#8936)
- Fix tick resolution continuous contract history requests. Adding unit
  tests
- Some improvements for OpenInterest explicit request. Adding unit tests
2025-08-19 14:21:49 -03:00
Martin-Molinero
db25a3402e Normalize OutOfSampleMaxEndDate datetime format (#8935)
- Normalize OutOfSampleMaxEndDate datetime format. Adding unit test
2025-08-18 18:44:25 -03:00
Martin-Molinero
06f0da69c3 Improve schedule rules symbol handling (#8930)
- Improve schedule rules non existing symbol handling. Adding regression
  tests
2025-08-15 14:59:11 -03:00
Jhonathan Abreu
838232e696 Update Pythonnet version to 2.0.48 (#8929) 2025-08-15 13:04:02 -04:00
JosueNina
e13f8c10a7 Add tag to RemoveSecurity method (#8928)
* Add tag parameter, update CancelOpenOrders and Liquidate calls

* Resolved commen on the related PR: following the pattern of Liquidate() using Liquidated as default, I think the tag should be Removed

* Add tag parameter to RemoveSecurity and update regression algorithms

* Minor tweaks

---------

Co-authored-by: meysam <poormonfared.azimi@gmail.com>
Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-08-15 10:40:35 -03:00
Jhonathan Abreu
4c3e79b441 Bump Pythonnet version to 2.0.47 (#8927) 2025-08-14 12:09:07 -04:00
Martin-Molinero
cffd20236c Object store dispose hang (#8925) 2025-08-13 18:18:48 -03:00
Martin-Molinero
3f04b6c90a Update readme.md 2025-08-13 15:04:36 -03:00
Martin-Molinero
852c9cd856 Update IB gateway v10.39.1f (#8923) 2025-08-13 14:51:48 -03:00
Martin-Molinero
37237206dd Use ISO for DateTime JsonConverter (#8919)
- Use ISO for DateTime JsonConverter, keeping backwards compatible.
  Adding unit test
2025-08-13 10:27:30 -03:00
Jared
58979872c1 Delete Api/QuantConnect-Platform-2.0.0.yaml (#8924)
YAML is now hosted in the documentation 
https://github.com/QuantConnect/Documentation/blob/master/QuantConnect-Platform-2.0.0.yaml
2025-08-13 09:43:46 -03:00
1064 changed files with 46295 additions and 50810 deletions

View File

@@ -28,9 +28,9 @@ jobs:
shell: bash
run: |
# install dependencies
pip3 install papermill==2.4.0 clr-loader==0.1.6
pip3 install papermill==2.4.0 clr-loader==0.2.9
# install kernel
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.607001
dotnet tool install -g --no-cache --version 1.0.661703 --add-source "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" Microsoft.dotnet-interactive
# Add dotnet tools to Path
export PATH="$HOME/.dotnet/tools:$PATH"
# activate kernel for jupyter

View File

@@ -28,5 +28,5 @@ jobs:
options: --workdir /__w/Lean/Lean -v /home/runner/work:/__w
shell: bash
run: |
pip install --no-cache-dir quantconnect-stubs types-requests==2.32.* mypy==1.15.0 && \
pip install --no-cache-dir quantconnect-stubs types-requests==2.32.* types-pytz==2025.2.0.* mypy==1.15.0 && \
python run_syntax_check.py

View File

@@ -30,11 +30,11 @@ jobs:
# Build
dotnet build /p:Configuration=Release /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln && \
# Python Virtual Environment System Packages
python -m venv /lean-testenv --system-site-packages && . /lean-testenv/bin/activate && pip install --no-cache-dir lean==1.0.185 && deactivate && \
python -m venv /lean-testenv --system-site-packages && . /lean-testenv/bin/activate && pip install --no-cache-dir lean==1.0.221 && deactivate && \
# Run Virtual Environment Test System Packages
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonVirtualEnvironmentTests.AssertVirtualEnvironment" && \
# Python Virtual Environment
rm -rf /lean-testenv && python -m venv /lean-testenv && . /lean-testenv/bin/activate && pip install --no-cache-dir lean==1.0.185 && deactivate && \
rm -rf /lean-testenv && python -m venv /lean-testenv && . /lean-testenv/bin/activate && pip install --no-cache-dir lean==1.0.221 && deactivate && \
# Run Virtual Environment Test
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonVirtualEnvironmentTests.AssertVirtualEnvironment" && \
# Run Python Package Tests
@@ -46,19 +46,21 @@ jobs:
# Run TensorlyTest Python Package Test
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.TensorlyTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run NeuralTangents, Ignite Python Package Test
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.NeuralTangentsTest|IgniteTest" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.IgniteTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run TensorflowTest
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.TensorflowTest" --blame-hang-timeout 120seconds --blame-crash && \
# Run TensorflowProbability
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 && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.RiskparityportfolioTest" --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|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.KerasTest|PyvinecopulibTest" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.StatsForecast|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 && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ModuleVersionTestExplicit" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Neuralforecast" --blame-hang-timeout 120seconds --blame-crash
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Neuralforecast" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Tsfel" --blame-hang-timeout 120seconds --blame-crash && \
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ScikitOptimizeTest" --blame-hang-timeout 120seconds --blame-crash

View File

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

View File

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

View File

@@ -1,11 +1,11 @@
/*
* 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");
*
* 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.
@@ -107,7 +107,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 77;
public int AlgorithmHistoryDataPoints => 26;
/// <summary>
/// Final status of the algorithm
@@ -122,18 +122,18 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "436"},
{"Average Win", "0.28%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "1.926%"},
{"Compounding Annual Return", "1.925%"},
{"Drawdown", "1.000%"},
{"Expectancy", "1.650"},
{"Expectancy", "1.649"},
{"Start Equity", "10000.00"},
{"End Equity", "10411.11"},
{"Net Profit", "4.111%"},
{"End Equity", "10410.99"},
{"Net Profit", "4.110%"},
{"Sharpe Ratio", "0.332"},
{"Sortino Ratio", "0.313"},
{"Probabilistic Sharpe Ratio", "74.084%"},
{"Loss Rate", "90%"},
{"Win Rate", "10%"},
{"Profit-Loss Ratio", "25.26"},
{"Profit-Loss Ratio", "25.25"},
{"Alpha", "0.003"},
{"Beta", "0.001"},
{"Annual Standard Deviation", "0.01"},
@@ -146,7 +146,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "BTCUSD 2XR"},
{"Portfolio Turnover", "2.22%"},
{"Drawdown Recovery", "139"},
{"OrderListHash", "9fce77ef8817cf0159897fc64d01f5e9"}
{"OrderListHash", "896ecc92440d51ed26644aac5b8706e4"}
};
}
}

View File

@@ -132,34 +132,34 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "3"},
{"Total Orders", "4"},
{"Average Win", "0%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "-2.594%"},
{"Drawdown", "0.000%"},
{"Average Loss", "-0.10%"},
{"Compounding Annual Return", "-14.232%"},
{"Drawdown", "0.200%"},
{"Expectancy", "-1"},
{"Start Equity", "100000"},
{"End Equity", "99966.4"},
{"Net Profit", "-0.034%"},
{"Sharpe Ratio", "-10.666"},
{"End Equity", "99803.9"},
{"Net Profit", "-0.196%"},
{"Sharpe Ratio", "-7.95"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "1.216%"},
{"Loss Rate", "100%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.029"},
{"Beta", "0.004"},
{"Annual Standard Deviation", "0.003"},
{"Alpha", "-0.128"},
{"Beta", "0.026"},
{"Annual Standard Deviation", "0.016"},
{"Annual Variance", "0"},
{"Information Ratio", "-0.768"},
{"Tracking Error", "0.241"},
{"Treynor Ratio", "-6.368"},
{"Information Ratio", "-1.186"},
{"Tracking Error", "0.237"},
{"Treynor Ratio", "-4.747"},
{"Total Fees", "$8.60"},
{"Estimated Strategy Capacity", "$5500000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "66.80%"},
{"Estimated Strategy Capacity", "$2000.00"},
{"Lowest Capacity Asset", "ES VU1EHIDJYLMP"},
{"Portfolio Turnover", "66.50%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "579e2e83dd7e5e7648c47e9eff132460"}
{"OrderListHash", "4720516462fcabb4db1aead46051cb4a"}
};
}
}

View File

@@ -134,10 +134,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "68696.045"},
{"Total Fees", "$35.70"},
{"Estimated Strategy Capacity", "$2600000.00"},
{"Lowest Capacity Asset", "ES 31C3JQS9D84PW|ES XCZJLC9NOB29"},
{"Lowest Capacity Asset", "ES 31C3JQS9DCF1G|ES XCZJLC9NOB29"},
{"Portfolio Turnover", "495.15%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "85257286f088992d599c1ad0799a6237"}
{"OrderListHash", "af830085995d0b8fa0d33a6e80dd1241"}
};
}
}

View File

@@ -0,0 +1,145 @@
/*
* 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.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
using QuantConnect.Securities.Option;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Algorithm asserting AddFutureOptionContract does not throw even when the underlying security configurations are internal
/// </summary>
public class AddFutureOptionContractWithInternalMappedUnderlyingRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Future _continuousContract;
private Option _fopContract;
public override void Initialize()
{
SetStartDate(2020, 01, 04);
SetEndDate(2020, 01 , 06);
_continuousContract = AddFuture(Futures.Indices.SP500EMini,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.LastTradingDay,
contractDepthOffset: 0);
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.AddedSecurities.Any(security => security.Symbol == _continuousContract.Symbol))
{
if (SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(_continuousContract.Mapped).Count != 0 ||
SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(_continuousContract.Mapped, includeInternalConfigs: true).Count == 0)
{
throw new RegressionTestException("Continuous future underlying should only have internal subscription configs");
}
var contract = OptionChain(_continuousContract.Mapped).FirstOrDefault()?.Symbol;
try
{
_fopContract = AddFutureOptionContract(contract);
}
catch (Exception e)
{
throw new RegressionTestException($"Failed to add future option contract {contract}", e);
}
}
else if (_fopContract != null && changes.AddedSecurities.Any(security => security.Symbol == _fopContract.Symbol))
{
var underlyingSubscriptions = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(_fopContract.Symbol.Underlying);
if (underlyingSubscriptions.Any(x => x.DataNormalizationMode == DataNormalizationMode.Raw))
{
throw new RegressionTestException("Future option underlying should not have raw data normalization mode");
}
}
}
public override void OnEndOfAlgorithm()
{
if (_fopContract == null)
{
throw new RegressionTestException("Failed to add future option contract");
}
}
/// <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 long DataPoints => 3181;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 1;
/// <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", "-14.395"},
{"Tracking Error", "0.043"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -240,31 +240,31 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "309.669%"},
{"Drawdown", "0.900%"},
{"Compounding Annual Return", "430.834%"},
{"Drawdown", "4.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101950.53"},
{"Net Profit", "1.951%"},
{"Sharpe Ratio", "15.402"},
{"End Equity", "102313.03"},
{"Net Profit", "2.313%"},
{"Sharpe Ratio", "17.721"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "95.977%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "1.886"},
{"Beta", "1.066"},
{"Annual Standard Deviation", "0.155"},
{"Annual Variance", "0.024"},
{"Information Ratio", "13.528"},
{"Tracking Error", "0.142"},
{"Treynor Ratio", "2.237"},
{"Alpha", "2.663"},
{"Beta", "1.264"},
{"Annual Standard Deviation", "0.184"},
{"Annual Variance", "0.034"},
{"Information Ratio", "16.514"},
{"Tracking Error", "0.169"},
{"Treynor Ratio", "2.574"},
{"Total Fees", "$3.57"},
{"Estimated Strategy Capacity", "$760000.00"},
{"Lowest Capacity Asset", "ES XCZJLDQX2SRO|ES XCZJLC9NOB29"},
{"Portfolio Turnover", "32.31%"},
{"Estimated Strategy Capacity", "$28000000.00"},
{"Lowest Capacity Asset", "ES XCZJLCA62LNO|ES XCZJLC9NOB29"},
{"Portfolio Turnover", "33.84%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "7a04f66a30d793bf187c2695781ad3ee"}
{"OrderListHash", "7c82013ecabca41591e0253a477025dd"}
};
}
}

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 37597;
public long DataPoints => 37598;
/// <summary>
/// Data Points count of the algorithm history
@@ -158,10 +158,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "2.01"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$5700000.00"},
{"Lowest Capacity Asset", "AOL VRKS95ENLBYE|AOL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AOL VRKS95ENPM9Y|AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.55%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "fc5ab25181a01ca5ce39212f60eb0ecd"}
{"OrderListHash", "d314aef81752b6583fd58f9e49054cd4"}
};
}
}

View File

@@ -169,7 +169,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 5798;
public long DataPoints => 5800;
/// <summary>
/// Data Points count of the algorithm history
@@ -210,10 +210,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0.335"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$2800000.00"},
{"Lowest Capacity Asset", "AOL VRKS95ENLBYE|AOL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AOL VRKS95ENPM9Y|AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "1.14%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "cde7b518b7ad6d86cff6e5e092d9a413"}
{"OrderListHash", "e33b98d8e94ed92d0441fc6fe0d461fb"}
};
}
}

View File

@@ -116,7 +116,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 3814;
public long DataPoints => 3818;
/// <summary>
/// Data Points count of the algorithm history
@@ -157,10 +157,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$5000000.00"},
{"Lowest Capacity Asset", "AAPL VXBK4R62CXGM|AAPL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AAPL VXBK4R62H7S6|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "22.70%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "29fd1b75f6db05dd823a6db7e8bd90a9"}
{"OrderListHash", "71511e4929377cd55fbf5e7e9555c248"}
};
}
}

View File

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

View File

@@ -246,10 +246,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$6.00"},
{"Estimated Strategy Capacity", "$4000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ2BZBZT2|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV 305RBQ2BZGA4M|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "2.58%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "09f766c470a8bcf4bb6862da52bf25a7"}
{"OrderListHash", "f418de0673fc166487daf80991dfe3a0"}
};
}
}

View File

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

View File

@@ -110,7 +110,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 7063;
public long DataPoints => 7065;
/// <summary>
/// Data Points count of the algorithm history
@@ -154,7 +154,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "AIG R735QTJ8XC9X"},
{"Portfolio Turnover", "29.88%"},
{"Drawdown Recovery", "2"},
{"OrderListHash", "6061ecfbb89eb365dff913410d279b7c"}
{"OrderListHash", "f04b3521256c7d6740966bc3df34e7b1"}
};
}
}

View File

@@ -101,7 +101,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 1578;
public long DataPoints => 1579;
/// <summary>
/// Data Points count of the algorithm history
@@ -142,10 +142,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$6200000.00"},
{"Lowest Capacity Asset", "AAPL VXBK4QA5EM92|AAPL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AAPL VXBK4QA5IWKM|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "90.27%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "a111609c2c64554268539b5798e5b31f"}
{"OrderListHash", "a332b93ff5e2dfe89258c450a64c7125"}
};
}
}

View File

@@ -38,7 +38,7 @@ namespace QuantConnect.Algorithm.CSharp
SetEndDate(2013, 10, 10);
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
_symbol = FuturesChain(SP500).First();
_symbol = FuturesChain(SP500).OrderBy(x => x.Symbol.ID.Date).First();
// Test case: custom IndicatorBase<QuoteBar> indicator using Future unsubscribed symbol
var indicator1 = new CustomIndicator();

View File

@@ -0,0 +1,137 @@
/*
* 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.Interfaces;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Data.Market;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that security are automatically seeded by default
/// </summary>
public abstract class AutomaticSeedBaseRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
protected virtual bool ShouldHaveTradeData { get; }
protected virtual bool ShouldHaveQuoteData { get; }
protected virtual bool ShouldHaveOpenInterestData { get; }
public override void OnSecuritiesChanged(SecurityChanges changes)
{
var gotTrades = false;
var gotQuotes = false;
var gotOpenInterest = false;
foreach (var addedSecurity in changes.AddedSecurities.Where(x => !x.Symbol.IsCanonical() || x.Symbol.SecurityType == SecurityType.Future))
{
if (addedSecurity.Price == 0)
{
throw new RegressionTestException("Security was not seeded");
}
if (!addedSecurity.HasData)
{
throw new RegressionTestException("Security does not have TradeBar or QuoteBar or OpenInterest data");
}
gotTrades |= addedSecurity.Cache.GetData<TradeBar>() != null;
gotQuotes |= addedSecurity.Cache.GetData<QuoteBar>() != null;
gotOpenInterest |= addedSecurity.Cache.GetData<OpenInterest>() != null;
}
if (changes.AddedSecurities.Count > 0)
{
if (ShouldHaveTradeData && !gotTrades)
{
throw new RegressionTestException("No contract had TradeBar data");
}
if (ShouldHaveQuoteData && !gotQuotes)
{
throw new RegressionTestException("No contract had QuoteBar data");
}
if (ShouldHaveOpenInterestData && !gotOpenInterest)
{
throw new RegressionTestException("No contract had OpenInterest 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 };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public abstract long DataPoints { get; }
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public abstract int AlgorithmHistoryDataPoints { get; }
/// <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", "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%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

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

View File

@@ -0,0 +1,156 @@
/*
* 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.Interfaces;
using QuantConnect.Orders;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that in backtesting, orders are submitted in the same time step even when asynchronous
/// </summary>
public class BacktestingAsynchronousOrdersRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _symbol;
public override void Initialize()
{
SetStartDate(2013, 10, 07);
SetEndDate(2013, 10, 08);
SetCash(100000);
_symbol = AddEquity("SPY").Symbol;
}
public override void OnData(Slice slice)
{
if (!Portfolio.Invested)
{
var marketOrderTicket = MarketOrder(_symbol, 100, asynchronous: false);
AssertMarketOrderStatus(marketOrderTicket);
var asyncMarketOrderTicket = MarketOrder(_symbol, -100, asynchronous: true);
AssertMarketOrderStatus(asyncMarketOrderTicket);
var limitPrice = Securities[_symbol].Price * 0.95m;
var limitOrderTicket = LimitOrder(_symbol, 100, limitPrice, asynchronous: false);
AssertLimitOrderStatus(limitOrderTicket);
var asyncLimitOrderTicket = LimitOrder(_symbol, -100, limitPrice, asynchronous: true);
AssertLimitOrderStatus(asyncLimitOrderTicket);
}
}
private static void AssertMarketOrderStatus(OrderTicket ticket)
{
// In backtesting the order should be submitted and filled right away.
// Note that OrderSet event will not be fired if there is an error when processing the order submission,
// but this is a happy case
if (!ticket.OrderSet.WaitOne(0))
{
throw new RegressionTestException("Order was not submitted immediately in backtesting mode");
}
if (!ticket.OrderClosed.WaitOne(0))
{
throw new RegressionTestException("Order was not filled immediately in backtesting mode");
}
if (ticket.Status != OrderStatus.Filled)
{
throw new RegressionTestException($"Order status is not filled: {ticket.Status}");
}
}
private static void AssertLimitOrderStatus(OrderTicket ticket)
{
// In backtesting the order should be submitted right away but not filled since price hasn't moved even when asynchronous
// Note that OrderSet event will not be fired if there is an error when processing the order submission,
// but this is a happy case
if (!ticket.OrderSet.WaitOne(0))
{
throw new RegressionTestException("Asynchronous limit order was not submitted immediately in backtesting mode");
}
if (ticket.OrderClosed.WaitOne(0))
{
throw new RegressionTestException("Asynchronous limit order was filled immediately in backtesting mode when it shouldn't");
}
if (ticket.Status != OrderStatus.Submitted)
{
throw new RegressionTestException($"Order status is not submitted: {ticket.Status}");
}
}
/// <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 long DataPoints => 1582;
/// <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", "4"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100168.20"},
{"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", "$3.00"},
{"Estimated Strategy Capacity", "$22000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "21.72%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "65f010e904a929e5383f0920a3c5b797"}
};
}
}

View File

@@ -340,7 +340,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "17.02%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "a7ce5ff2bbe0fe273cf1631ea5a73fa6"}
{"OrderListHash", "1be5073f2cf8802ffa163f7dab7d040e"}
};
}
}

View File

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

View File

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

View File

@@ -202,7 +202,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 240;
public int AlgorithmHistoryDataPoints => 35;
/// <summary>
/// Final status of the algorithm
@@ -220,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "31588.24"},
{"Start Equity", "31592.84"},
{"End Equity", "30866.71"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},

View File

@@ -119,9 +119,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected holdings cost {btcUsdHoldings.HoldingsCost}");
}
// margin used is based on the maintenance rate
if (Math.Abs(btcUsdHoldings.AbsoluteHoldingsCost * 0.05m - marginUsed) > 1
|| _btcUsd.BuyingPowerModel.GetMaintenanceMargin(_btcUsd) != marginUsed)
if (_btcUsd.BuyingPowerModel.GetMaintenanceMargin(_btcUsd) != marginUsed)
{
throw new RegressionTestException($"Unexpected margin used {marginUsed}");
}
@@ -142,8 +140,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected holdings cost {adaUsdtHoldings.HoldingsCost}");
}
if (Math.Abs(adaUsdtHoldings.AbsoluteHoldingsCost * 0.05m - marginUsed) > 1
|| _adaUsdt.BuyingPowerModel.GetMaintenanceMargin(_adaUsdt) != marginUsed)
if (_adaUsdt.BuyingPowerModel.GetMaintenanceMargin(_adaUsdt) != marginUsed)
{
throw new RegressionTestException($"Unexpected margin used {marginUsed}");
}
@@ -273,7 +270,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.65"},
{"Estimated Strategy Capacity", "$500000000.00"},
{"Estimated Strategy Capacity", "$620000000.00"},
{"Lowest Capacity Asset", "ADAUSDT 18R"},
{"Portfolio Turnover", "0.16%"},
{"Drawdown Recovery", "0"},

View File

@@ -93,7 +93,7 @@ namespace QuantConnect.Algorithm.CSharp
if (!Portfolio.Invested && Transactions.OrdersCount == 0)
{
var ticket = Buy(_adaUsdt.Symbol, 100000);
if(ticket.Status != OrderStatus.Invalid)
if (ticket.Status != OrderStatus.Invalid)
{
throw new RegressionTestException($"Unexpected valid order {ticket}, should fail due to margin not sufficient");
}
@@ -114,8 +114,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected holdings cost {adaUsdtHoldings.HoldingsCost}");
}
if (Math.Abs(adaUsdtHoldings.AbsoluteHoldingsCost * 0.05m - marginUsed) > 1
|| _adaUsdt.BuyingPowerModel.GetMaintenanceMargin(_adaUsdt) != marginUsed)
if (_adaUsdt.BuyingPowerModel.GetMaintenanceMargin(_adaUsdt) != marginUsed)
{
throw new RegressionTestException($"Unexpected margin used {marginUsed}");
}
@@ -236,7 +235,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.61"},
{"Estimated Strategy Capacity", "$370000000.00"},
{"Estimated Strategy Capacity", "$460000000.00"},
{"Lowest Capacity Asset", "ADAUSDT 18R"},
{"Portfolio Turnover", "0.12%"},
{"Drawdown Recovery", "0"},

View File

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

View File

@@ -127,7 +127,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 5861;
public virtual long DataPoints => 5867;
/// <summary>
/// Data Points count of the algorithm history
@@ -144,34 +144,34 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "34"},
{"Total Orders", "38"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.106%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "0.098%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.178"},
{"Expectancy", "0.165"},
{"Start Equity", "1000000"},
{"End Equity", "1001066.2"},
{"Net Profit", "0.107%"},
{"Sharpe Ratio", "-1.695"},
{"Sortino Ratio", "-0.804"},
{"Probabilistic Sharpe Ratio", "14.797%"},
{"Loss Rate", "88%"},
{"Win Rate", "12%"},
{"Profit-Loss Ratio", "9.01"},
{"End Equity", "1000991.96"},
{"Net Profit", "0.099%"},
{"Sharpe Ratio", "-1.708"},
{"Sortino Ratio", "-0.84"},
{"Probabilistic Sharpe Ratio", "14.542%"},
{"Loss Rate", "89%"},
{"Win Rate", "11%"},
{"Profit-Loss Ratio", "10.07"},
{"Alpha", "-0.007"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.353"},
{"Information Ratio", "-1.354"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-4.112"},
{"Total Fees", "$76.30"},
{"Treynor Ratio", "-4.054"},
{"Total Fees", "$85.54"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.92%"},
{"Portfolio Turnover", "1.04%"},
{"Drawdown Recovery", "69"},
{"OrderListHash", "ddaa9dd20647fdbc4811d6e64bb30a40"}
{"OrderListHash", "eafc33ea4dcb219f7aacdbdd0973d5bc"}
};
}
}

View File

@@ -36,7 +36,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 25312;
public override long DataPoints => 25339;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
@@ -70,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "20.14%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "f6482c8757f82cb9f4c058e3ed6bc494"}
{"OrderListHash", "c301a0a086f8905b1a555f0257087272"}
};
}
}

View File

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

View File

@@ -36,41 +36,41 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 5965;
public override long DataPoints => 5971;
/// <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", "32"},
{"Total Orders", "36"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "0.103%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.184"},
{"Expectancy", "0.172"},
{"Start Equity", "1000000"},
{"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"},
{"End Equity", "1001033.76"},
{"Net Profit", "0.103%"},
{"Sharpe Ratio", "-1.701"},
{"Sortino Ratio", "-0.809"},
{"Probabilistic Sharpe Ratio", "14.685%"},
{"Loss Rate", "89%"},
{"Win Rate", "11%"},
{"Profit-Loss Ratio", "9.55"},
{"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.042"},
{"Total Fees", "$81.24"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.87%"},
{"Portfolio Turnover", "0.99%"},
{"Drawdown Recovery", "69"},
{"OrderListHash", "741a26424d2210171ad849d92fc75d23"}
{"OrderListHash", "67120ad5c9a6116001dda6c8061e5353"}
};
}
}

View File

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

View File

@@ -168,10 +168,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-1.771"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P3GHIA9A|SPX 31"},
{"Portfolio Turnover", "23.97%"},
{"Drawdown Recovery", "9"},
{"OrderListHash", "51f1bc2ea080df79748dc66c2520b782"}
{"OrderListHash", "4b560d2a8cfae510c3c8dc92603470fc"}
};
}
}

View File

@@ -147,10 +147,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-6.937"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P3GHIA9A|SPX 31"},
{"Portfolio Turnover", "2.42%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "61e8517ac3da6bed414ef23d26736fef"}
{"OrderListHash", "ce421d0aeb7bde3bc92a6b87c09c510e"}
};
}
}

View File

@@ -64,10 +64,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-6.189"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$300000.00"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P3GHIA9A|SPX 31"},
{"Portfolio Turnover", "24.63%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "5595ab834c2584c1d124ad575e88cc1a"}
{"OrderListHash", "7bc05310e971f09b0663bc380fdfee80"}
};
}
}

View File

@@ -108,10 +108,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-44.954"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P59H9OI6|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "8340619d603921c1ce261287890b9c1c"}
{"OrderListHash", "34d295b82e29b1dbe8f104d3300d9255"}
};
}
}

View File

@@ -79,10 +79,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "116.921"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P59H9OI6|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "1c5f424cfe62777733ee68a20320bb8d"}
{"OrderListHash", "214026660a13ecaecc7074fa97f86ea1"}
};
}
}

View File

@@ -44,7 +44,7 @@ namespace QuantConnect.Algorithm.CSharp
_optionSymbol = option.Symbol;
// set our strike/expiry filter for this option chain
option.SetFilter(u => u.Strikes(-2, +2)
option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2)
// Expiration method accepts TimeSpan objects or integer for days.
// The following statements yield the same filtering criteria
.Expiration(0, 180));
@@ -73,7 +73,7 @@ namespace QuantConnect.Algorithm.CSharp
var higherStrike = callContracts[2].Strike;
var optionStrategy = OptionStrategies.CallButterfly(_optionSymbol, higherStrike, middleStrike, lowerStrike, expiry);
Order(optionStrategy, 10);
}
}
@@ -143,10 +143,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$69000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAT67A|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "61.31%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "35d406df401e5b27244e20f5ec57346e"}
{"OrderListHash", "ccd6cb1b6244d0c6d30b2760938958f1"}
};
}
}

View File

@@ -50,8 +50,9 @@ namespace QuantConnect.Algorithm.CSharp
// set our strike/expiry filter for this option chain
// SetFilter method accepts TimeSpan objects or integer for days.
// The following statements yield the same filtering criteria
option.SetFilter(-2, +2, 0, 180);
// option.SetFilter(-2, +2, TimeSpan.Zero, TimeSpan.FromDays(180));
option.SetFilter(u => u.StandardsOnly()
.Strikes(-2, +2)
.Expiration(0, 180));
// Adding this to reproduce GH issue #2314
SetWarmup(TimeSpan.FromMinutes(1));
@@ -83,7 +84,7 @@ namespace QuantConnect.Algorithm.CSharp
Liquidate();
}
foreach(var kpv in slice.Bars)
foreach (var kpv in slice.Bars)
{
Log($"---> OnData: {Time}, {kpv.Key.Value}, {kpv.Value.Close:0.00}");
}
@@ -153,10 +154,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$543.40"},
{"Estimated Strategy Capacity", "$4000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZFMEBBB2E|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZFMEBFLDY|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "338.60%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "301c15063f6e269023d144ca69a765da"}
{"OrderListHash", "8229716b93428dc885cf856b4cc9fc35"}
};
}
}

View File

@@ -48,11 +48,10 @@ namespace QuantConnect.Algorithm.CSharp
_optionSymbol = option.Symbol;
// set our strike/expiry filter for this option chain
option.SetFilter(u => u.Strikes(-2, +2)
option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2)
// Expiration method accepts TimeSpan objects or integer for days.
// The following statements yield the same filtering criteria
.Expiration(0, 180));
// .Expiration(TimeSpan.Zero, TimeSpan.FromDays(180)));
.Expiration(0, 180)); // .Expiration(TimeSpan.Zero, TimeSpan.FromDays(180)));
// use the underlying equity as the benchmark
SetBenchmark(equity.Symbol);
@@ -150,10 +149,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$1300000.00"},
{"Lowest Capacity Asset", "GOOCV 30AKMEIPOSS1Y|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV 30AKMEIPOX2DI|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "10.71%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "8a36462ee0349c04d01d464e592dd347"}
{"OrderListHash", "19ba1220073493495880581b38df2da9"}
};
}
}

View File

@@ -163,10 +163,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-3.212"},
{"Total Fees", "$1.00"},
{"Estimated Strategy Capacity", "$72000.00"},
{"Lowest Capacity Asset", "AAPL W78ZEO2985GM|AAPL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AAPL W78ZEO29CFS6|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.02%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "5e20fad3461ac9998afe8d76ad43b25c"}
{"OrderListHash", "5639c19a7d56ec312f61029b943903b8"}
};
}
}

View File

@@ -143,7 +143,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "15.08%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "f68f6d64a5721ee148bc3c643f8d1b7f"}
{"OrderListHash", "c53bc9318676161ed3b7797c945e2113"}
};
}
}

View File

@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 17486;
public long DataPoints => 17487;
/// <summary>
/// Data Points count of the algorithm history
@@ -183,7 +183,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "13.50%"},
{"Drawdown Recovery", "2"},
{"OrderListHash", "d40c84371facba5dac8a2c919ea75807"}
{"OrderListHash", "2ab4ffc0944a2888a3be0568c2570a79"}
};
}
}

View File

@@ -48,7 +48,7 @@ namespace QuantConnect.Algorithm.CSharp
_optionSymbol = option.Symbol;
// set our strike/expiry filter for this option chain
option.SetFilter(u => u.Strikes(-2, +2)
option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2)
// Expiration method accepts TimeSpan objects or integer for days.
// The following statements yield the same filtering criteria
.Expiration(0, 180));
@@ -150,10 +150,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "1.434"},
{"Total Fees", "$4.00"},
{"Estimated Strategy Capacity", "$1000.00"},
{"Lowest Capacity Asset", "AAPL 2ZTXYMUAHCIAU|AAPL R735QTJ8XC9X"},
{"Lowest Capacity Asset", "AAPL 2ZTXYMUAHGSME|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "2.28%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "7804b3dcf20d3096a2265a289fa81cd3"}
{"OrderListHash", "70bbc60c969f18e943e8e00cf0f7a0ea"}
};
}
}

View File

@@ -144,10 +144,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-0.725"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$580000.00"},
{"Lowest Capacity Asset", "SPXW 31K54PVWHUJHQ|SPX 31"},
{"Lowest Capacity Asset", "SPXW 31K54PVWHYTTA|SPX 31"},
{"Portfolio Turnover", "0.40%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "db5e3681c5fa1888262f2370a9b14c11"}
{"OrderListHash", "03148bbb5453fc1056a3285bd31ce158"}
};
}
}

View File

@@ -150,10 +150,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0.589"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$13000000.00"},
{"Lowest Capacity Asset", "SPXW XKX6S2GM9PGU|SPX 31"},
{"Lowest Capacity Asset", "SPXW XKX6S2GMDZSE|SPX 31"},
{"Portfolio Turnover", "0.28%"},
{"Drawdown Recovery", "2"},
{"OrderListHash", "17764ae9e216d003b1f3ce68d15b68ef"}
{"OrderListHash", "9d03f85003416861df07ccb31a18af9a"}
};
}
}

View File

@@ -87,10 +87,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-1.771"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Lowest Capacity Asset", "SPX XL80P3GHIA9A|SPX 31"},
{"Portfolio Turnover", "24.03%"},
{"Drawdown Recovery", "9"},
{"OrderListHash", "fcd6fddb0a315e21095c2b35eb633e2b"}
{"OrderListHash", "691cf4990024b856a0a70255c9fd2545"}
};
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.Benchmarks
{
/// <summary>
/// Benchmark Algorithm that adds SPX option chain but does not trade it.
/// This is an interesting benchmark because SPX option chains are large
/// </summary>
public class EmptySPXOptionChainBenchmark : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2018, 1, 1);
SetEndDate(2020, 6, 1);
var index = AddIndex("SPX");
var option = AddOption(index);
option.SetFilter(x => x.IncludeWeeklys().Strikes(-30, 30).Expiration(0, 7));
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -112,9 +112,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected holdings cost {btcUsdHoldings.HoldingsCost}");
}
// margin used is based on the maintenance rate
if (Math.Abs(btcUsdHoldings.AbsoluteHoldingsCost * 0.05m - marginUsed) > 1
|| _btcUsd.BuyingPowerModel.GetMaintenanceMargin(_btcUsd) != marginUsed)
if (_btcUsd.BuyingPowerModel.GetMaintenanceMargin(_btcUsd) != marginUsed)
{
throw new RegressionTestException($"Unexpected margin used {marginUsed}");
}
@@ -135,8 +133,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Unexpected holdings cost {btcUsdtHoldings.HoldingsCost}");
}
if (Math.Abs(btcUsdtHoldings.AbsoluteHoldingsCost * 0.05m - marginUsed) > 1
|| _btcUsdt.BuyingPowerModel.GetMaintenanceMargin(_btcUsdt) != marginUsed)
if (_btcUsdt.BuyingPowerModel.GetMaintenanceMargin(_btcUsdt) != marginUsed)
{
throw new RegressionTestException($"Unexpected margin used {marginUsed}");
}
@@ -226,7 +223,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 60;
public int AlgorithmHistoryDataPoints => 10;
/// <summary>
/// Final status of the algorithm
@@ -244,7 +241,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100285.86"},
{"Start Equity", "100285.85"},
{"End Equity", "100285.26"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
@@ -261,7 +258,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.60"},
{"Estimated Strategy Capacity", "$200000000.00"},
{"Estimated Strategy Capacity", "$100000000.00"},
{"Lowest Capacity Asset", "BTCUSDT 2V3"},
{"Portfolio Turnover", "1.08%"},
{"Drawdown Recovery", "0"},

View File

@@ -135,7 +135,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 60;
public int AlgorithmHistoryDataPoints => 10;
/// <summary>
/// Final status of the algorithm
@@ -153,7 +153,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "117171.12"},
{"Start Equity", "117170.74"},
{"End Equity", "117244.52"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},

View File

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

View File

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

View File

@@ -47,6 +47,11 @@ namespace QuantConnect.Algorithm.CSharp
_aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
UniverseSettings.Resolution = Resolution.Minute;
// Let's disable initial price seeding, the algorithm will wait until both equity
// and options are added an have prices to do the tests, we don't want the equity
// having prices before the options are added.
Settings.SeedInitialPrices = false;
SetStartDate(2014, 06, 04);
// TWX is selected the 4th and 5th and aapl after that.
// If the algo ends on the 6th, TWX subscriptions will not be removed before OnEndOfAlgorithm is called:
@@ -206,7 +211,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Lowest Capacity Asset", "AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "17.64%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "a8605c1f5a9c67f60f1ddc963ec45542"}
{"OrderListHash", "228e694280e05c8aa24246a5866b5a83"}
};
}
}

View File

@@ -0,0 +1,120 @@
/*
* 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.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that securities added via coarse selection get automatically seeded by default
/// </summary>
public class CoarseSelectionsAutomaticSeedRegressionAlgorithm : AutomaticSeedBaseRegressionAlgorithm
{
private readonly Queue<List<Symbol>> _coarseSelections = new(new[] { "AAPL", "GOOG", "AIG", "BAC", "FB", "IBM" }
.Select(x => QuantConnect.Symbol.Create(x, SecurityType.Equity, Market.USA))
.BatchBy(2));
private HashSet<Symbol> _addedSecurities = new();
protected override bool ShouldHaveTradeData => true;
// Daily resolution, only trade data is available
protected override bool ShouldHaveQuoteData => false;
protected override bool ShouldHaveOpenInterestData => false;
public override void Initialize()
{
SetStartDate(2015, 01, 01);
SetEndDate(2015, 03, 01);
SetCash(100000);
Settings.SeedInitialPrices = true;
UniverseSettings.Resolution = Resolution.Daily;
AddUniverse((coarse) =>
{
var selection = _coarseSelections.Dequeue();
_coarseSelections.Enqueue(selection);
return selection;
});
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
base.OnSecuritiesChanged(changes);
foreach (var addedSecurity in changes.AddedSecurities.Where(x => !x.Symbol.IsCanonical()))
{
_addedSecurities.Add(addedSecurity.Symbol);
}
}
public override void OnEndOfAlgorithm()
{
if (!_coarseSelections.SelectMany(x => x).Order().SequenceEqual(_addedSecurities.Order()))
{
throw new RegressionTestException("Not all securities were added");
}
}
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 358;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 390;
/// <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", "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", "-1.066"},
{"Tracking Error", "0.116"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

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

View File

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

View File

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

View File

@@ -27,6 +27,8 @@ namespace QuantConnect.Algorithm.CSharp
{
private List<decimal> _originalLimitPrices = new();
protected virtual bool AsynchronousOrders => false;
protected override IEnumerable<OrderTicket> PlaceComboOrder(List<Leg> legs, int quantity, decimal? limitPrice = null)
{
foreach (var leg in legs)
@@ -35,7 +37,7 @@ namespace QuantConnect.Algorithm.CSharp
leg.OrderPrice *= 2; // Won't fill
}
return ComboLegLimitOrder(legs, quantity);
return ComboLegLimitOrder(legs, quantity, asynchronous: AsynchronousOrders);
}
protected override void UpdateComboOrder(List<OrderTicket> tickets)
@@ -55,6 +57,14 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException($"Limit price expected to be greater that the fill price for each order. Limit prices: {string.Join(",", OrderLegs.Select(x => x.OrderPrice))} Fill prices: {string.Join(",", FillOrderEvents.Select(x => x.FillPrice))}");
}
foreach (var ticket in Transactions.GetOrderTickets())
{
if (ticket.SubmitRequest.Asynchronous != AsynchronousOrders)
{
throw new RegressionTestException("Expected all orders to have the same asynchronous flag as the algorithm.");
}
}
}
/// <summary>
@@ -111,10 +121,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$58000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAT67A|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "30.22%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "ab6171073cd96df46fd9d7bce62f5594"}
{"OrderListHash", "6168ffaa5b9f3c389f5da52e90455889"}
};
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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 to test combo leg limit orders in asynchronous mode
/// </summary>
public class ComboLegLimitOrderAsyncAlgorithm : ComboLegLimitOrderAlgorithm
{
protected override bool AsynchronousOrders => true;
}
}

View File

@@ -46,6 +46,8 @@ namespace QuantConnect.Algorithm.CSharp
}
}
protected virtual bool AsynchronousOrders => false;
protected override IEnumerable<OrderTicket> PlaceComboOrder(List<Leg> legs, int quantity, decimal? limitPrice)
{
_limitPrice = limitPrice.Value;
@@ -56,7 +58,7 @@ namespace QuantConnect.Algorithm.CSharp
legs.ForEach(x => { x.OrderPrice = null; });
// First, let's place a limit order that won't fill so we can update it later
return ComboLimitOrder(legs, _temporaryComboQuantity, _temporaryLimitPrice);
return ComboLimitOrder(legs, _temporaryComboQuantity, _temporaryLimitPrice, asynchronous: AsynchronousOrders);
}
protected override void UpdateComboOrder(List<OrderTicket> tickets)
@@ -121,6 +123,14 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException("Combo order was not liquidated");
}
foreach (var ticket in Transactions.GetOrderTickets().Where(x => x.OrderType == OrderType.ComboLimit))
{
if (ticket.SubmitRequest.Asynchronous != AsynchronousOrders)
{
throw new RegressionTestException("Expected all orders to have the same asynchronous flag as the algorithm.");
}
}
}
/// <summary>
@@ -177,10 +187,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$52.00"},
{"Estimated Strategy Capacity", "$5000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAT67A|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "60.91%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "100742aeee45101940dc60e26fa1aa39"}
{"OrderListHash", "7daf3d43bef2b023ab26517085840c0e"}
};
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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 to test combo limit orders in asynchronous mode
/// </summary>
public class ComboLimitOrderAsyncAlgorithm : ComboLimitOrderAlgorithm
{
protected override bool AsynchronousOrders => true;
}
}

View File

@@ -93,10 +93,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$69000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAT67A|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "30.35%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "615c795b0c450cb8e4c3cba803ebb180"}
{"OrderListHash", "0b9f42bc22c9c7c382bc57a64c99f7e5"}
};
}
}

View File

@@ -58,7 +58,7 @@ namespace QuantConnect.Algorithm.CSharp
var option = AddOption(equity.Symbol, fillForward: true);
_optionSymbol = option.Symbol;
option.SetFilter(u => u.Strikes(-2, +2)
option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2)
.Expiration(0, 180));
}

View File

@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
var option = AddOption(equity.Symbol, fillForward: true);
_optionSymbol = option.Symbol;
option.SetFilter(u => u.Strikes(-2, +2)
option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2)
.Expiration(0, 180));
}
@@ -243,8 +243,7 @@ namespace QuantConnect.Algorithm.CSharp
}
if (orderEvent.Quantity != order.Quantity)
{
throw new RegressionTestException($@"OrderEvent quantity should hold the current order Quantity. Got {orderEvent.Quantity
}, expected {order.Quantity}");
throw new RegressionTestException($@"OrderEvent quantity should hold the current order Quantity. Got {orderEvent.Quantity}, expected {order.Quantity}");
}
if (order is ComboLegLimitOrder && orderEvent.LimitPrice == 0)
{
@@ -303,8 +302,7 @@ namespace QuantConnect.Algorithm.CSharp
{
throw new RegressionTestException(
"There were expected 6 filled market orders, 3 filled combo limit orders and 6 filled combo leg limit orders, " +
$@"but there were {filledComboMarketOrders.Count} filled market orders, {filledComboLimitOrders.Count
} filled combo limit orders and {filledComboLegLimitOrders.Count} filled combo leg limit orders");
$@"but there were {filledComboMarketOrders.Count} filled market orders, {filledComboLimitOrders.Count} filled combo limit orders and {filledComboLegLimitOrders.Count} filled combo leg limit orders");
}
if (openOrders.Count != 0 || openOrderTickets.Count != 0)
@@ -372,10 +370,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$26.00"},
{"Estimated Strategy Capacity", "$2000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAOVVQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZERHAT67A|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "58.98%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "e69460f62d4c165fe4b4a9bff1f48962"}
{"OrderListHash", "bec09c16bbc4d87a4e5122f29dd5a38b"}
};
}
}

View File

@@ -13,7 +13,6 @@
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
@@ -31,6 +30,8 @@ namespace QuantConnect.Algorithm.CSharp
private bool _thereIsAtLeastOneTradeBar;
private bool _thereIsAtLeastOneQuoteBar;
private int _consolidationCount;
public override void Initialize()
{
SetStartDate(2013, 10, 06);
@@ -56,6 +57,12 @@ namespace QuantConnect.Algorithm.CSharp
public void OnQuoteTickMaxCount(QuoteBar quoteBar)
{
_thereIsAtLeastOneQuoteBar = true;
// Let's shortcut to reduce regression test duration: algorithms using tick data are too long
if (++_consolidationCount >= 1000)
{
Quit();
}
}
public void OnQuoteTick(Tick tick)
@@ -112,7 +119,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 2857175;
public long DataPoints => 12190;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
SetEndDate(2020, 01, 20);
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
var symbol = FuturesChain(SP500).First();
var symbol = FuturesChain(SP500).OrderBy(x => x.Symbol.ID.Date).First();
_future = AddFutureContract(symbol);
var tradableDatesCount = QuantConnect.Time.EachTradeableDayInTimeZone(_future.Exchange.Hours,

View File

@@ -209,6 +209,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}

View File

@@ -0,0 +1,143 @@
/*
* 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.Data;
using QuantConnect.Interfaces;
using QuantConnect.Data.Market;
using System.Collections.Generic;
using QuantConnect.Data.Consolidators;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm show casing and asserting the behavior of creating a consolidator specifying the start time
/// </summary>
public class ConsolidatorStartTimeRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private readonly Queue<TimeSpan> _expectedConsolidationTime = new([
new TimeSpan(9, 30, 0),
new TimeSpan(10, 30, 0),
new TimeSpan(11, 30, 0),
new TimeSpan(12, 30, 0),
new TimeSpan(13, 30, 0),
new TimeSpan(14, 30, 0)
]);
private TradeBarConsolidator consolidator;
/// <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, 04);
SetEndDate(2013, 10, 04);
AddEquity("SPY", Resolution.Minute);
consolidator = new TradeBarConsolidator(TimeSpan.FromHours(1), startTime: new TimeSpan(9, 30, 0));
consolidator.DataConsolidated += BarHandler;
SubscriptionManager.AddConsolidator("SPY", consolidator);
}
private void BarHandler(object _, TradeBar bar)
{
if (Time != bar.EndTime)
{
throw new RegressionTestException($"Unexpected consolidation time {bar.Time} != {Time}!");
}
var expected = _expectedConsolidationTime.Dequeue();
if (bar.Time.TimeOfDay != expected)
{
throw new RegressionTestException($"Unexpected consolidation time {bar.Time.TimeOfDay} != {expected}!");
}
if (bar.Period != TimeSpan.FromHours(1))
{
throw new RegressionTestException($"Unexpected consolidation period {bar.Period}!");
}
}
public override void OnEndOfAlgorithm()
{
if (_expectedConsolidationTime.Count > 0)
{
throw new RegressionTestException("Unexpected consolidation times!");
}
}
/// <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%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -26,20 +26,20 @@ namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that continuous future universe selection happens right away for all futures.
/// An example case is ES and Milk futures, which have different time zones. ES is in New York and Milk is in Chicago.
/// An example case is ES and HSI futures, which have different time zones. ES is in New York and HSI is in Hong Kong.
/// ES selection would happen first just because of this, but all futures should have a mapped contract right away.
/// </summary>
public class ContinuousFutureImmediateUniverseSelectionRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Future _es;
private Future _milk;
private Future _hsi;
private bool _dataReceived;
private DateTime _startDateUtc;
private DateTime _esSelectionTimeUtc;
private DateTime _milkSelectionTimeUtc;
private DateTime _hsiSelectionTimeUtc;
private bool _securitiesChangedEventReceived;
@@ -57,10 +57,9 @@ namespace QuantConnect.Algorithm.CSharp
contractDepthOffset: 0,
extendedMarketHours: true);
// Milk time zone is Chicago, so market open will be after ES
_milk = AddFuture(Futures.Dairy.ClassIIIMilk,
_hsi = AddFuture(Futures.Indices.HangSeng,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.OpenInterestAnnual,
dataMappingMode: DataMappingMode.FirstDayMonth,
contractDepthOffset: 0,
extendedMarketHours: true);
@@ -75,25 +74,22 @@ namespace QuantConnect.Algorithm.CSharp
throw new RegressionTestException($"Expected ES universe selection to happen on algorithm start ({_startDateUtc}), " +
$"but happened on {_esSelectionTimeUtc}");
}
}
return universe;
});
_milk.SetFilter(universe =>
_hsi.SetFilter(universe =>
{
if (_milkSelectionTimeUtc == DateTime.MinValue)
if (_hsiSelectionTimeUtc == DateTime.MinValue)
{
_milkSelectionTimeUtc = universe.LocalTime.ConvertToUtc(_milk.Exchange.TimeZone);
_hsiSelectionTimeUtc = universe.LocalTime.ConvertToUtc(_hsi.Exchange.TimeZone);
if (_milkSelectionTimeUtc != _startDateUtc)
if (_hsiSelectionTimeUtc != _startDateUtc)
{
throw new RegressionTestException($"Expected DC universe selection to happen on algorithm start ({_startDateUtc}), " +
$"but happened on {_milkSelectionTimeUtc}");
throw new RegressionTestException($"Expected HSI universe selection to happen on algorithm start ({_startDateUtc}), " +
$"but happened on {_hsiSelectionTimeUtc}");
}
}
return universe;
});
}
@@ -107,14 +103,14 @@ namespace QuantConnect.Algorithm.CSharp
throw new RegressionTestException("ES mapped contract is null");
}
// This is what we actually want to assert: even though Milk future time zone is 1 hour behind,
// This is what we actually want to assert: even though Hong Kong future time zone is different,
// we should have a mapped contract right away.
if (_milk.Mapped == null)
if (_hsi.Mapped == null)
{
throw new RegressionTestException("DC mapped contract is null");
throw new RegressionTestException("HSI mapped contract is null");
}
Log($"{slice.Time} :: ES Mapped Contract: {_es.Mapped}. DC Mapped Contract: {_milk.Mapped}");
Log($"{slice.Time} :: ES Mapped Contract: {_es.Mapped}. HSI Mapped Contract: {_hsi.Mapped}");
}
public override void OnSecuritiesChanged(SecurityChanges changes)
@@ -134,9 +130,9 @@ namespace QuantConnect.Algorithm.CSharp
throw new RegressionTestException("ES universe selection time was not set");
}
if (_milkSelectionTimeUtc == DateTime.MinValue)
if (_hsiSelectionTimeUtc == DateTime.MinValue)
{
throw new RegressionTestException("DC universe selection time was not set");
throw new RegressionTestException("HSI universe selection time was not set");
}
if (changes.AddedSecurities.Count == 0 || changes.RemovedSecurities.Count != 0)
@@ -150,9 +146,9 @@ namespace QuantConnect.Algorithm.CSharp
throw new RegressionTestException($"Expected to find a multiple futures for ES");
}
if (!changes.AddedSecurities.Any(x => !x.Symbol.IsCanonical() && x.Symbol.Canonical == _milk.Symbol))
if (!changes.AddedSecurities.Any(x => !x.Symbol.IsCanonical() && x.Symbol.Canonical == _hsi.Symbol))
{
throw new RegressionTestException($"Expected to find a multiple futures for DC");
throw new RegressionTestException($"Expected to find a multiple futures for HSI");
}
}
}
@@ -184,7 +180,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 445961;
public long DataPoints => 129796;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -45,17 +45,23 @@ namespace QuantConnect.Algorithm.CSharp
protected abstract Offset ExchangeToDataTimeZoneOffset { get; }
protected virtual bool SeedIntialPrices { get; }
private DateTimeZone DataTimeZone => TimeZones.Utc;
private DateTimeZone ExchangeTimeZone => DateTimeZone.ForOffset(ExchangeToDataTimeZoneOffset);
private bool RolloverHappened => _rolloverTime != DateTime.MinValue;
private BaseData MappedContractSeededData;
public override void Initialize()
{
SetStartDate(2013, 10, 8);
SetEndDate(2013, 12, 20);
Settings.SeedInitialPrices = SeedIntialPrices;
_originalMhdbEntry = MarketHoursDatabase.GetEntry(Market.CME, Ticker, SecurityType.Future);
var exchangeHours = new SecurityExchangeHours(ExchangeTimeZone,
_originalMhdbEntry.ExchangeHours.Holidays,
@@ -115,6 +121,9 @@ namespace QuantConnect.Algorithm.CSharp
$"Expected {expectedMappingOldSymbol} -> {expectedMappingNewSymbol} " +
$"but was {symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.NewSymbol}");
}
var mappedContract = Securities[_continuousContract.Mapped];
MappedContractSeededData = mappedContract.GetLastData();
}
var mappedFuture = Securities[_continuousContract.Mapped];
@@ -148,7 +157,10 @@ namespace QuantConnect.Algorithm.CSharp
}
else if (mappedFuturePrice != 0 || !RolloverHappened)
{
if (continuousContractPrice != mappedFuturePrice)
var mappedFutureData = mappedFuture.GetLastData();
// We only do this check is default securities seeding is desabled, else the mapped contract will have historical data
if ((!Settings.SeedInitialPrices || !ReferenceEquals(MappedContractSeededData, mappedFutureData)) &&
continuousContractPrice != mappedFuturePrice)
{
var continuousContractLastData = _continuousContract.GetLastData();
throw new RegressionTestException($"[{Time}] -- Prices do not match. " +
@@ -221,7 +233,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public virtual int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm

View File

@@ -34,5 +34,10 @@ namespace QuantConnect.Algorithm.CSharp
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 483;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 0;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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>
/// 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 ContinuousFutureRolloverDailyExchangeTimeZoneAheadOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverDailyExchangeTimeZoneAheadOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 15;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverDailyExchangeTimeZoneBehindOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverDailyExchangeTimeZoneBehindOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 17;
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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>
/// 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 ContinuousFutureRolloverDailyExchangeTimeZoneSameAsDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverDailyExchangeTimeZoneSameAsDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 17;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverHourExchangeTimeZoneAheadOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverHourExchangeTimeZoneAheadOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 65;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverHourExchangeTimeZoneBehindOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverHourExchangeTimeZoneBehindOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 64;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverHourExchangeTimeZoneSameAsDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverHourExchangeTimeZoneSameAsDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 64;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverMinuteExchangeTimeZoneAheadOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverMinuteExchangeTimeZoneAheadOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 1958;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverMinuteExchangeTimeZoneBehindOfDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverMinuteExchangeTimeZoneBehindOfDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 892;
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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>
/// 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 ContinuousFutureRolloverMinuteExchangeTimeZoneSameAsDataWithInitialSeedRegressionAlgorithm
: ContinuousFutureRolloverMinuteExchangeTimeZoneSameAsDataRegressionAlgorithm
{
protected override bool SeedIntialPrices => true;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public override int AlgorithmHistoryDataPoints => 668;
}
}

View File

@@ -138,10 +138,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$4.60"},
{"Estimated Strategy Capacity", "$120000.00"},
{"Lowest Capacity Asset", "GOOCV WBGM92QHIYO6|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV WBGM92QHN8ZQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "32.18%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "c0e25967c528ec4b1281f25a7735ed92"}
{"OrderListHash", "f8b1dfb65e4795a7929e7f3a3edd0205"}
};
}
}

View File

@@ -138,10 +138,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$4.60"},
{"Estimated Strategy Capacity", "$160000.00"},
{"Lowest Capacity Asset", "GOOCV 30AKMEIPOSS1Y|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV 30AKMEIPOX2DI|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "32.12%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "6a09be0b3b0ec11848f3b2c520234332"}
{"OrderListHash", "3f95cba29e9c396bc19c0d47a889dbfb"}
};
}
}

View File

@@ -43,7 +43,7 @@ namespace QuantConnect.Algorithm.CSharp
var option = AddOption(equity.Symbol);
_optionSymbol = option.Symbol;
option.SetFilter(u => u.Strikes(-1, +1).Expiration(0, 30));
option.SetFilter(u => u.StandardsOnly().Strikes(-1, +1).Expiration(0, 30));
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
@@ -70,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
var legs = new List<Leg> { Leg.Create(atmContract.Symbol, -1), Leg.Create(atmContract.Symbol.Underlying, 100) };
var comboPrice = underlyingPrice - optionPrice;
if(comboPrice < 734m)
if (comboPrice < 734m)
{
// just to make sure the price makes sense
throw new RegressionTestException($"Unexpected combo price {comboPrice}");
@@ -147,10 +147,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "0"},
{"Total Fees", "$6.90"},
{"Estimated Strategy Capacity", "$8000.00"},
{"Lowest Capacity Asset", "GOOCV W78ZFMEBBB2E|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV W78ZFMEBFLDY|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "227.27%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "94a9ae926f68c23d06d32af2b5a25fea"}
{"OrderListHash", "e36c11e174486d80060855efed57a2a9"}
};
}
}

View File

@@ -63,7 +63,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.15"},
{"Estimated Strategy Capacity", "$3400000000.00"},
{"Estimated Strategy Capacity", "$4300000000.00"},
{"Lowest Capacity Asset", "ADAUSDT 18R"},
{"Portfolio Turnover", "0.02%"},
{"Drawdown Recovery", "0"},

View File

@@ -167,7 +167,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.15"},
{"Estimated Strategy Capacity", "$330000000.00"},
{"Estimated Strategy Capacity", "$410000000.00"},
{"Lowest Capacity Asset", "ADAUSDT 18R"},
{"Portfolio Turnover", "0.02%"},
{"Drawdown Recovery", "0"},

View File

@@ -0,0 +1,170 @@
/*
* 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.Brokerages;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Securities.CryptoFuture;
using System.Collections.Generic;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that margin used and margin remaining update correctly when
/// changing leverage on a crypto future
/// </summary>
public class CryptoFutureLeverageBasedMarginRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private CryptoFuture _cryptoFuture;
public override void Initialize()
{
SetStartDate(2022, 12, 13);
SetEndDate(2022, 12, 13);
SetTimeZone(TimeZones.Utc);
SetAccountCurrency("USDT");
SetCash(200);
SetBrokerageModel(BrokerageName.BinanceFutures, AccountType.Margin);
_cryptoFuture = AddCryptoFuture("ADAUSDT");
_cryptoFuture.SetLeverage(10);
}
public override void OnData(Slice slice)
{
if (_cryptoFuture.Price == 0)
{
return;
}
if (!Portfolio.Invested)
{
SetHoldings(_cryptoFuture.Symbol, 10); // Buy all we can with our margin (leverage is 10)
var marginUsed = Portfolio.TotalMarginUsed;
var marginRemaining = Portfolio.MarginRemaining;
if (marginRemaining > 0)
{
throw new RegressionTestException($"Expected no margin remaining after buying with full leverage. " +
$"Actual margin remaining is {marginRemaining}");
}
_cryptoFuture.SetLeverage(20);
var newMarginUsed = Portfolio.TotalMarginUsed;
var newMarginRemaining = Portfolio.MarginRemaining;
if (newMarginUsed >= marginUsed)
{
throw new RegressionTestException($"Expected margin used to decrease after increasing leverage. " +
$"Previous margin used: {marginUsed}, new margin used: {newMarginUsed}");
}
if (newMarginRemaining <= 0 || newMarginRemaining <= marginRemaining)
{
throw new RegressionTestException($"Expected margin remaining to increase after increasing leverage. " +
$"Previous margin remaining: {marginRemaining}, new margin remaining: {newMarginRemaining}");
}
var holdingsQuantity = _cryptoFuture.Holdings.AbsoluteQuantity;
SetHoldings(_cryptoFuture.Symbol, 20); // Buy all we can with our margin (new leverage is 20)
var newHoldingsQuantity = _cryptoFuture.Holdings.AbsoluteQuantity;
if (newHoldingsQuantity <= holdingsQuantity)
{
throw new RegressionTestException($"Expected holdings quantity to increase after increasing leverage and buying more. " +
$"Previous holdings quantity: {holdingsQuantity}, new holdings quantity: {newHoldingsQuantity}");
}
newMarginRemaining = Portfolio.MarginRemaining;
if (marginRemaining > 0)
{
throw new RegressionTestException($"Expected no margin remaining after buying with full leverage. " +
$"Actual margin remaining is {newMarginRemaining}");
}
// We are done testing, exit the algorithm
Quit();
}
}
/// <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 long DataPoints => 4;
/// <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", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "200"},
{"End Equity", "195.58"},
{"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", "₮1.57"},
{"Estimated Strategy Capacity", "₮0"},
{"Lowest Capacity Asset", "ADAUSDT 18R"},
{"Portfolio Turnover", "2009.51%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "f92ad762f77fbf4ee13b1e89a78cb1eb"}
};
}
}

View File

@@ -0,0 +1,232 @@
/*
* 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.Globalization;
using Newtonsoft.Json;
using QuantConnect.Data;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression test to assert that custom data is seeded by default
/// </summary>
public class CustomDataAutomaticSeedRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
public override void Initialize()
{
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 10);
SetCash(100000);
Settings.SeedInitialPrices = true;
var resolution = Resolution.Daily;
var customData = AddData<Bitcoin>("BTC", resolution);
if (!customData.HasData || customData.Price == 0)
{
throw new RegressionTestException("Custom data was not seeded with data on addition");
}
var seedData = customData.GetLastData();
if (seedData is not Bitcoin)
{
throw new RegressionTestException("Custom data was not seeded with correct data type");
}
}
/// <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 long DataPoints => 50;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 5;
/// <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", "-9.259"},
{"Tracking Error", "0.073"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
/// <summary>
/// Custom Data Type: Bitcoin data from Quandl - http://www.quandl.com/help/api-for-bitcoin-data
/// </summary>
public class Bitcoin : BaseData
{
[JsonProperty("timestamp")]
public int Timestamp { get; set; }
[JsonProperty("open")]
public decimal Open { get; set; }
[JsonProperty("high")]
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")]
public decimal Bid { get; set; }
[JsonProperty("ask")]
public decimal Ask { get; set; }
[JsonProperty("vwap")]
public decimal WeightedPrice { get; set; }
[JsonProperty("volume")]
public decimal VolumeBTC { get; set; }
/// <summary>
/// The end time of this data. Some data covers spans (trade bars)
/// and as such we want to know the entire time span covered
/// </summary>
/// <remarks>
/// This property is overriden to allow different values for Time and EndTime
/// if they are set in the Reader. In the base implementation EndTime equals Time
/// </remarks>
public override DateTime EndTime { get; set; }
/// <summary>
/// 1. DEFAULT CONSTRUCTOR: Custom data types need a default constructor.
/// We search for a default constructor so please provide one here. It won't be used for data, just to generate the "Factory".
/// </summary>
public Bitcoin()
{
Symbol = "BTC";
}
/// <summary>
/// 2. RETURN THE STRING URL SOURCE LOCATION FOR YOUR DATA:
/// This is a powerful and dynamic select source file method. If you have a large dataset, 10+mb we recommend you break it into smaller files. E.g. One zip per year.
/// We can accept raw text or ZIP files. We read the file extension to determine if it is a zip file.
/// </summary>
/// <param name="config">Configuration object</param>
/// <param name="date">Date of this source file</param>
/// <param name="isLiveMode">true if we're in live mode, false for backtesting mode</param>
/// <returns>String URL of source file.</returns>
public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
{
if (isLiveMode)
{
return new SubscriptionDataSource("https://www.bitstamp.net/api/ticker/", SubscriptionTransportMedium.Rest);
}
//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/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=qAWKpUfmSVFnU3bRQwKy")
{
Sort = true
};
}
/// <summary>
/// 3. READER METHOD: Read 1 line from data source and convert it into Object.
/// Each line of the CSV File is presented in here. The backend downloads your file, loads it into memory and then line by line
/// feeds it into your algorithm
/// </summary>
/// <param name="line">string line from the data source file submitted above</param>
/// <param name="config">Subscription data, symbol name, data type</param>
/// <param name="date">Current date we're requesting. This allows you to break up the data source into daily files.</param>
/// <param name="isLiveMode">true if we're in live mode, false for backtesting mode</param>
/// <returns>New Bitcoin Object which extends BaseData.</returns>
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
{
var coin = new Bitcoin();
if (isLiveMode)
{
//Example Line Format:
//{"high": "441.00", "last": "421.86", "timestamp": "1411606877", "bid": "421.96", "vwap": "428.58", "volume": "14120.40683975", "low": "418.83", "ask": "421.99"}
try
{
coin = JsonConvert.DeserializeObject<Bitcoin>(line);
coin.EndTime = DateTime.UtcNow.ConvertFromUtc(config.ExchangeTimeZone);
coin.Value = coin.Close;
}
catch { /* Do nothing, possible error in json decoding */ }
return coin;
}
//Example Line Format:
// 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[1], CultureInfo.InvariantCulture);
coin.EndTime = coin.Time.AddDays(1);
coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
coin.Low = Convert.ToDecimal(data[3], 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 */ }
return coin;
}
}
}
}

View File

@@ -198,7 +198,6 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Bitcoin()
{
Symbol = "BTC";
}
/// <summary>
@@ -237,7 +236,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <returns>New Bitcoin Object which extends BaseData.</returns>
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
{
var coin = new Bitcoin();
var coin = new Bitcoin() { Symbol = config.Symbol };
if (isLiveMode)
{
//Example Line Format:

View File

@@ -0,0 +1,121 @@
/*
* 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;
using QuantConnect.Securities;
using static QuantConnect.Algorithm.CSharp.CustomDataRegressionAlgorithm;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm used to verify that GetData<T> correctly retrieves
/// the latest custom data stored in the security cache.
/// </summary>
public class CustomDataSecurityCacheGetDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
public override void Initialize()
{
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 10);
AddData<Bitcoin>("BTC", Resolution.Daily);
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(security => seeder.SeedSecurity(security));
}
public override void OnData(Slice slice)
{
var bitcoin = Securities["BTC"].Cache.GetData<Bitcoin>();
if (bitcoin == null)
{
throw new RegressionTestException("Expected Bitcoin data in cache, but none was found");
}
if (bitcoin.Value == 0)
{
throw new RegressionTestException("Expected Bitcoin value to be non-zero");
}
var bitcoinFromSlice = slice.Get<Bitcoin>().Values.FirstOrDefault();
if (bitcoinFromSlice != bitcoin)
{
throw new RegressionTestException("Expected cached Bitcoin to match the one from Slice");
}
}
/// <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 => 50;
/// <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", "-9.259"},
{"Tracking Error", "0.073"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

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

View File

@@ -83,10 +83,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-0.115"},
{"Total Fees", "$2.00"},
{"Estimated Strategy Capacity", "$4800000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WLZZA|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "26.72%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "fb2bef182af109f6441ae739d826f39f"}
{"OrderListHash", "20f33e143b62ee896aa56f85dd2aa2e8"}
};
}
}

View File

@@ -91,10 +91,10 @@ namespace QuantConnect.Algorithm.CSharp
{"Treynor Ratio", "-3.295"},
{"Total Fees", "$16.00"},
{"Estimated Strategy Capacity", "$87000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WLZZA|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "10.93%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "8133cb99a1a9f9e9335bc98def3cc624"}
{"OrderListHash", "19b8f2a8081c3cfa8f6bc02b5d045765"}
};
}
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*

View File

@@ -0,0 +1,128 @@
/*
* 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.Data;
using QuantConnect.Interfaces;
using System.Collections.Generic;
using QuantConnect.Securities.CryptoFuture;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting DYDX Crypto Future support
/// </summary>
public class DYDXCryptoFuturesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private CryptoFuture _cryptoFuture;
/// <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(2026, 1, 1);
SetEndDate(2026, 1, 1);
SetBrokerageModel(Brokerages.BrokerageName.DYDX, AccountType.Margin);
_cryptoFuture = AddCryptoFuture("BTCUSD");
}
/// <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 (!Portfolio.Invested)
{
Buy("BTCUSD", 1);
}
else
{
if (Math.Abs(Portfolio.TotalFees - Portfolio.TotalHoldingsValue * 0.0005m) > 1
|| Math.Abs(Portfolio.TotalFees - _cryptoFuture.Price * 0.0005m) > 1)
{
throw new RegressionTestException("Unexpected fees value!");
}
if (Math.Abs(Portfolio.TotalHoldingsValue - _cryptoFuture.Price) > 1)
{
throw new RegressionTestException("Unexpected holdings value!");
}
Quit();
}
}
/// <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 long DataPoints => 5;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 15;
/// <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"},
{"End Equity", "99929.57"},
{"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", "$43.71"},
{"Estimated Strategy Capacity", "$33000.00"},
{"Lowest Capacity Asset", "BTCUSD 38Z"},
{"Portfolio Turnover", "87.48%"},
{"Drawdown Recovery", "0"},
{"OrderListHash", "637a937cda83ce88d29a3b279832401d"}
};
}
}

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