Add contract days_to_expiry/dte and interpret Python date/datetime type errors - #9665
Closed
jhonabreul wants to merge 1 commit into
Closed
Add contract days_to_expiry/dte and interpret Python date/datetime type errors#9665jhonabreul wants to merge 1 commit into
jhonabreul wants to merge 1 commit into
Conversation
… errors - BaseContract.DaysToExpiry(reference)/DTE on option and future contracts; from Python the reference accepts both datetime and date instances - UnsupportedOperandPythonExceptionInterpreter also interprets the datetime-vs-date comparison TypeError and appends a hint pointing at .date() alignment and days_to_expiry/dte for the datetime-date shapes - New TzInfoPythonExceptionInterpreter for TimeZones values passed as Python tzinfo, pointing at zoneinfo; AlgorithmImports imports ZoneInfo - New GenericTypeParameterPythonExceptionInterpreter for pythonnet's 'type(s) expected' when parameterizing generics with Python types - ContractDaysToExpiryRegressionAlgorithm (C# + Python) and unit tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
Superseded: this surface is already addressed by pythonnet PR #143 (datetime/date coercion at the interop layer). Closing per review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Python algorithms constantly mix .NET-converted
datetimevalues (self.time,contract.id.date, expiries) with pure Pythondateobjects, and die on DTE math — the single most repeated runtime arithmetic failure across user deployments:The change:
BaseContract.DaysToExpiry()/DaysToExpiry(DateTime reference)andBaseContract.DTEon option and future contracts (contract.days_to_expiry(reference)/contract.dtein Python): whole days between the reference date (default: the contract's currentTime) andExpiry, date parts only. From Python the reference accepts bothdatetimeanddateinstances (pythonnet converts either), removing the need for the failing manual arithmetic.DTEis[PandasIgnore]d so dataframe shapes don't change.UnsupportedOperandPythonExceptionInterpreternow also interprets thecan't compare datetime.datetime to datetime.dateTypeError, and when the offending operands aredatetime.datetimevsdatetime.date(in either flavor) it appends a hint pointing at.date()alignment andcontract.days_to_expiry(reference)/contract.dte.TzInfoPythonExceptionInterpreter:datetime.now(TimeZones.NEW_YORK)now explains that Lean time zones are NodaTimeDateTimeZoneobjects and points atdatetime.now(ZoneInfo("America/New_York"))andZoneInfo(str(TimeZones.NEW_YORK)). It only fires when the rejected tzinfo type is aDateTimeZone.AlgorithmImportsnow importsZoneInfo(stdlibzoneinfo), so the hinted fix works without an extra import — this also preempts the observed follow-up failure of reaching forpytz, which is not imported either.GenericTypeParameterPythonExceptionInterpreter: pythonnet's baretype(s) expectedTypeError (e.g.RollingWindow[datetime](30)) now explains that Python types cannot parameterize .NET generics and points atRollingWindow[DateTime], the int/float/bool/str aliases, and the untypedRollingWindow(n).Related work: QuantConnect/pythonnet#143 makes converted
DateTimevalues coerce against puredateoperands at the interop layer; the interpreter hints here remain useful for pure-Python mixes (e.g. a stored plaindatetimevsself.time.date()) and until that package rolls out.Deferred (needs interop-layer changes, no Lean-side path):
RollingWindow[datetime]actually work: requires mapping Pythondatetime/datetypes toSystem.DateTimein pythonnet'sConverter.GetTypeByAlias(used byRuntime.PythonArgsToTypeArrayandClassObject.type_subscript), including theclr_datetimesubclass type introduced by Support subtraction and ordering between converted DateTime values and datetime.date pythonnet#143.TimeZones.NEW_YORKdirectly usable as a Pythontzinfo: a CLR-wrapped NodaTimeDateTimeZonecannot subclass Python'stzinfo; the new interpreter +ZoneInfoimport is the Lean-side answer.Related Issue
Part of QuantConnect/Agents#305 (improvement #6: unify date/datetime across the expiry/time surface)
Motivation and Context
DTE filtering is line one of nearly every options/futures selector users write; fleet evidence shows the same failing line reinvented across many deployments, plus a three-error timezone chain (
TimeZonesas tzinfo →pytznot defined → naive-vs-aware compare) that burned three backtests per step.Requires Documentation Change
Yes: document
days_to_expiry(reference)/dteon option and future contracts, and thatZoneInfois available in algorithms.How Has This Been Tested?
ContractDaysToExpiryRegressionAlgorithm(C# + Python twins): validatesDaysToExpiry()/DTEagainst manual expiry math on every chain contract; the Python twin additionally passesdatetime,dateand keyword references. Both language runs pass with identical statistics.OptionContractTests/FuturesContractTests:DaysToExpirywith default and explicit references, plus a Python-engine test bindingdays_to_expirywithdate,datetimeandreference=arguments.UnsupportedOperandPythonExceptionInterpreterTests: real Python TypeErrors for subtraction and comparison shapes get the hint; non-datetime operands and naive-vs-aware compares do not.TzInfoPythonExceptionInterpreterTests/GenericTypeParameterPythonExceptionInterpreterTests: real exceptions fromdatetime.now(TimeZones.NEW_YORK)andRollingWindow[datetime](10); a string tzinfo is not interpreted.QuantConnect.Tests.Common.Exceptions+QuantConnect.Tests.Common.Data.Marketnamespaces: 211 passed, 0 failed.ZoneInfopath verified after.Types of changes
Checklist:
bug-<issue#>-<description>orfeature-<issue#>-<description>