Compare commits

...

284 Commits
16632 ... 17150

Author SHA1 Message Date
Martin-Molinero
3826b1d86a Update readme.md 2025-06-18 18:32:13 -03:00
JosueNina
b991dc8ada Add PyObject overload constructor to FilteredIdentity (#8840)
* Add PyObject overload constructor to FilteredIdentity for Python filter support

* Solve review comments
2025-06-18 18:31:22 -03:00
JosueNina
5729be4661 Make RollingWindow compatible with any data type (#8836)
* Make RollingWindow compatible with any data type

* Add generic RW<T> method

* Add RollingWindow wrapper class for PyObject

* Solve review comments

* Resolve review comments
2025-06-18 18:29:00 -03:00
Jhonathan Abreu
4dcd41b690 Wire and handle brokerage errors when used as DQH only (#8832)
* Wire and handle brokerage errors when used as DQH only

* Minor fix

* Minor fixes
2025-06-17 12:11:54 -04:00
Jhonathan Abreu
4602a9d222 Fill-forward last warmup data point to normal data feed (#8831)
* Fill-forward last warmup data point to normal data feed

* Minor clean up

* Minor changes and unit tests

* Address peer review

* Minor changes

* Improve unit tests
2025-06-17 12:07:58 -04:00
Martin-Molinero
e2de840aed Avoid empty public constructor from being removed (#8837) 2025-06-17 13:04:30 -03:00
Martin-Molinero
93d58d5cdf Minor fixes for quantbook (#8835) 2025-06-16 18:59:58 -03:00
Martin-Molinero
d611105413 Split conflicting python library tests run (#8830) 2025-06-13 17:14:55 -03:00
Roman Yavnikov
3f53f6ec77 refactor: change access modifier of GetFutureContractMonthNoRulesApplied (#8829) 2025-06-13 14:51:24 -03:00
Martin-Molinero
dbcb464268 Update PythonPackagesTests.cs 2025-06-13 13:39:57 -03:00
Martin-Molinero
26a00a2adb Update readme.md 2025-06-13 13:36:52 -03:00
Martin-Molinero
a75e132bed Foundation update (#8827) 2025-06-13 12:35:45 -03:00
Martin-Molinero
890fcd114e Fix Symbol EOD internal SecurityChanges handling (#8824)
- Fix Symbol EOD internal SecurityChanges handling. Adding unit test and
  regression test
2025-06-12 19:18:15 -03:00
arthion
f3d734c4fe Implements new indicator - KST - Know Sure Thing (#8819)
* feat: Implements Know Sure Thing

* Removed extra space

* Removed identity variables and returned value directly
2025-06-12 19:17:47 -03:00
JosueNina
dbdf014a4c Add BNFCR as stable coin without pair (#8821)
* Add BNFCR as stable coin without pair

* Add unit test

* Skip conversion in PerformCashSync when ConversionRate is zero

* Solve review comments
2025-06-12 19:17:32 -03:00
Martin-Molinero
0d70244d7b Update readme.md 2025-06-10 19:34:01 -03:00
Martin-Molinero
e72362b14d Update readme.md 2025-06-10 19:21:21 -03:00
Martin-Molinero
52365ed766 Update readme.md 2025-06-10 19:00:52 -03:00
Martin-Molinero
592118b323 Fix live warmup price scaling (#8822)
- Fix missing live warmup price scaling. Adding unit test
2025-06-10 13:30:43 -03:00
Martin-Molinero
cd01b769a6 Fix api ObjectStorageUsed size (#8823) 2025-06-10 13:14:14 -03:00
Jhonathan Abreu
9e349259b2 Conditional timeout for live fill forward (#8817)
* Wait for data before emitting fill forwarded bars only on market open/close in live trading

* Minor fixes and more unit tests
2025-06-10 10:58:56 -04:00
Matt Fair
b1ce8f0045 feature: Klinger Volume Oscillator (#8811)
* implements Klinger Volume Oscillator

* preserve newest data file

* improve class summary

* address PR comments, add signal line, use RollingWindow to persist data, refactor code to make easier to follow

* add helper method KVO in in QCAlgorithm.Indicators.cs, add Signal test, fix IsReady and WarmUpPeriod

* default signal period for KVO, refactor and improve ComputeNextValue, simplified code

* update comment

* update comment
2025-06-06 11:03:57 -03:00
Jhonathan Abreu
9e31261116 Add open interest data to future chains contracts (#8805)
* Add open interest data to future chains contracts

Even though futures chains and contracts are not created from internal subscriptions data (like OI subscriptions or continuous futures contracts subscriptions), we still want to add OI data to already created contracts given that OI subscriptions are always internal but trade an quote ones are not.

* Minor changes
2025-06-06 10:35:45 -03:00
Jhonathan Abreu
e70d783c93 Support stop limit orders for crypto futures in Binance (#8792)
Co-authored-by: Martin-Molinero <martin@quantconnect.com>
2025-06-05 09:24:06 -03:00
Jhonathan Abreu
11ddf6abc2 Add support for stop limit orders in Bitfinex (#8810)
* Add support for stop limit orders in Bitfinex

* Add place order exception message to invalid order tag

* Minor change

* Minor change
2025-06-05 09:22:32 -03:00
Alexandre Catarino
515606dc35 Review Collective2 Implemention (#8773)
* Review Collective2 Implemention

According to `SetDesiredPositions` [API](https://api-docs.collective2.com/apis/general/swagger/strategies/c2_api_strategies/setdesiredpositions_post#strategies/c2_api_strategies/setdesiredpositions_post/t=request&path=positions), the quantity must be non-zero. To close a position, send stop sending a position.

The current for all assets, except FOREX, is the quote currency.

FOREX:
- Observe the [C2 minilot](https://support.collective2.com/hc/en-us/articles/360038042774-Forex-minilots)
- Currency is always USD

Unit tests:
- Increase the initial cash to accomodate FOREX minilot
- Additional message for minilot warning
- Fix currencies

* Addresses Peer Review
2025-06-05 09:21:57 -03:00
Jhonathan Abreu
61376cd5cc Support Equity Limit orders outside regular hours in Tradier (#8807)
* Support Equity Limit orders outside regular hours in Tradier

* Address peer review

* Minor change

* Minor change
2025-06-04 13:14:56 -04:00
Jhonathan Abreu
1fc0c37388 Support limit orders outside regular hours in Alpaca (#8800)
* Add support for Limit orders outside regular hours in Alpaca

* Minor change
2025-06-04 09:11:22 -04:00
Jhonathan Abreu
bfa0e26605 Add PostOnly TradeStation order property (#8787)
* Add PostOnly TradeStation order property

* Minor fix
2025-06-04 09:10:32 -04:00
Jhonathan Abreu
85bcb9ef43 Add support for trailing stop orders in TradeStation (#8780) 2025-06-04 09:10:28 -04:00
Jhonathan Abreu
abaa73ebce Add new IgnoreUnknownAssetHoldings algorithm setting (#8764)
* Add new IgnoreUnknownAssetTypes algorithm setting

* Wire brokerage message handler before algorithm initialization

* Ignore unknown assets by default

* Trigger Build

* Rename IgnoreUnknownAssetTypes to IgnoreUnknownAssetHoldings

* Minor change

* Minor change
2025-06-04 09:07:57 -04:00
Roman Yavnikov
d9bdbab810 Feature: Implementation Tastytrade Brokerage (#8809)
* feat: Tastytrade brokerage helper classes and configs

* refactor: TastytradeFeeModel
test:feat: TastytradeFeeModel
refactor: curl brackets in namespaces to keep project style
2025-06-04 10:03:46 -03:00
JosueNina
ba931a26c3 Restrict supported order types in Bitfinex brokerage (#8776)
* Limit supported order types to Market, Limit, and StopMarket in Bitfinex brokerage

* Update brokerage models

* Fix broken unit test

* Solve review comments

* Convert regression algorithm into a unit test

* Resolve review comments
2025-06-03 17:17:31 -03:00
Alexandre Catarino
1d6a5472b0 Updates Python Example get_value to get (#8806)
`get` is the Pythonist way to access a dictionary.
Also, `not x` replaces `is None`, since the former translates into is None or empty.
2025-06-03 17:03:12 -03:00
Derek Melchin
c9c892510a Fix comment (#8788) 2025-06-03 17:00:03 -03:00
JosueNina
666f810dd9 Refactor AverageTrueRange to use TrueRange implementation (#8785)
* Refactor AverageTrueRange

* Solve review comments
2025-06-03 15:57:26 -04:00
JosueNina
4363801ec9 Add alias for AccumulationDistributionOscillator(ChaikinOscillator) (#8781)
* Add alias to AccumulationDistributionOscillator(ChaikinOscillator)

* Add unit tests for ChaikinOscillator
2025-06-03 15:49:29 -04:00
JosueNina
29ab1d6acd Initial solution (#8772) 2025-06-03 14:35:59 -04:00
JosueNina
5d732a877a Add support for negative indexing in RollingWindow (#8770)
* Add support for negative indexing in RollingWindow

* Solve review comments

* Resolve comments review
2025-06-03 14:33:08 -04:00
JosueNina
2edac83d4f Ensure Indicator.Current retains the Symbol from the latest input data (#8767) 2025-06-03 15:26:42 -03:00
JosueNina
791a40596a Update SPDB with CoinBase, ByBit, Bitfinex, Kraken, Binance and BinanceUS (#8765)
* Update SPDB with Bybit

* Update SPDB with CoinBase

* Update SPDB with Bitfinex

* Update SPDB with Kraken

* Update SPDB with Binance

* Update SPDB with BinanceUS

* Update regression algorithms

* Update SPDB - Binanceus to solve issues with the unit tests
2025-06-03 15:21:59 -03:00
Jhonathan Abreu
54e58c6302 Add 2025 equity and equity options holidays (#8799)
* Add 2025 equity and equity options holidays

* Minor fix
2025-05-27 13:22:28 -04:00
JosueNina
eb8043e7c6 Fix problem with IsSubscriptionValidForConsolidator() method (#8754)
* Fix problem with IsSubscriptionValidForConsolidator() method

* Add regression algorithms using TickQuoteBarConsolidator

* Fix the method IsSubscriptionValidForConsolidator()

* Refactor IsSubscriptionValidForConsolidator method

* Resolve review comments

* Add new regression algo and update unit tests

* Update TickTradeBarConsolidatorWithQuoteTickTypeRegressionAlgorithm.cs

---------

Co-authored-by: Martin-Molinero <martin.molinero1@gmail.com>
2025-05-09 16:42:25 -03:00
Jhonathan Abreu
7dad4deb5a Support DAX EUREX indices (#8761) 2025-05-09 15:11:10 -03:00
Martin-Molinero
88947a96b9 Create SPDB and MHDB on engine constructor (#8760) 2025-05-09 10:54:51 -03:00
JosueNina
9f322e150b Update FutureSymbolGenerator to Use FuturesExpiryFunctions for Accurate Expiry Dates (#8749)
* Initial solution

* Solve review comments

* Fix unit tests

* Resolve comments reviews

* Return a default symbol instead of throwing an exception

* Add unit test
2025-05-09 09:20:55 -03:00
Jhonathan Abreu
201ea1ce74 More Python syntax check improvements (#8758)
* Ignore more mypy errors and fix more python algos syntax

* Minor change
2025-05-08 18:06:18 -04:00
Louis Szeto
d2d1ca5c9e Make Local Backtest Config Customizable (#8746)
* customizable lloocal backtest config

* bug fix

* address review
2025-05-08 11:34:18 -03:00
Jhonathan Abreu
5f27689c53 Improve python syntax check (#8744)
* Ignore some errors in python syntax check.

Fix some algorithms syntax as well.

* Revert some changes

* Minor change

* Minor change

* Minor syntax check fixes

* Ignore more mypy errors

* Minor changes

* Ignore more mypy messages

* Ignore more mypy messages
2025-05-07 19:45:17 -03:00
Martin-Molinero
dec831f361 Minor packet type additions (#8752) 2025-05-06 17:18:13 -03:00
Ricardo Andrés Marino Rojas
7942f7d6dc Fix failing API test (#8747) 2025-05-05 13:34:22 -03:00
JosueNina
359c7a7c8e Improve SecurityExchangeHours exception messages (#8741)
* Improve SecurityExchangeHours exception messages

* Solve comments review
2025-05-02 14:02:05 -03:00
Jhonathan Abreu
053c9a20c4 ExtendedDictionary improvements (#8723)
* Make ExtendedDictionary extend IDictionary

* Revert "Make ExtendedDictionary extend IDictionary"

This reverts commit bbbe9c769be682767cb9e487b904480376b53596.

* Make ExtendedDictionary key a type parameter

* Make SecurityPositionGroupModel an ExtendedDictionary

* Add unit tests

* Minor change

* Add more unit tests and other minor changes

* Add Count and ContainsKey to BaseChain

* Update pythonnet version to 2.0.43

* Update some python regression algorithms

* Minor regression algorithms fix

* Make CashBook and ExtendedDictionary

* Minor changes

* Minor changes

* Update pythonnet version to 2.0.44
2025-05-02 11:02:06 -04:00
Roman Yavnikov
4e13189787 Feature: support MOO in CharlesSchwabBrokerageModel (#8737)
* feat: support MOO in CharlesSchwabBrokerageModel

* feat: validate IsMarketOpen with MOO order type in PreOrderChecks

* test:feat: Validate MOO in various Market hours time

* fix: Algo with new MOO time validation

* test:fix: set DateTime of Algo explicitly in OrderQuantityConversionTest
2025-05-02 16:15:17 +03:00
Ricardo Andrés Marino Rojas
25c4a879f6 Add failure API backtest unit tests (#8703)
* First attempt

* Improve unit test

* Add suggestions

* Nit changes

* Address requested changes

* Fix failing unit tests

* First attempt to fix API tests

* Fix command

* Address suggestions

* Address minor suggestions
2025-05-01 15:48:46 -03:00
JosueNina
db3f567ebf Implement the missing python constructors for selection models (#8738)
* Initial solution

* Solve comments reviews

* Resolve comments reviews
2025-05-01 15:23:11 -03:00
Roman Yavnikov
abf0e70a20 Feature: support OutsideRegularTradingHours by TradeStation (#8734)
* wip: show work

* refactor: TradeStationBrokerageModel of using OutsideRegularTradingHours
test:feat: OutsideRegularTradingHours

* remove: comboLimit OrderType in IsLimitOrder(...)

* fix: regression algo which test unsupported OrderType in extend market hours

* fix: condition with supportsOutsideTradingHours in CanSubmitOrder

* refactor: regression test with OutsideRegularMarketHours TradeStation

* refactor: TradeStationBrokerageTradeWithOutsideRegularMarketHoursParameter

---------

Co-authored-by: Henry Ennis-Thomas <henry@henryetdev.com>
2025-04-29 18:52:41 -03:00
Jhonathan Abreu
33d850ae34 Add support for DAX EUREX futures (#8732)
* Add support for DAX EUREX futures

* Add margin files

* Minor change

* Minor changes
2025-04-29 16:06:50 -04:00
JosueNina
07f6cd494d Create DollarVolumeRenkoConsolidator (#8729)
* Initial solution

* Add unit test

* Solve review comments
2025-04-29 16:04:02 -04:00
Martin-Molinero
77a240ff25 Minor tweak (#8731) 2025-04-29 11:04:55 -03:00
JosueNina
e5a81ef285 Implement python version of OptionAssignmentRegressionAlgorithm (#8728)
* Implement python version of OptionAssignmentRegressionAlgorithm

* Solve comments review
2025-04-28 16:00:09 -03:00
Roman Yavnikov
818108b944 Fix: UnsettledCash Handling in Lean and Refactor PerformCashSync from Brokerage (#8726)
* test:feat: Assert Lean UnsettledCash and Brokerage.PerformCashSync
test:feat: new PaperBrokerage with manual cash balance

* test:refactor: calculation of Margin

* feat: change DefaultSettlementTime

* test:fix: use right brokerage settlement cash to balance

* test:refactor: use specific time when SettlementModel.Scan happens
2025-04-28 13:35:47 -03:00
JosueNina
cc38a6410f Add python SecurityCache.GetData method (#8724)
* Initial solution

* Fix regression algorithms
2025-04-28 11:46:31 -03:00
JosueNina
55b21cd714 Fix bug in ClassicRenkoConsolidator (#8713)
* Initial solution: Add an extra conditional in SubscriptionManager and add regression algorithms

* Solve comments review

* Add unit test

* Refactor unit tests in SubscriptionManagerTests

* Resolve comments review
2025-04-24 12:55:23 -04:00
Roman Yavnikov
25618ae5bc feat: generic BrokerageOrderIdChangedEvent in BrokerageTests (#8719) 2025-04-23 16:44:59 -03:00
Martin-Molinero
515408b167 Fix sytanx check on algorithms importing algorithms (#8720) 2025-04-23 16:39:23 -03:00
Jhonathan Abreu
0df082cc68 Add StubsAvoidImplicitsAttribute to avoid generating implicit types in stubs (#8718)
This allows the stubs generator to know when to not generate Union types for parameters that can accept multiple types, like Symbol | str | BaseContract
2025-04-23 14:22:14 -03:00
Jhonathan Abreu
cf8c5b854a Python algorithms typing cleanup [part 1] (#8716)
* Cleanup algorithms python typing

* Minor tweaks

* Improve indicator extensions

---------

Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
2025-04-23 14:20:38 -03:00
Martin-Molinero
e4ff27a738 Minor improvements for syntax check test script (#8714) 2025-04-22 18:14:48 -03:00
Martin-Molinero
a087d7e766 Update run_syntax_check.py
Sort algorithms before syntax check
2025-04-22 16:57:28 -03:00
Martin-Molinero
065dbf3959 Normalize algorithm trading option strategy return type (#8712) 2025-04-22 12:01:08 -03:00
Martin-Molinero
1be7c9e141 Minor python syntax fixes (#8711) 2025-04-22 10:54:44 -03:00
Jhonathan Abreu
1ad4afa54e Add StubsIgnore attribute to missing methods (#8710) 2025-04-22 09:51:44 -04:00
Jhonathan Abreu
5845f3cd81 Use StubsIgnore attribute in some methods (#8708)
IBaseData.Reader
IBaseData.GetSource
IndicatorBase.Update
IAlgorithm.OnEndOfDay
2025-04-21 16:27:37 -04:00
Martin-Molinero
d60b3323c3 Minor python syntax fixes (#8709) 2025-04-21 17:23:36 -03:00
Martin-Molinero
4584feb7da Merge PythonSlice into Slice (#8707)
- To simplify stub generation, merge PythonSlice into Slice, following
  existing pattern too, see QCAlgorithm.Python.cs
- Minor sintax fixes in example python algorithms
2025-04-21 13:37:33 -03:00
Martin-Molinero
b81bcf086e Minor syntax fixes for python algorithms (#8705) 2025-04-21 10:06:47 -03:00
Martin-Molinero
e34a7e0bfa Update readme.md 2025-04-17 16:08:32 -03:00
JosueNina
e8cdb23cc0 Fix MarginCalls outside of regular market hours (#8696)
* Initial Solution

* Add regression algorithm

* Solve review comments

* Resolve review comments

* Add HasTimeProvider property and prevent overwriting existing time provider

* Resolve review comments

* Filter marginCall orders

* Update EquityMarginCall Algorithm

* Add header to the regression algorithm
2025-04-17 16:00:47 -03:00
Martin-Molinero
ea7d73d95d Add Missing Good Friday (#8702) 2025-04-17 10:42:45 -03:00
Henry Ennis-Thomas
7daa0929fa Update devcontainer.json for improved developer experience (#8697)
Co-authored-by: Henry Ennis-Thomas <henry@henryetdev.com>
2025-04-16 10:04:12 -03:00
Martin-Molinero
a55c387512 Update Packet.cs 2025-04-15 19:49:35 -03:00
Martin-Molinero
c130bb2de4 Dispose of python algorithm instance (#8695) 2025-04-15 11:33:33 -03:00
Roman Yavnikov
a1302d2bcd fix: missed orderProps when create MerketOnOpen (#8693) 2025-04-14 09:44:27 -03:00
Louis Szeto
020cf013df Fix bug/syntax in python examples (#8658)
* CustomDataRegressionAlgorithm

* DescendingCustomDataObjectStoreRegressionAlgorithm

* CustomDataPropertiesRegressionAlgorithm

* DateTime -> should be datetime

* KerasNeuralNetworkAlgorithm

* OptionIndicatorsMirrorContractsRegressionAlgorithm

* BybitCustomDataCryptoRegressionAlgorithm

* DropboxBaseDataUniverseSelectionAlgorithm

* UserDefinedUniverseAlgorithm

* CompleteOrderTagUpdateAlgorithm

* BasicTemplateOptionEquityStrategyAlgorithm hint

* ETFConstituentUniverseFrameworkRegressionAlgorithm

* FutureStopMarketOrderOnExtendedHoursRegressionAlgorithm

* SecurityDynamicPropertyPythonClassAlgorithm

* hint

* hinting

* CallbackCommandRegressionAlgorithm

* CustomWarmUpPeriodIndicatorAlgorithm

* CrunchDAOSignalExportDemonstrationAlgorithm

* ExpiryHelperAlphaModelFrameworkAlgorithm

* ClassicRenkoConsolidatorAlgorithm

* SmaCrossUniverseSelectionAlgorithm

* PEP8 Fix: Assigning to a Method

* SliceGetByTypeRegressionAlgorithm

* MarketOnCloseOrderBufferExtendedMarketHoursRegressionAlgorithm

* MarketOnCloseOrderBufferRegressionAlgorithm

* CustomIndicatorAlgorithm

* ScheduledQueuingAlgorithm

* ComboOrdersFillModelAlgorithm

* CustomIndicatorWithExtensionAlgorithm

* IndicatorWithRenkoBarsRegressionAlgorithm

* CoarseFineOptionUniverseChainRegressionAlgorithm

* NumeraiSignalExportDemonstrationAlgorithm

* DropboxUniverseSelectionAlgorithm

* WeeklyUniverseSelectionRegressionAlgorithm

* AutoRegressiveIntegratedMovingAverageRegressionAlgorithm

* DropboxBaseDataUniverseSelectionAlgorithm

* IronCondorStrategyAlgorithm

* LongAndShortButterflyPutStrategiesAlgorithm

* FutureStopMarketOrderOnExtendedHoursRegressionAlgorithm

* LongAndShortCallCalendarSpreadStrategiesAlgorithm

* KerasNeuralNetworkAlgorithm

* LongAndShortPutCalendarSpreadStrategiesAlgorithm

* OptionPriceModelForOptionStylesBaseRegressionAlgorithm

* TensorFlowNeuralNetworkAlgorithm

* MarketOnCloseOrderBufferRegressionAlgorithm

* MarketOnCloseOrderBufferExtendedMarketHoursRegressionAlgorithm

* typing

* ComboOrderTicketDemoAlgorithm

* PytorchNeuralNetworkAlgorithm

* MultipleSymbolConsolidationAlgorithm

* fixes

* revert getattr mypy syntax

* address peer review

* Addresses Peer-Review

---------

Co-authored-by: Alexandre Catarino <AlexCatarino@users.noreply.github.com>
2025-04-14 09:43:03 -03:00
Jhonathan Abreu
fe46e5ec3b Fill-forward previous universe files for manual chains fetching when current missing (#8691)
* Fill forward prev date universe file in manual chains fetch

If there is no universe file available for the current date, use the previous one and fill forward to avoid having empty chains on a day when we haven't generated the universe files

* Try a maximum of 3 days behind for manual chains fetching

* Minor change

* Minor fix

* Add comments

* Minor fix

* Minor fix for expired contracts
2025-04-11 13:57:29 -03:00
JosueNina
4c7bda8e34 Fix futures history request error (#8678)
* Initial solution

* Create testCases for earlyClose and lateOpen

* Refactor GetExchangeHours and add unit tests

* Update market-hours-database and create a unit test

* Resolve review comments

* Update market-hours-database

* Parallelize the foreach loop to improve test performance
2025-04-11 13:37:14 -03:00
Roman Yavnikov
13ace56eea Refactor: Eze brokerage (#8689)
* refactor: model and OrderProperties of Eze

* feat: additional configs for Eze brokerage
2025-04-11 13:35:14 -03:00
Martin-Molinero
ff185d0311 Minor Api testing improvements (#8687)
* Add missing backtests/read null check

* Improve SPDB error message
2025-04-10 17:30:55 -03:00
Jhonathan Abreu
e90309678e Security initialization on re-addition (#8681)
* Initialize security after addition and re-addition

* Improve regression algorithms

* Add universe selection regression algorithm

* Add minor comment
2025-04-09 16:26:05 -04:00
Alexandre Catarino
ea41fedb30 Handles Empty Signal Export List (#8686) 2025-04-09 16:44:47 -03:00
Alexandre Catarino
1cb0405517 Adds Custom Signal Export Example (#8674)
* Adds example of custom signal exports.

- SignalExportManager send signals automatically after 5 seconds.
- Missing example and Python support.

* Updates Examples to Disable Automatic Export

* Addresses Peer-Review
2025-04-09 10:14:21 -03:00
Jhonathan Abreu
1e4ef83132 Fix failing history unit test (#8682)
* Fix failing unit test

Add algorithm start date so period history request is consistent

* Minor change
2025-04-08 12:00:32 -03:00
Martin-Molinero
e416a54873 Update readme.md 2025-04-07 19:24:29 -03:00
Jhonathan Abreu
a9927fe111 Adjust times to exchange and QB time zones in Option/Future history calls (#8680) 2025-04-07 19:10:41 -03:00
Martin-Molinero
cd7663ef97 Minor tweaks for testing (#8679)
* Minor tweaks for backtest tests

* More tweaks
2025-04-07 18:41:44 -03:00
Roman Yavnikov
e1cd63643f feat: OptionCodeLookup publicly (#8676) 2025-04-07 12:22:18 -03:00
Roman Yavnikov
87487ec4c0 feat: missed order status in OrderTestParameters for different orders (#8677) 2025-04-07 12:22:09 -03:00
Jhonathan Abreu
1974884c13 Security re-addition tidy up (#8656)
* Initialize securities on re-addition

* Minor unit tests fixes

* Reset Index.ManualSetIsTradable when security is removed

* More changes to clean up and simplify

* Address security re-utilization only

* Cleanup regression algorithms
2025-04-04 16:28:15 -04:00
Martin-Molinero
f963e43346 Minor improvements for testing and api (#8672)
* Minor improvements for LLMs

- Minor tweaks in regression tests
- Minor API sugars

* Ignore union-attr error
2025-04-03 17:49:41 -03:00
Ricardo Andrés Marino Rojas
980cdeaa75 Remove fill warnings from order tags (#8668)
* Remove warnings from tags and tests

* Fix bugs

* fix bugs

* Revert wrong updates in some stats

* Fix bugs
2025-04-03 17:49:21 -03:00
Jhonathan Abreu
26ef02399f Fix QuantBook Option/Future history api date range (#8671)
* Fix QuantBook Option/Future history api date range

Properly calculate date range when passed range is not a whole date but a time of day

* Extended unit tests
2025-04-03 16:45:35 -04:00
Jhonathan Abreu
68ec0b72b2 Disable extended market hours for universe history requests (#8670)
* Disable extended market hours for universe history requests

* Exclude extended market hours for all chain universe history requests

* Disable extended market hours for chain universes

* Minor change

* Minor fix

* Minor change
2025-04-02 14:11:38 -03:00
JosueNina
a8d36497d4 Prevent fill-forwarding outside OpenInterest trading hours (#8662)
* Prevent fill-forwarding outside OpenInterest trading hours

* Solve review comments

* Fix unit test

* Resolve review comments

* Revert changes in FillForwardEnumerator

* Revert unrelated changes
2025-04-02 09:22:58 -03:00
Jhonathan Abreu
73684e8e70 Keep time of day on open interest consolidator (#8667)
* Avoid time round down for open interest hour and daily consolidation

* Consolidate OI data on date and hour change

* Cleanup

* Add more test cases
2025-03-31 17:57:12 -04:00
laur89
1e84ee59ce fix CandlestickSeries constructor (#8664)
- likely a copy-pasta error from Series, where index=0 is passed to
  BaseSeries constructor, only now it was passed as SeriesType, which
  is subsequently set in CandlestickSeries constructor
2025-03-31 16:44:22 -03:00
Martin-Molinero
2cafba85f7 Ignore missing types in syntax check (#8660) 2025-03-28 13:19:40 -03:00
Martin-Molinero
513ced31d7 Add python syntax check (#8651)
* Add python syntax check

* Fix some python regression algorithms

* Fixing more bugs
2025-03-28 10:36:26 -03:00
Roman Yavnikov
581e87809b Fix: SettlementDays (#8657)
* feat: make static and get; set; of DefaultSettlementDays in Equity,Option

* refactor: reset _lastUnsettledCash depend on settlementDays in UnsettledCashWhenQuoteCurrencyIsNotAccountCurrencyAlgorithm
2025-03-28 10:36:05 -03:00
JosueNina
80498d5a1f Fix dataType assignment logic in GetMatchingSubscriptions (#8653)
* Fix dataType assignment logic in GetMatchingSubscriptions

* Updated unit test

* Change parameter from string to bool
2025-03-27 16:19:28 -03:00
Ricardo Andrés Marino Rojas
f5dd7236fc Avoid innecessary stub generation (#8654)
* FINAL TEST

* Change version

* test commit

* echo commits

* echo last commits before generating stubs

* Fix bugs

* fix more bugs

* fix yaml error

* try with a different version

* Check we can get last commits

* add variables in options

* Echo commits

* tweaks

* More tweaks

* Add an exception

* FINAL TEST
2025-03-27 13:30:34 -03:00
Jhonathan Abreu
69d2f5ae82 Futures and Future Options file-based universes (#8480)
* Make FOPs selection universe file-based for backtesting

* Make FOPs option chains universe file based

* Make Future universe selection file-based like option universe

* Make Future universe selection file-based like option universe

* Abstraction cleanup

* Add FuturesChains API to QC algorithm

Also refactor future chain provider to use the new FutureUniverse instead of zip file names

* Update regression algorithms stats

* Refactor QuantBook option and future history to use new universes

* Fix failing tests

* Fix failing tests

* Fix failing tests

* Minor future chains unit test improvement

* Add futures chains DataFrame property

Also, remove IDerivativeSecurity interface from Future

* Add DataFrame property to FuturesChains class

* Add regression algorithms

* Add regression algorithms

* Replace QCAlgorithm.FutureChainProvider usages with new FuturesChain api

* Minor fixes

* Reduce number of universe files in repo

* Minor data fixes

* Regression algorithms updates

* Add implicit conversion from FuturesContract to Symbol

Modified algorithms to use futures contract objects directly instead of accessing their Symbol property.
Removed unnecessary import statements and redundant lines in various files.

* Improve resolution handling for history requests

* Changed _auxiliaryData field to lazily-initialized AuxiliaryData property

* Refactor data handling in BaseChain and TimeSliceFactory

- Added `AddData` method to `BaseChain` for adding market data
- Refactored `TimeSliceFactory` to use `BaseChain.AddData` method

* Remove specific constructors and indexers from Chain classes

Removed public indexers in `BaseChains` for getting or setting `BaseChain` instances by `ticker` or `Symbol`, which were used for Pythonnet compatibility.

* Remove chain cache logic from FuturesChainUniverse

* Refactor class and interface names for clarity

Renamed `FileBasedUniverse` to `BaseChainUniverseData` and
`IFileBasedUniverse` to `IChainUniverseData`.

* Add base class for options and futures contracts

- Introduced `BaseContract` as an abstract base class for contracts, consolidating common properties and methods.
- Removed ISymbolInterface

* Add minor fix for future options tickers parsing

Added tests

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Clean chain provider classes up

* Remove ZipEntryName other classes and unused code

Removed ZipEntryName class and references across various files.
Removed DataQueueFuturesChainUniverseDataCollectionEnumerator and DataQueueOptionChainUniverseDataCollectionEnumerator classes.
Removed OptionChainUniverseSubscriptionEnumeratorFactory class.
Removed unused code for handling OptionChainUniverse and FuturesChainUniverse in FileSystemDataFeed.cs and LiveTradingDataFeed.cs.
Removed several test files related to enumerator factories and universe data collection.

* Minor changes and cleanup

* Trigger Build

* Trigger Build

* Refactor FuturesContract data handling

Forward price data from bars and ticks stored in private fields for improved memory usage

* Fix: use universe data for market data in FuturesContract

* Update regression algorithms stats after rebase

Added HSI futures universe files

* Sort configs by internal flag

Internals go first

* Throw from option universe data filters for future options

Future options IV, Open interest and greeks are not supported for future options

* Minor changes

* Improve some regression algorithms

* Minor fix for failing unit tests

* Update FOPs universe file header

Removed greeks and IV columns.
Updated FOPs universe files: removed outdated columns.

* Minor unit test fix

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Minor fix

* Add history provider as constructor argument for chain providers

* Update new regression algorithms data points count

* Minor fix for FakeDataQueue

* Add initialize method to chain providers classes

* Minor changes

* Trigger Build

* Trigger Build

* Trigger Build

* Minor fix

* Minor fix

* Trigger Build

* Trigger Build

* Trigger Build

* Trigger Build

* Add logs to ProcessedDataProvider

* Removed test logs

* Minor fix

* Support downloading options and futures universe files from api data provider
2025-03-25 16:22:38 -04:00
JosueNina
2d7e3297a6 Add regression algo for indicator updates: Resolution.Daily vs TimeSpan.FromDays(1) (#8646)
* Create regression algorithm

* Add new regression algo

* Update regression algorithms

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

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

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

* Update unit test

* Explicit conversion if T is IndicatorDataPoint

* Solve review comments

* Add override tests for Beta and Alpha

* Refactor and update unit test suite

* Create unit test for OptionIndicators

* Resolve review comments

* Resolve new review comments

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

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

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

* test:feat: parsing of universe path

* rename: return variable in ParseUniversePath

* feat: extension to create history request internally

* feat: entity  DataUniverseDownloaderGetParameters

* config: downloaderDataProvider project

* feat: create DataUniverseDownloadConfig in download project

* feat: run universe downloader in DownloaderProvider

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

* refactor: run Universe downloader in Main

* feat: GetUniverseFileName by processingDate

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

* feat: new out argument in TryParsePath's LeanData

* feat: RunUniverseDownloader in DownloadDataProvider

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

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

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

* refactor: overload TryParsePath only with 4 parameters

* remove: editconfig file in DownloaderDataProvider

* remove: validation on null parameters

* rename: typo DateType to DataType

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

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

* fix: RunUniverseDownloader with EndUtc in DownloaderDataProvider

* refactor: GetUniverseFullFilePath

* remove:  validate historyData like Any

* fix: use date from parsing path in DownloaderDataProvider

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

* revert: CreateHistoryRequest() in DownloaderExtensions

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

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

* clean: extra `usings`

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

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

* Fix WarmupIndicator to support multi symbol indicators in Python

* Minor fix for WarmUpIndicator api

* Refactored switch statements for indicator conversion

* Solve comments review

* Refactored WarmUpIndicator to remove duplicated code

* Resolve review comments

---------

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

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

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

* Use local repo data for unit tests

* Move unit tests to algorithm history tests

* Use UniverseManager instead of CacheCustomPythonDataType

* Add regression algorithms

* Update regression algorithms to solve issues

* Update regression test and History

* Updated source path to avoid issues with linux

---------

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

Send a command to all live algorithms.

* Addresses Peer-Review

* Minor tweaks

---------

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

* Update regression algorithms

* Resolve review comments

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

* Remove old format

* Address requested changes

* Add Index option test case

* nit changes

* Address Martin reviews, improve unit tests and solve 8577

* Add unit tests

* Nit change

* Address requested changes

* Address Martin reviews

* Nit changes and more unit tests

* Nit change

* Address requested changes

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

* Add python support for CompositeIndicator

* Add unit tests and update CompositeIndicator

* Add new test case

* Update TryConvertToIndicator logic

* Solve review comments

* Resolve review comments

* Remove unnessary case

* Use GetIndicatorAsManagedObject instead of ConvertToIndicator

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

* Update ib gateway version in config file

* Remove ib-version config

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

* remove outdated comments

---------

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

* Resolve review comments

* Add an entry to SPDB for ASX

* Add new indexes and update the old ones

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

* Further improvements

* Add test for default empty holding

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

* Add missing holidays to MHDB

* Add 2025 new year's eve bank holiday

* Add Columbus day and veterans day to bank holidays

* Add missing bank holidays entry

* Modify FuturesExpiryFunctions

* Add missing change

* Remove empty bankHolidays lists from MHDB

* Address review

* Add tests

* Address review

* Add bank holidays from 2009-2024

* Fix unit and regression tests

* Review bank holidays

* Fix tests

* MHDB tweaks

* Remove Bank holidays from CNH, MNH and MIR

* Add setting for bank holidays disabled by default

---------

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

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

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

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

* Improve unit test

* Apply market hours database updates to instance

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

* Improved unit tests

* Update data folder MHDB entries instead of overriding instance

* Optionally reset custom mhdb entries on reset

* Simplify mhdb reset in live trading

Cleanup and minor fixes

* Ensure symbol properties database updates are picked up by consumers

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

* Fix for symbol properties update thread safety

* Minor improvements and cleanup

* Mhdb and spdb update logic simplification

* Move "force exchange always open" logic to mhdb

* Simplify symbol properties holder and updates

* Refactor security databases to use a common base class

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

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

* Introduce MultiSymbolIndicator for indicators working on multiple symbols

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

* Accept any BaseData for options indicators

* Improve indicator conversion from python on registration

Also minor fixes

* Cleanup and simplification

* Fix ImpliedVolatility IsReady flag

* Update regression algorithm history count

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

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

* Update regression test

* Update assertions

* Resolve PR comments

* Add more order types to regression test

* Update regression algorithm name

* Update old regression algorithm

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

* Update ValidateSufficientBuyingPowerForOrders

* Update regression algorithm

* Resolve review comments

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

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

* Central Time correction

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

* Add expectedQuantities to the testCases

* Update regression tests

* Update name of regressionAlgorithm

* Address review comments

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

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

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

* Minor fix

* Minor change

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

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

* Addressed review comments

* Addressed new comments review

* Update default value for 'tag'

* Update ExpectedStatistics

* Identify and liquidate portfolio symbols not included in targets

* Create a new regression test

* Fix minor comments

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

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

* Update unit test and create test cases

* Add new unit test

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

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

* Make Collective2SignalExport Destination public and assignable

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

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

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

* Minor MHDB cleanup

---------

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

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

* Addressed PR comments

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

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

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

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

* Update unit test

* Added TestCase for CNHT and USD

* Fixed bug in pair comparison logic, corrected concatenation approach

* Add unit test for currency pair match

* Added test cases for currency pair comparison

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

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

* Add holiday to equity and index

And by extension to options and index options

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

* Update SPDB with Coinbase

* Merge completed successfully without deletion

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

* Use InitialMargin instead of MaintenanceMargin

* Addressed review comments

* Update unit test

* Refactor GenerateOptionTicker method to handle IndexOption

* Addressed PR comments

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

* Update readme.md

* Update readme.md

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

* Patched holidays in MarketHours

* Minor fix

---------

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

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

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

* Skip subscription to selected securities when no tradable dates

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

* Minor comment

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

* Keep holidays list order

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

* Simplified comparison logic and improved abstraction

* Refactor Correlation and Beta indicators

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

* Addressed review comments

* Update regression test

* Add new unit test to CommonIndicatorTests

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

* Add 2025 holidays, early closes and late opens

* Review and improve changes

* add missing entries

* Nit change

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

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

* First potential solution

* Add regression tests

* Nit change

* Address requested changes

* Nit change

* Nit change

* Improve implementation

* Fix bugs

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

* Create Unit Test for ZigZag Indicator

* Update QCAlgorithm with ZigZag Indicator

* Resolved review comments

* Refactor ZigZag Indicator

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

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

* Create unit test for SqueezeMomentum Indicator

* Update QCAlgorithm with SqueezeMomentum indicator

* Resolved review comments

* Switched to using Keltner indicator instead of manual calculation

* Refactor Squeeze Momentum indicator

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

* Fix issue with regression tests

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

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

* Address review comments

* Add time zone handling and resolution-based truncation

* Fix regression test for Beta indicator

* Handle resolution for beta indicator

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

* Fix issue with period and WarmUpPeriod

* Update unit tests for Alpha indicator

* Fixing minor issues

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

* Add regression test for Beta calculation between BTCUSD and SPY

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

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

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

* Update tolerance in greek indicators tests

* Minor fix

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

* Cache option expiration date time

* Minor changes

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

* Address requests

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

* Cleanup

* Update regression algorithms stats

* Minor fix and cleanup

* Minor fix

* Minor fix

* Update regression algorithms data point count

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

* Fix bug

* Address requests

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

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

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

* add python example

* regression

* add pythom implementation as example model

* peer review

* dependencies

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

* Add regression tests

* Improve solution and add unit test

* Address suggestions

* Improve unit tests

* Nit changes

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

Closes #8443

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

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

* Optimize Hurst Exponent calculation

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

* Refactor HurstExponent indicator

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

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

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

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

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

* Make base data collection aggregator reader fall back to BaseDataCollection

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

* Minor change

* Minor change

* Update pythonnet to 2.0.41

* Ignore data column for every flattened universe dataframe

* Filter empty collections columns in data frames

* Allow snake case named attributes in PythonSlice

* Remove PythonSlice Data Python class

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

* Add regression tests

* Nit changes

* Solve root issue

* Improve regression tests

* Reduce duplication

* Nit change

* Improve implementation

* Address suggestions

* Address requested improvements

* Nit change

* Nit changes

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

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

* Minor fixes

* Minor test data changes

* Fixes and comments

* Address peer review and add some fixes

* Minor fix and add regression algorithm

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

* Add regression tests

* Nit changes

* Solve root issue

* Improve regression tests

* Reduce duplication

* Nit change

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

* Implemented Mesa Adaptive Moving Average (MAMA) indicator

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

* Refactor Mesa Adaptive Moving Average(MAMA)

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

* Refactor variables and update method parameters

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

* Add XML docs

* Fix and improve unit test

* Address suggestions

* Improve unit test

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

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

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

* Fixes

* Add PandasConverter.DataFrameGenerator class

* Pandas data frame generator class fixes

* Add comments

* Housekeeping

* Add attributes to mark classes and properties for pandas processing

* Improve pandas properties expanding

Allow and handle duplicate names

* Use PandasData generalization for Lean common data types

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

* Cleanup and minor changes

* Minor change

* Pandas data to get type members on demand

* Move Pandas helper classes to their own files

* Minor changes

* Add flatten argument to python history api

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

* Adding missing changes to last commit

* Update Pythonnet version to 2.0.40

* Add flattent argument to algorithm's OptionChain api

* Minor changes

* Housekeeping

* Minor changes

* Bug fix skipping data collection data points

* Add comment

* Set correct exchange time to OptionUniverse instances

* Address peer review and cleanup

* Cleanup

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

* Fix bugs

* second try to fix bugs

* Fix typos

* Nit change

* Update enums too

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

* Add unit tests

* Address requested changes

* Add unit test reproducing user bug

* Missing update

* Address reviews

* Improve unit test

* Improve unit test

* Nit change

* Nit changes

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

* Add unit test

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

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

* Refactor CRSI indicator

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

* Refactor CRSI Indicator:

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

* Fix comments from code review

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

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

* Update regression algorithm stats

* Revert/remove transaction handler initialization parameters DTO class

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

* Add regression algorithms

* Cleanup

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

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

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

* feat: BrokerageModel, FeeModel of Charles Schwab

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

* refactor: CharlesSchwabFeeModel (a little bit simpler)

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

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

* Refactor AverageDailyRange Indicator

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

* Solving minor issues with AR indicator

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

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

This commit introduces a new indicator.

* Add license header and adjust spacing

* Refactor Premier Stochastic Oscillator (PSO)

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

* Refactor PSO

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

* Add assertions

* Nit changes

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

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

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

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

* Try a different approach

* Nit change

* Add unit tests

* Add edge cases

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

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

* Fix price shift on continuous future rollover

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

* Fix for daily and hourly resolutions.

Add daily and hour algorithms

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

* Cleanup

* Minor fix

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

* Minor fix

* More fixes

* More fixes

* Fixes for universe files

* More fixes for daily resolution data

* Separate DateChangeTimeKeeper to its own file

* Add DateChangeTimeKeeper unit tests

* Minor fix

* Add more DateChangeTimeKeeper unit tests

* Address peer review

* Address peer review

* Address peer review

* Detect mappings using the config NewSymbol event

* DateChangeTimeKeeper performance improvement for time zone conversions

* Clean up date change time keeper

* Cleanup

* Minor regression algo update

* Cleanup

* Cleanup

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

* Cleanup

* Address peer review

* More cleanup

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

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

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

* Reduce duplication

* Fix missing overload method

* Address requests

* Nit change

* Improve implementation

* Improve implementation

* Fix bug and add more unit tests

* Nit change

* Address requested changes

* Address requested changes

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

* fix: CustomDataPropertiesRegressionAlgorithm

* fix: CustomDataRegressionAlgorithm py

* fix: CustomDataPropertiesRegressionAlgorithm py

* fix: RegisterIndicatorRegressionAlgorithm py

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

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

* refactor: xml description of Sort property in SubscriptionDataSource

* revet: TextSubscriptionDataSourceReader changes

* feat: develop UnsortedTextSubscriptionDataSourceReader

* remove: UnsortedTextSubscriptionDataSourceReader

* feat: develop SortEnumerator
feat: use SortEnumerator in SubscriptionDataReader

* revert: TextSubscriptionDataSourceReader changes

* feat: use sort Enumerator in LiveCustomDataSubscriptionEnumeratorFactory

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

* test:feat: history CustomData request with unsorted data

* refactor: develop TryWrapper on SortEnumerator

* remove: extra spacing

* refactor: Sort in SubscriptionDataSource

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

* refactor: xml description of prop Sort in  SubscriptionDataSource

* refactor: SortEnumerator

* test:refactor access modifier in ExampleCustomDataWithSort

* test:refactor: increase performance LiveDataFeedSourcesDataFromObjectStore

* feat: add xml comment of regression algorithm

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

* test:refactor: use while instead of timer

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

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

* Add missing algorithm

* Improve regression tests

* Nit change

* Address requests

* Nit change

* Address minor requests

* Nit changes

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

* Improve solution

* Nit change

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

* Properly convert list of data into dataframe

Take into consideration data for multiple symbols in the same list

* Cleanup

* Index dataframes by symbol object instead of SID string

* Add symbol equality operator to compare against object

* Exclude "ID" from option chain dataframe

* Minor fix

* Add greeks columns directly in option chain dataframe.

Also add pass-through properties for greek values in OptionUniverse

* Some cleanup

* Minor fix

* Add new QCAlgorithm.OptionChains() method

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

* Unify QCAlgorithmOptionChain API

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

* Pass symbol properties to OptionUniverse option chain from algorithm

* Format OptionContract for dataframe

* Minor fix

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

* Address peer review

Add NullGreeks class: keep ModeledGreeks as internal as possible

* Minor fix and add PandasConverter unit tests

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

* Handle Greeks unwrapping by PandasData

* PandasData cleanup

* Add data and other minor changes

* Unit test fix

* Update Pythonnet to 2.0.39

* Cleanup

* PandasData handling children class members

Address peer review

* Fix: indexing symbol conversion in pandas mapper

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

* Cleanup

* Cleanup

* Add PandasColumn python class to handle proper indexing

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

* Minor fixes

* Symbol cache improvements

* Minor fix for cache miss

* Revert PandasMapper reserved names and improvements

* Minor fix

* Revert reserved names

* Minor fix for Symbol equality operators

---------

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

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

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

* Margin model

* regression tests

* strategy unit test

* refactor

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

* Infer data type from configs in bar count history requests

* Minor changes

* Minor fix

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

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

* feat: missed config of TradeStation in Launcher

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

* Minor tweaks

---------

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

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

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

* feat: GetSubscribedSymbols by TickType

* test:feat: GetSubscribeSymbolsBySpecificTickType

* refactor: equal channel name with InvariantCultureIgnoreCase
2024-09-17 12:52:24 -03:00
1242 changed files with 93461 additions and 15511 deletions

View File

@@ -1,33 +1,43 @@
{
"name": "Lean Development Container",
"workspaceMount": "source=${localWorkspaceFolder},target=/Lean,type=bind",
"workspaceFolder": "/Lean",
// Use devcontainer Dockerfile that is based on Lean foundation image
"build": { "dockerfile": "Dockerfile" },
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash"
"build": {
"dockerfile": "Dockerfile"
},
//See https://containers.dev/implementors/json_reference/ for a comprehensive json schema used to define this file.
"customizations": {
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csdevkit",
"ms-python.python",
"eamodio.gitlens",
"yzhang.markdown-all-in-one",
"SonarSource.sonarlint-vscode"
],
// Set *default* vscode specific settings.json values on container create.
"settings": {
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash"
}
}
}
}
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["ms-dotnettools.csharp", "ms-python.python", "ms-python.vscode-pylance", "formulahendry.dotnet-test-explorer", "eamodio.gitlens", "yzhang.markdown-all-in-one"],
//use the same network configuration as the host machine, ensuring no problems with firewalls, proxies etc.
"runArgs": [
"--network=host"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line to run commands after the container is created - for example installing curl.
"postCreateCommand": "dotnet nuget add source /Lean/LocalPackages;chmod u+x /Lean/.vscode/launch_research.sh;dos2unix /Lean/.vscode/launch_research.sh",
// Add mounts to docker container
"mounts": [
"mounts": [
// Example data mount from local machine, must use target directory in Config.json
// "source=C:/Users/XXXXXXXXXXXX/Lean/Data,target=/Data,type=bind,consistency=cached"
]

View File

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

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

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

View File

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

View File

@@ -9,14 +9,19 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
# Only run on push events (not on pull_request) for security reasons in order to be able to use secrets
if: ${{ github.event_name == 'push' }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- name: Run API Tests
uses: addnab/docker-run-action@v3
with:
@@ -27,4 +32,4 @@ jobs:
# Build
dotnet build /p:Configuration=Release /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln
# Run Projects tests
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 300seconds --blame-crash --filter "FullyQualifiedName=QuantConnect.Tests.API.ProjectTests|ObjectStoreTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\)
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 7minutes --blame-crash --logger "console;verbosity=detailed" --filter "FullyQualifiedName=QuantConnect.Tests.API.ProjectTests|FullyQualifiedName=QuantConnect.Tests.API.ObjectStoreTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\)

View File

@@ -9,12 +9,20 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Free space
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
with:
fetch-depth: 0 # Ensures we fetch all history
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- uses: addnab/docker-run-action@v3
with:
@@ -22,9 +30,15 @@ jobs:
options: --workdir /__w/Lean/Lean -v /home/runner/work:/__w -e GITHUB_REF=${{ github.ref }} -e PYPI_API_TOKEN=${{ secrets.PYPI_API_TOKEN }} -e ADDITIONAL_STUBS_REPOS=${{ secrets.ADDITIONAL_STUBS_REPOS }} -e QC_GIT_TOKEN=${{ secrets.QC_GIT_TOKEN }}
shell: bash
run: |
# Add exception
git config --global --add safe.directory /__w/Lean/Lean
# Get Last Commit of the Current Tag
TAG_COMMIT=$(git rev-parse HEAD) && echo "CURRENT BRANCH LAST COMMIT $TAG_COMMIT"
# Get Last Commit of the master
MASTER_COMMIT=$(git rev-parse origin/master) && echo "MASTER BRANCH LAST COMMIT $MASTER_COMMIT"
# Build
dotnet build /p:Configuration=Release /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln && \
# Run Tests
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 300seconds --blame-crash --filter "TestCategory!=TravisExclude&TestCategory!=ResearchRegressionTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\) && \
# Generate & Publish python stubs
echo "GITHUB_REF $GITHUB_REF" && if [[ $GITHUB_REF = refs/tags/* ]]; then (chmod +x ci_build_stubs.sh && ./ci_build_stubs.sh -t -g -p); else echo "Skipping stub generation"; fi
echo "GITHUB_REF $GITHUB_REF" && if [[ $GITHUB_REF = refs/tags/* && "$TAG_COMMIT" = "$MASTER_COMMIT" ]]; then echo "Generating stubs" && (chmod +x ci_build_stubs.sh && ./ci_build_stubs.sh -t -g -p); else echo "Skipping stub generation"; fi

View File

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

View File

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

View File

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

View File

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

32
.github/workflows/syntax-tests.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Syntax Tests
on:
push:
branches: ['*']
tags: ['*']
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- name: Run Syntax Test
uses: addnab/docker-run-action@v3
with:
image: quantconnect/lean:foundation
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 && \
python run_syntax_check.py

View File

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

View File

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

6
.vscode/readme.md vendored
View File

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

View File

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

View File

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

View File

@@ -49,7 +49,7 @@ namespace QuantConnect.Algorithm.CSharp
contractDepthOffset: 0
);
_futureContract = AddFutureContract(FutureChainProvider.GetFutureContractList(_continuousContract.Symbol, Time).First());
_futureContract = AddFutureContract(FuturesChain(_continuousContract.Symbol).First());
}
/// <summary>
@@ -115,12 +115,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 73;
public long DataPoints => 61;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 1;
/// <summary>
/// Final status of the algorithm

View File

@@ -164,12 +164,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 311879;
public long DataPoints => 311881;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 2;
/// <summary>
/// Final status of the algorithm

View File

@@ -93,12 +93,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 12169;
public long DataPoints => 9922;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 2;
/// <summary>
/// Final status of the algorithm
@@ -113,7 +113,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "20"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "386219349.202%"},
{"Compounding Annual Return", "88398927.578%"},
{"Drawdown", "5.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

@@ -108,7 +108,7 @@ namespace QuantConnect.Algorithm.CSharp
return;
}
foreach (var chain in slice.OptionChains.Values)
foreach (var chain in slice.OptionChains.Values.OrderBy(x => x.Symbol.Underlying.ID.Date))
{
var futureInvested = false;
var optionInvested = false;
@@ -220,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 608377;
public long DataPoints => 319494;
/// <summary>
/// Data Points count of the algorithm history
@@ -240,7 +240,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "2"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "347.065%"},
{"Compounding Annual Return", "309.669%"},
{"Drawdown", "0.900%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

@@ -0,0 +1,130 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Interfaces;
using System;
using QuantConnect.Securities;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This example demonstrates how to use the FutureUniverseSelectionModel to select futures contracts for a given underlying asset.
/// The model is set to update daily, and the algorithm ensures that the selected contracts meet specific criteria.
/// This also includes a check to ensure that only future contracts are added to the algorithm's universe.
/// </summary>
public class AddFutureUniverseSelectionModelRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
public override void Initialize()
{
SetStartDate(2013, 10, 08);
SetEndDate(2013, 10, 10);
SetUniverseSelection(new FutureUniverseSelectionModel(
TimeSpan.FromDays(1),
time => new List<Symbol> {
QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME)
}
));
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.AddedSecurities.Count > 0)
{
foreach (var security in changes.AddedSecurities)
{
if (security.Symbol.SecurityType != SecurityType.Future)
{
throw new RegressionTestException($"Expected future security, but found '{security.Symbol.SecurityType}'");
}
if (security.Symbol.ID.Symbol != "ES")
{
throw new RegressionTestException($"Expected future symbol 'ES', but found '{security.Symbol.ID.Symbol}");
}
}
}
}
public override void OnEndOfAlgorithm()
{
if (ActiveSecurities.Count == 0)
{
throw new RegressionTestException("No active securities found. Expected at least one active security");
}
}
/// <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 => 26094;
/// <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", "-66.775"},
{"Tracking Error", "0.243"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -160,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$5700000.00"},
{"Lowest Capacity Asset", "AOL VRKS95ENLBYE|AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.55%"},
{"OrderListHash", "24191a4a3bf11c07622a21266618193d"}
{"OrderListHash", "fc5ab25181a01ca5ce39212f60eb0ecd"}
};
}
}

View File

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

View File

@@ -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.Collections.Generic;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Interfaces;
using System;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This example demonstrates how to use the OptionUniverseSelectionModel to select options contracts based on specified conditions.
/// The model is updated daily and selects different options based on the current date.
/// The algorithm ensures that only valid option contracts are selected for the universe.
/// </summary>
public class AddOptionUniverseSelectionModelRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private int _optionCount;
public override void Initialize()
{
SetStartDate(2014, 06, 05);
SetEndDate(2014, 06, 06);
UniverseSettings.Resolution = Resolution.Minute;
SetUniverseSelection(new OptionUniverseSelectionModel(
TimeSpan.FromDays(1),
SelectOptionChainSymbols
));
}
private static IEnumerable<Symbol> SelectOptionChainSymbols(DateTime utcTime)
{
var newYorkTime = utcTime.ConvertFromUtc(TimeZones.NewYork);
if (newYorkTime.Date < new DateTime(2014, 06, 06))
{
yield return QuantConnect.Symbol.Create("TWX", SecurityType.Option, Market.USA);
}
if (newYorkTime.Date >= new DateTime(2014, 06, 06))
{
yield return QuantConnect.Symbol.Create("AAPL", SecurityType.Option, Market.USA);
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.AddedSecurities.Count > 0)
{
foreach (var security in changes.AddedSecurities)
{
var symbol = security.Symbol.Underlying == null ? security.Symbol : security.Symbol.Underlying;
if (symbol != "AAPL" && symbol != "TWX")
{
throw new RegressionTestException($"Unexpected security {security.Symbol}");
}
_optionCount += (security.Symbol.SecurityType == SecurityType.Option) ? 1 : 0;
}
}
}
public override void OnEndOfAlgorithm()
{
if (ActiveSecurities.Count == 0)
{
throw new RegressionTestException("No active securities found. Expected at least one active security");
}
if (_optionCount == 0)
{
throw new RegressionTestException("The option count should be greater than 0");
}
}
/// <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 => 1658167;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "0"},
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

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

View File

@@ -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 = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
_symbol = FuturesChain(SP500).First();
// Test case: custom IndicatorBase<QuoteBar> indicator using Future unsubscribed symbol
var indicator1 = new CustomIndicator();
@@ -151,7 +151,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 84;
public int AlgorithmHistoryDataPoints => 85;
/// <summary>
/// Final status of the algorithm

View File

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

View File

@@ -339,7 +339,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "17.02%"},
{"OrderListHash", "b1e5e72fb766ab894204bc4b1300912b"}
{"OrderListHash", "a7ce5ff2bbe0fe273cf1631ea5a73fa6"}
};
}
}

View File

@@ -18,7 +18,6 @@ using QuantConnect.Data;
using QuantConnect.Orders;
using QuantConnect.Interfaces;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Securities;
@@ -118,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 713369;
public long DataPoints => 162575;
/// <summary>
/// Data Points count of the algorithm history
@@ -161,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$7100000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.33%"},
{"OrderListHash", "9c524830ffc7354327638142ae62acd2"}
{"OrderListHash", "223735440010fcec5889bb7becacfa82"}
};
}
}

View File

@@ -123,7 +123,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 2217299;
public long DataPoints => 504530;
/// <summary>
/// Data Points count of the algorithm history
@@ -166,7 +166,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$890000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.32%"},
{"OrderListHash", "f60fc7dcba2c1ff077afeb191aee5008"}
{"OrderListHash", "1504a8892da8d8c0650018732f315753"}
};
}
}

View File

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

View File

@@ -56,7 +56,7 @@ namespace QuantConnect.Algorithm.CSharp
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
_mappedSymbol = _continuousContract.Mapped;
var benchmark = AddIndex("SX5E", market: Market.EUREX);
var benchmark = AddIndex("SX5E");
SetBenchmark(benchmark.Symbol);
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
@@ -190,12 +190,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 133945;
public long DataPoints => 94326;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 26;
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
@@ -233,7 +233,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "€2300000000.00"},
{"Lowest Capacity Asset", "FESX YJHOAMPYKRS5"},
{"Portfolio Turnover", "0.40%"},
{"OrderListHash", "54040d29a467becaedcf59d79323321b"}
{"OrderListHash", "ac9acc478ba1afe53993cdbb92f8ec6e"}
};
}
}

View File

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

View File

@@ -149,7 +149,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 75403;
public long DataPoints => 40308;
/// <summary>
/// Data Points count of the algorithm history
@@ -169,7 +169,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "2700"},
{"Average Win", "0.00%"},
{"Average Loss", "0.00%"},
{"Compounding Annual Return", "-99.777%"},
{"Compounding Annual Return", "-99.597%"},
{"Drawdown", "4.400%"},
{"Expectancy", "-0.724"},
{"Start Equity", "1000000"},

View File

@@ -18,8 +18,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
@@ -104,6 +104,16 @@ namespace QuantConnect.Algorithm.CSharp
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.RemovedSecurities.Count > 0 &&
Portfolio.Invested &&
Securities.Values.Where(x => x.Invested).All(x => x.Exchange.Hours.IsOpen(Time, true)))
{
Liquidate();
}
}
/// <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>
@@ -117,7 +127,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 12452;
public virtual long DataPoints => 5861;
/// <summary>
/// Data Points count of the algorithm history
@@ -134,33 +144,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "32"},
{"Total Orders", "34"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Compounding Annual Return", "0.106%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.184"},
{"Expectancy", "0.178"},
{"Start Equity", "1000000"},
{"End Equity", "1001108"},
{"Net Profit", "0.111%"},
{"Sharpe Ratio", "-1.688"},
{"Sortino Ratio", "-0.772"},
{"Probabilistic Sharpe Ratio", "14.944%"},
{"End Equity", "1001066.2"},
{"Net Profit", "0.107%"},
{"Sharpe Ratio", "-1.695"},
{"Sortino Ratio", "-0.804"},
{"Probabilistic Sharpe Ratio", "14.797%"},
{"Loss Rate", "88%"},
{"Win Rate", "12%"},
{"Profit-Loss Ratio", "8.47"},
{"Profit-Loss Ratio", "9.01"},
{"Alpha", "-0.007"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Treynor Ratio", "-4.112"},
{"Total Fees", "$76.30"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "168731c8f3a19f230cc1410818b3b573"}
{"Portfolio Turnover", "0.92%"},
{"OrderListHash", "ddaa9dd20647fdbc4811d6e64bb30a40"}
};
}
}

View File

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

View File

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

View File

@@ -140,12 +140,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 48690;
public virtual long DataPoints => 25316;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public virtual int AlgorithmHistoryDataPoints => 5305;
public virtual int AlgorithmHistoryDataPoints => 6075;
/// <summary>
/// Final status of the algorithm

View File

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

View File

@@ -14,12 +14,7 @@
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
@@ -41,40 +36,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 87289;
public override long DataPoints => 25312;
/// <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", "716"},
{"Total Orders", "718"},
{"Average Win", "0.03%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-1.716%"},
{"Compounding Annual Return", "-1.720%"},
{"Drawdown", "1.700%"},
{"Expectancy", "-0.770"},
{"Start Equity", "1000000"},
{"End Equity", "982718.38"},
{"Net Profit", "-1.728%"},
{"Sharpe Ratio", "-8.845"},
{"Sortino Ratio", "-5.449"},
{"End Equity", "982676.58"},
{"Net Profit", "-1.732%"},
{"Sharpe Ratio", "-8.877"},
{"Sortino Ratio", "-5.476"},
{"Probabilistic Sharpe Ratio", "0.000%"},
{"Loss Rate", "96%"},
{"Win Rate", "4%"},
{"Profit-Loss Ratio", "4.89"},
{"Profit-Loss Ratio", "4.90"},
{"Alpha", "-0.018"},
{"Beta", "-0.002"},
{"Annual Standard Deviation", "0.002"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.483"},
{"Information Ratio", "-1.484"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "9.102"},
{"Total Fees", "$1634.12"},
{"Treynor Ratio", "9.171"},
{"Total Fees", "$1638.42"},
{"Estimated Strategy Capacity", "$8000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "20.10%"},
{"OrderListHash", "aa7e574f86b70428ca0afae381be80ba"}
{"Portfolio Turnover", "20.14%"},
{"OrderListHash", "f6482c8757f82cb9f4c058e3ed6bc494"}
};
}
}

View File

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

View File

@@ -14,14 +14,7 @@
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
@@ -43,40 +36,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 14790;
public override long DataPoints => 5965;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "36"},
{"Total Orders", "32"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "0.102%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.171"},
{"Expectancy", "0.184"},
{"Start Equity", "1000000"},
{"End Equity", "1001024.4"},
{"Net Profit", "0.102%"},
{"Sharpe Ratio", "-1.702"},
{"Sortino Ratio", "-0.836"},
{"Probabilistic Sharpe Ratio", "14.653%"},
{"Loss Rate", "89%"},
{"Win Rate", "11%"},
{"Profit-Loss Ratio", "9.54"},
{"End Equity", "1001108"},
{"Net Profit", "0.111%"},
{"Sharpe Ratio", "-1.688"},
{"Sortino Ratio", "-0.772"},
{"Probabilistic Sharpe Ratio", "14.944%"},
{"Loss Rate", "88%"},
{"Win Rate", "12%"},
{"Profit-Loss Ratio", "8.47"},
{"Alpha", "-0.007"},
{"Beta", "0.002"},
{"Annual Standard Deviation", "0.004"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.353"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "-4.126"},
{"Total Fees", "$80.60"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.97%"},
{"OrderListHash", "52c852d720692fab1e12212b2aba03d4"}
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "741a26424d2210171ad849d92fc75d23"}
};
}
}

View File

@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 228834;
public override long DataPoints => 67924;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
@@ -74,7 +74,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "56.73%"},
{"OrderListHash", "424536177e9be5895bab50638ef43a9d"}
{"OrderListHash", "6ce7812de5c98744cc35169a86a24325"}
};
}
}

View File

@@ -118,7 +118,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$110000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "19.96%"},
{"OrderListHash", "966f8355817adbc8c724d1062691a60b"}
{"OrderListHash", "60747dce5c2aed393b7dccc258d2c9b5"}
};
}
}

View File

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

View File

@@ -66,7 +66,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$300000.00"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Portfolio Turnover", "24.63%"},
{"OrderListHash", "44325fc1fdebb8e54f64a3f6e8a4bcd7"}
{"OrderListHash", "5595ab834c2584c1d124ad575e88cc1a"}
};
}
}

View File

@@ -67,7 +67,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 356;
public override long DataPoints => 360;
/// <summary>
/// Data Points count of the algorithm history
@@ -110,7 +110,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "285cec32c0947f0e8cf90ccb672cfa43"}
{"OrderListHash", "8340619d603921c1ce261287890b9c1c"}
};
}
}

View File

@@ -81,7 +81,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "75e6584cb26058b09720c3a828b9fbda"}
{"OrderListHash", "1c5f424cfe62777733ee68a20320bb8d"}
};
}
}

View File

@@ -128,7 +128,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "₹61000000000.00"},
{"Lowest Capacity Asset", "YESBANK UL"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "7a0257f08e3bb9143b825e07ab47fea0"}
{"OrderListHash", "06f782c83dd633dac6f228b91273ba26"}
};
}
}

View File

@@ -152,7 +152,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "₹84000.00"},
{"Lowest Capacity Asset", "JUNIORBEES UL"},
{"Portfolio Turnover", "0.04%"},
{"OrderListHash", "79ab9ec506959c562be8b3cdbb174c39"}
{"OrderListHash", "8790bec8175539e6d92e01608ac57733"}
};
}
}

View File

@@ -165,7 +165,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$72000.00"},
{"Lowest Capacity Asset", "AAPL W78ZEO2985GM|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.02%"},
{"OrderListHash", "b3125e0af79da0f5eea4cfda09806324"}
{"OrderListHash", "5e20fad3461ac9998afe8d76ad43b25c"}
};
}
}

View File

@@ -142,7 +142,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "15.08%"},
{"OrderListHash", "db6a1134ad325bce31c2bdd2e87ff5f4"}
{"OrderListHash", "f68f6d64a5721ee148bc3c643f8d1b7f"}
};
}
}

View File

@@ -182,7 +182,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "13.50%"},
{"OrderListHash", "cf14a7ce9c86e6844051820fd4c9394c"}
{"OrderListHash", "d40c84371facba5dac8a2c919ea75807"}
};
}
}

View File

@@ -121,20 +121,20 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "0%"},
{"Average Loss", "-0.69%"},
{"Average Win", "0.63%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "54.478%"},
{"Drawdown", "0.400%"},
{"Expectancy", "-0.5"},
{"Expectancy", "23.219"},
{"Start Equity", "1000000"},
{"End Equity", "1006025"},
{"Net Profit", "0.602%"},
{"Sharpe Ratio", "2.62"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "63.221%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "23.22"},
{"Alpha", "0.067"},
{"Beta", "-0.013"},
{"Annual Standard Deviation", "0.004"},
@@ -146,7 +146,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$580000.00"},
{"Lowest Capacity Asset", "SPXW 31K54PVWHUJHQ|SPX 31"},
{"Portfolio Turnover", "0.40%"},
{"OrderListHash", "07a085baedb37bb7c8d460558ea77e88"}
{"OrderListHash", "db5e3681c5fa1888262f2370a9b14c11"}
};
}
}

View File

@@ -127,11 +127,11 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "10"},
{"Average Win", "0.47%"},
{"Average Win", "0.46%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "101.998%"},
{"Drawdown", "0.100%"},
{"Expectancy", "24.484"},
{"Expectancy", "24.137"},
{"Start Equity", "1000000"},
{"End Equity", "1009050"},
{"Net Profit", "0.905%"},
@@ -140,7 +140,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Probabilistic Sharpe Ratio", "95.546%"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "49.97"},
{"Profit-Loss Ratio", "49.27"},
{"Alpha", "-2.01"},
{"Beta", "0.307"},
{"Annual Standard Deviation", "0.021"},
@@ -152,7 +152,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$13000000.00"},
{"Lowest Capacity Asset", "SPXW XKX6S2GM9PGU|SPX 31"},
{"Portfolio Turnover", "0.28%"},
{"OrderListHash", "c1a9bc141ae25c9542b93a887e79dafe"}
{"OrderListHash", "17764ae9e216d003b1f3ce68d15b68ef"}
};
}
}

View File

@@ -154,7 +154,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "117171.12"},
{"End Equity", "117244.50"},
{"End Equity", "117244.52"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
@@ -173,7 +173,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "₮560000.00"},
{"Lowest Capacity Asset", "BTCUSDT 2UZ"},
{"Portfolio Turnover", "44.04%"},
{"OrderListHash", "7426da82dca9e493acbc53c7b9f449f0"}
{"OrderListHash", "47580e88a8cc54b04f3b2bcb5d501150"}
};
}
}

View File

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

View File

@@ -0,0 +1,52 @@
/*
* 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.Data.Consolidators;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the Classic Renko Consolidator with future and default tick data.
/// If consolidation does not happen, a RegressionTestException is thrown
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesAndDefaultTickTypeRegressionAlgorithm : ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm
{
protected override ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
if (tick.TickType != TickType.Quote)
{
throw new RegressionTestException("The tick type should be quote");
}
WasSelectorExecuted = true;
return tick.AskPrice * 10;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator);
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.Data.Consolidators;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the Classic Renko Consolidator with future quote tick data.
/// It checks if valid quote data (non-zero Bid/Ask prices) is received during the algorithm's execution.
/// If consolidation does not happen, a RegressionTestException is thrown
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesQuoteTickTypeRegressionAlgorithm : ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm
{
private bool _hasNonZeroBidPrice;
private bool _hasNonZeroAskPrice;
protected override TickType TickType => TickType.Quote;
protected override ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
_hasNonZeroBidPrice |= tick.BidPrice != 0;
_hasNonZeroAskPrice |= tick.AskPrice != 0;
if (tick.TickType != TickType)
{
throw new RegressionTestException("The tick type should be quote");
}
WasSelectorExecuted = true;
return tick.AskPrice * 10;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator, TickType);
}
public override void OnEndOfAlgorithm()
{
if (!_hasNonZeroBidPrice || !_hasNonZeroAskPrice)
{
throw new RegressionTestException("No valid Quote tick data found: fields (Bid/Ask) were zero.");
}
base.OnEndOfAlgorithm();
}
}
}

View File

@@ -0,0 +1,158 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the functionality of the Classic Renko Consolidator with future trade tick data.
/// It checks if data consolidation occurs as expected for the given time period. If consolidation does not happen, a RegressionTestException is thrown.
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Dictionary<Symbol, ClassicRenkoConsolidator> _consolidators = new Dictionary<Symbol, ClassicRenkoConsolidator>();
private bool _itWasConsolidated;
protected Future GoldFuture { get; set; }
protected virtual TickType TickType => TickType.Trade;
protected decimal BucketSize { get; set; }
protected bool WasSelectorExecuted { get; set; }
public override void Initialize()
{
SetStartDate(2013, 10, 7);
SetEndDate(2013, 10, 9);
GoldFuture = AddFuture("GC", Resolution.Tick, Market.COMEX);
GoldFuture.SetFilter(0, 180);
BucketSize = 2000m;
}
private void OnConsolidated(object sender, TradeBar bar)
{
_itWasConsolidated = true;
}
public override void OnData(Slice slice)
{
if (!_consolidators.ContainsKey(GoldFuture.Mapped))
{
var consolidator = GetConsolidator();
consolidator.DataConsolidated += OnConsolidated;
AddConsolidator(consolidator);
_consolidators[GoldFuture.Mapped] = consolidator;
}
}
public virtual void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator, TickType);
}
protected virtual ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
if (tick.TickType != TickType)
{
throw new RegressionTestException("The tick type should be trade");
}
WasSelectorExecuted = true;
return tick.Quantity * tick.Price;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void OnEndOfAlgorithm()
{
if (!_itWasConsolidated)
{
throw new RegressionTestException("ClassicRenko did not consolidate any data.");
}
if (!WasSelectorExecuted)
{
throw new RegressionTestException("The selector was not executed");
}
}
/// <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 => 1082920;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "5.524"},
{"Tracking Error", "0.136"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -142,7 +142,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$71000.00"},
{"Lowest Capacity Asset", "BTCUSD 2XR"},
{"Portfolio Turnover", "0.29%"},
{"OrderListHash", "179b672b3c1024bbe49dd3b4974232f1"}
{"OrderListHash", "a0058926f4ca5b009cfcc9096506a548"}
};
}
}

View File

@@ -80,8 +80,10 @@ namespace QuantConnect.Algorithm.CSharp
// Initialize this flag, to check when the ema indicators crosses between themselves
_emaFastIsNotSet = true;
// Disable automatic exports as we manually set them
SignalExport.AutomaticExportTimeSpan = null;
// Set Collective2 signal export provider
SignalExport.AddSignalExportProviders(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
SignalExport.AddSignalExportProvider(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
SetWarmUp(100);
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 713369;
public long DataPoints => 162571;
/// <summary>
/// Data Points count of the algorithm history
@@ -182,7 +182,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$76000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "0.91%"},
{"OrderListHash", "7e45786e43b159c7edfcdf0aa0876deb"}
{"OrderListHash", "a472060eeb87c7474d25f7035fa150c4"}
};
}
}

View File

@@ -155,7 +155,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 723496;
public long DataPoints => 172698;
/// <summary>
/// Data Points count of the algorithm history
@@ -198,7 +198,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$230000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "1.39%"},
{"OrderListHash", "795bfb3ab8565e759e98e43a49b0a91d"}
{"OrderListHash", "6a5b2e6b3f140e9bb7f32c07cbf5f36c"}
};
}
}

View File

@@ -120,7 +120,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 9951;
public virtual long DataPoints => 5469;
/// <summary>
/// Data Points count of the algorithm history
@@ -160,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Tracking Error", "0"},
{"Treynor Ratio", "0"},
{"Total Fees", "$2.15"},
{"Estimated Strategy Capacity", "$100000000.00"},
{"Estimated Strategy Capacity", "$130000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "41.23%"},
{"OrderListHash", "b9f8e1a0704c086944e5df07e0ab04d6"}

View File

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

View File

@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
}
return universe.Select(x => x);
return universe;
});
_milk.SetFilter(universe =>
@@ -94,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
}
}
return universe.Select(x => x);
return universe;
});
}
@@ -184,7 +184,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 596356;
public long DataPoints => 445961;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 19886;
public long DataPoints => 10883;
/// <summary>
/// Data Points count of the algorithm history
@@ -98,7 +98,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "-99.258%"},
{"Compounding Annual Return", "-99.012%"},
{"Drawdown", "6.300%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,134 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Compares two correlation types and asserts they are not equal during the algorithm's execution.
/// </summary>
public class CorrelationTypeComparisonRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Correlation _correlationPearson;
private Correlation _correlationSpearman;
/// <summary>
/// Initialise the data and resolution required, as well as the start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 08); //Set Start Date
SetEndDate(2013, 10, 17); //Set End Date
var symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
var spy = AddEquity("SPY", Resolution.Daily).Symbol;
_correlationPearson = C(symbol, spy, 5, CorrelationType.Pearson);
_correlationSpearman = C(symbol, spy, 5, CorrelationType.Spearman);
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice slice)
{
if (_correlationPearson.IsReady && _correlationSpearman.IsReady)
{
var pearsonValue = _correlationPearson.Current.Value;
var spearmanValue = _correlationSpearman.Current.Value;
// Check that the correlation values are not the same
if (pearsonValue == spearmanValue)
{
// Throw an exception if the correlation values are equal
throw new RegressionTestException($"Error: Pearson and Spearman correlation values are the same: Pearson = {pearsonValue}, Spearman = {spearmanValue}. This should not happen.");
}
}
}
/// <summary>
/// End of algorithm run event handler. This method is called at the end of a backtest or live trading operation. Intended for closing out logs.
/// </summary>
public override void OnEndOfAlgorithm()
{
if (!_correlationPearson.IsReady || !_correlationSpearman.IsReady)
{
throw new RegressionTestException("Error: Both correlation values should be ready at the end of the algorithm.");
}
}
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally => true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 80;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "-19.184"},
{"Tracking Error", "0.138"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$66000000.00"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "20.08%"},
{"OrderListHash", "ae85de0e28b44116de68c56ca141c00f"}
{"OrderListHash", "fa51af977e55213dc007a38a3d681b62"}
};
}
}

View File

@@ -144,7 +144,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$150000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "26.62%"},
{"OrderListHash", "c5ca1a8b0ce57cfeadd9eddf8abdd80c"}
{"OrderListHash", "dae7e349316dce7621bc1f8be86ccd0d"}
};
}
}

View File

@@ -111,7 +111,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$180000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "24.86%"},
{"OrderListHash", "c07a9cae88eb3f47309fbf18216bc3cf"}
{"OrderListHash", "8c07dafc84c73401fa0c7709b6baf802"}
};
public class ExampleCustomData : BaseData

View File

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

View File

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

View File

@@ -162,7 +162,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "NWSA.CustomDataUsingMapping T3MO1488O0H0"},
{"Portfolio Turnover", "16.62%"},
{"OrderListHash", "a605ae85beeb854fde8d7b7eff9040ac"}
{"OrderListHash", "fe95edf1a3eabc0ac044b85eb833da5a"}
};
/// <summary>

View File

@@ -159,7 +159,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$150000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "3.19%"},
{"OrderListHash", "91660550269bce594c61fbf9159807d2"}
{"OrderListHash", "c0205e9d3d1bfdee958fecccb36413ec"}
};
}
}

View File

@@ -85,7 +85,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$4800000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "26.72%"},
{"OrderListHash", "a0e8659f340ecf7faa1cc5a0da2760ba"}
{"OrderListHash", "fb2bef182af109f6441ae739d826f39f"}
};
}
}

View File

@@ -93,7 +93,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$87000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "10.93%"},
{"OrderListHash", "3c5f9544f697725475491434f18803e6"}
{"OrderListHash", "8133cb99a1a9f9e9335bc98def3cc624"}
};
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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 Newtonsoft.Json;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Portfolio.SignalExports;
using QuantConnect.Api;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm sends a list of portfolio targets to custom endpoint
/// </summary>
/// <meta name="tag" content="using data" />
/// <meta name="tag" content="using quantconnect" />
/// <meta name="tag" content="securities and portfolio" />
public class CustomSignalExportDemonstrationAlgorithm : QCAlgorithm
{
/// <summary>
/// Initialize the date and add all equity symbols present
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 07);
SetEndDate(2013, 10, 11);
/// Our custom signal export accepts all asset types
AddEquity("SPY", Resolution.Second);
AddCrypto("BTCUSD", Resolution.Second);
AddForex("EURUSD", Resolution.Second);
AddFutureContract(QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15), null));
AddOptionContract(QuantConnect.Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Call, 130, new DateTime(2023, 9, 1)));
// Set CustomSignalExport signal export provider.
SignalExport.AddSignalExportProvider(new CustomSignalExport());
}
/// <summary>
/// Buy and hold EURUSD and SPY
/// </summary>
/// <param name="slice"></param>
public override void OnData(Slice slice)
{
foreach (var ticker in new[] { "SPY", "EURUSD", "BTCUSD" })
{
if (!Portfolio[ticker].Invested && Securities[ticker].HasData)
{
SetHoldings(ticker, 0.5m);
}
}
}
}
internal class CustomSignalExport : ISignalExportTarget
{
private readonly Uri _requestUri = new ("http://localhost:5000/");
private readonly HttpClient _httpClient = new();
public bool Send(SignalExportTargetParameters parameters)
{
object SimplePayload(PortfolioTarget target)
{
var newTarget = PortfolioTarget.Percent(parameters.Algorithm, target.Symbol, target.Quantity);
return new { symbol = newTarget.Symbol.Value, quantity = newTarget.Quantity };
};
var message = JsonConvert.SerializeObject(parameters.Targets.Select(SimplePayload));
using var httpMessage = new StringContent(message, Encoding.UTF8, "application/json");
using HttpResponseMessage response = _httpClient.PostAsync(_requestUri, httpMessage).Result;
var result = response.Content.ReadFromJsonAsync<RestResponse>().Result;
parameters.Algorithm.Log($"Send #{parameters.Targets.Count} targets. Success: {result.Success}");
return result.Success;
}
public void Dispose() => _httpClient.Dispose();
}
}
/*
# To test the algorithm, you can create a simple Python Flask application (app.py) and run flask
# $ flask --app app run
# app.py:
from flask import Flask, request, jsonify
from json import loads
app = Flask(__name__)
@app.post('/')
def handle_positions():
result = loads(request.data)
print(result)
return jsonify({'success': True,'message': f'{len(result)} positions received'})
if __name__ == '__main__':
app.run(debug=True)
*/

View File

@@ -0,0 +1,130 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
/// Reproduces GH issue #8421.
/// </summary>
public class DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Symbol _symbol;
private List<decimal> _openInterests = new();
public virtual bool DailyPreciseEndTime => true;
public override void Initialize()
{
Settings.DailyPreciseEndTime = DailyPreciseEndTime;
SetStartDate(2014, 06, 01);
SetEndDate(2014, 07, 06);
var option = AddOption("AAPL", Resolution.Daily);
option.SetFilter(-5, +5, 0, 365);
_symbol = option.Symbol;
}
public override void OnData(Slice slice)
{
if (slice.OptionChains.TryGetValue(_symbol, out var chain) && chain.Contracts.Count > 0)
{
var openInterest = chain.Sum(x => x.OpenInterest);
_openInterests.Add(openInterest);
Debug($"[{Time}] Sum of open interest: {openInterest}");
}
}
public override void OnEndOfAlgorithm()
{
if (_openInterests.Count == 0)
{
throw new RegressionTestException("No option chain data was received by the algorithm.");
}
if (_openInterests.All(x => x == 0))
{
throw new RegressionTestException("Contracts received didn't have valid open interest values.");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 47132;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "0"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "0%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "100000"},
{"Net Profit", "0%"},
{"Sharpe Ratio", "0"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "0%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0"},
{"Beta", "0"},
{"Annual Standard Deviation", "0"},
{"Annual Variance", "0"},
{"Information Ratio", "-5.732"},
{"Tracking Error", "0.05"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -0,0 +1,31 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
/// Reproduces GH issue #8421.
/// </summary>
public class DailyOptionChainOpenInterestDataWithoutStrictDailyEndTimesRegressionAlgorithm : DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm
{
public override bool DailyPreciseEndTime => false;
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 46264;
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Tests indicator behavior when "DailyPreciseEndTime" is disabled,
/// ensuring updates occur at midnight and values remain consistent.
/// </summary>
public class DailyResolutionVsTimeSpanNoPreciseEndRegressionAlgorithm : DailyResolutionVsTimeSpanRegressionAlgorithm
{
// Disables precise end time, considering the full day instead.
protected override bool DailyPreciseEndTime => false;
protected override void SetupFirstIndicatorUpdatedHandler()
{
RelativeStrengthIndex1.Updated += (sender, data) =>
{
var updatedTime = Time;
// RSI1 should update at midnight when precise end time is disabled
if (updatedTime.TimeOfDay != new TimeSpan(0, 0, 0))
{
throw new RegressionTestException($"{RelativeStrengthIndex1.Name} must have updated at midnight, but it was updated at {updatedTime}");
}
// Since RSI1 updates before RSI2, it should have exactly one extra sample
if (RelativeStrengthIndex1.Samples - 1 != RelativeStrengthIndex2.Samples)
{
throw new RegressionTestException("RSI1 must have 1 extra sample");
}
// RSI1's previous value should match RSI2's current value, ensuring consistency
if (RelativeStrengthIndex1.Previous.Value != RelativeStrengthIndex2.Current.Value)
{
throw new RegressionTestException("RSI1 and RSI2 must have same value");
}
};
}
public override void OnEndOfAlgorithm()
{
if (RelativeStrengthIndex1.Current.Value != RelativeStrengthIndex2.Current.Value)
{
throw new RegressionTestException("RSI1 and RSI2 must have same value");
}
if (RelativeStrengthIndex1.Samples <= 20 || RelativeStrengthIndex2.Samples != RelativeStrengthIndex1.Samples)
{
throw new RegressionTestException("The number of samples must be the same and greater than 20");
}
}
}
}

View File

@@ -0,0 +1,210 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the behavior of indicators with different update mechanisms based on resolution and time span.
/// </summary>
public class DailyResolutionVsTimeSpanRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
protected Symbol Spy { get; set; }
protected RelativeStrengthIndex RelativeStrengthIndex1 { get; set; }
protected RelativeStrengthIndex RelativeStrengthIndex2 { get; set; }
protected virtual bool DailyPreciseEndTime => true;
public override void Initialize()
{
InitializeBaseSettings();
Settings.DailyPreciseEndTime = DailyPreciseEndTime;
// First RSI: Updates at market close (4 PM) by default
// If DailyPreciseEndTime is false, updates at midnight (12:00 AM)
RelativeStrengthIndex1 = new RelativeStrengthIndex(14, MovingAverageType.Wilders);
RegisterIndicator(Spy, RelativeStrengthIndex1, Resolution.Daily);
// Second RSI: Updates every 24 hours (from 12:00 AM to 12:00 AM) using a time span
RelativeStrengthIndex2 = new RelativeStrengthIndex(14, MovingAverageType.Wilders);
RegisterIndicator(Spy, RelativeStrengthIndex2, TimeSpan.FromDays(1));
// Warm up indicators with historical data
var history = History<TradeBar>(Spy, 20, Resolution.Daily).ToList();
foreach (var bar in history)
{
RelativeStrengthIndex1.Update(bar.EndTime, bar.Close);
RelativeStrengthIndex2.Update(bar.EndTime, bar.Close);
}
if (!RelativeStrengthIndex1.IsReady || !RelativeStrengthIndex2.IsReady)
{
throw new RegressionTestException("Indicators not ready.");
}
SetupFirstIndicatorUpdatedHandler();
SetupSecondIndicatorUpdatedHandler();
}
protected virtual void InitializeBaseSettings()
{
SetStartDate(2013, 01, 01);
SetEndDate(2013, 01, 05);
Spy = AddEquity("SPY", Resolution.Hour).Symbol;
}
/// <summary>
/// Event handler for the first RSI indicator
/// Validates update timing and sample consistency
/// </summary>
protected virtual void SetupFirstIndicatorUpdatedHandler()
{
RelativeStrengthIndex1.Updated += (sender, data) =>
{
var updatedTime = Time;
// Ensure RSI1 updates exactly at market close (4 PM)
if (updatedTime.TimeOfDay != new TimeSpan(16, 0, 0))
{
throw new RegressionTestException($"RSI1 must have updated at 4 PM, but it updated at {updatedTime}.");
}
// Since RSI1 updates before RSI2, it should have one extra sample
if (RelativeStrengthIndex1.Samples - 1 != RelativeStrengthIndex2.Samples)
{
throw new RegressionTestException("First RSI indicator should have exactly one more sample than the second indicator.");
}
// RSI1's previous value should match RSI2's current value, ensuring consistency
if (RelativeStrengthIndex1.Previous.Value != RelativeStrengthIndex2.Current.Value)
{
throw new RegressionTestException("RSI1 and RSI2 must have same value");
}
// RSI1's and RSI2's current values should be different
if (RelativeStrengthIndex1.Current.Value == RelativeStrengthIndex2.Current.Value)
{
throw new RegressionTestException("RSI1 and RSI2 must have different values");
}
};
}
/// <summary>
/// Event handler for the second RSI indicator
/// Validates update timing and sample consistency
/// </summary>
protected virtual void SetupSecondIndicatorUpdatedHandler()
{
RelativeStrengthIndex2.Updated += (sender, data) =>
{
var updatedTime = Time;
// RSI2 updates at midnight, ensure the update time is correct
if (updatedTime.TimeOfDay != new TimeSpan(0, 0, 0))
{
throw new RegressionTestException($"RSI2 must have updated at midnight, but it was updated at {updatedTime}");
}
// Since RSI2 updates later, it must now have the same number of samples as RSI1
if (RelativeStrengthIndex1.Samples != RelativeStrengthIndex2.Samples)
{
throw new RegressionTestException("RSI1 must have same number of samples as RSI2");
}
// At this point, RSI1 and RSI2 should have the same value
if (RelativeStrengthIndex1.Current.Value != RelativeStrengthIndex2.Current.Value)
{
throw new RegressionTestException("RSI1 and RSI2 must have same value");
}
};
}
public override void OnEndOfAlgorithm()
{
if (RelativeStrengthIndex1.Samples <= 20)
{
throw new RegressionTestException("The number of samples must be greater than 20");
}
if (RelativeStrengthIndex1.Samples <= 20)
{
throw new RegressionTestException("The number of samples must be greater than 20");
}
}
/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
public bool CanRunLocally { get; } = true;
/// <summary>
/// This is used by the regression test system to indicate which languages this algorithm is written in.
/// </summary>
public List<Language> Languages { get; } = new() { Language.CSharp };
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 50;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 20;
/// <summary>
/// Final status of the algorithm
/// </summary>
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
/// </summary>
public 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", "-38.725"},
{"Tracking Error", "0.232"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

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