Skip to content

Add Price, Value and Close aliases to BaseContract#9578

Merged
jhonabreul merged 5 commits into
QuantConnect:masterfrom
jhonabreul:feature-basecontract-price-value-close
Jul 2, 2026
Merged

Add Price, Value and Close aliases to BaseContract#9578
jhonabreul merged 5 commits into
QuantConnect:masterfrom
jhonabreul:feature-basecontract-price-value-close

Conversation

@jhonabreul

Copy link
Copy Markdown
Collaborator

Description

Adds Price, Value and Close properties to BaseContract (inherited by OptionContract and FuturesContract) as aliases of the existing LastPrice property. This makes contracts mimic the familiar BaseData/TradeBar price API without inheriting BaseData — a contract is an aggregator over several concurrent data streams (trade/quote bars, ticks, open interest, universe data, option price model), not a single data point, so inheriting BaseData would be conceptually wrong and would drag in Reader/GetSource/Clone and the ProtoBuf serialization contract.

The new properties are virtual and marked [PandasIgnore] so they compose with each contract's existing LastPrice override and do not add duplicate columns to the option/future chain DataFrames (mirroring how BaseData tags its own Value/Price).

Related Issue

N/A

Motivation and Context

Users expect to be able to read contract.Price, contract.Value and contract.Close the same way they do on data/bars, for a consistent API surface across contracts and other data types.

Requires Documentation Change

No.

How Has This Been Tested?

Added unit tests asserting Price == Value == Close == LastPrice for both OptionContract and FuturesContract, before any data (all zero) and after a trade-bar update. New OptionContractTests fixture and a new case in FuturesContractTests. Built the Tests project in Release (0 errors) and ran both fixtures — all 10 tests pass.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My branch follows the naming convention bug-<issue#>-<description> or feature-<issue#>-<description>

Expose Price, Value and Close on BaseContract as aliases of LastPrice to
mimic the BaseData/TradeBar API without inheriting BaseData. Marked with
PandasIgnore to avoid duplicating the LastPrice column in chain DataFrames.
The pandas converter force-includes the 'Value' member for non-Lean-data
types (to preserve the value column of custom data types despite
BaseData.Value being PandasIgnore'd). That override made the new
BaseContract.Value alias leak into option/future chain DataFrames as a
redundant 'value' column. Exclude BaseContract-derived types from the
forced inclusion so their PandasIgnore'd aliases are honored and the
chain DataFrames stay unchanged.
OptionContract's default option data is the shared static
OptionPriceModelResultData.Null singleton, which other tests mutate via
Update. Reading LastPrice before setting up the contract's own data made
the assertion depend on global test state (failing in CI with a leaked
price). Assign a dedicated price model so the contract no longer reads
from or writes to the shared singleton.
…red singleton

OptionContract initialized its option data to the shared static
OptionPriceModelResultData.Null singleton. Update() mutates that data, so
contracts without an explicit price model shared and clobbered each
other's trade/quote/open-interest state (a latent bug, and the cause of
order-dependent test failures). Each contract now gets its own default
OptionPriceModelResultData instance, and the alias test no longer needs
to work around the shared state.
Revert OptionContract back to the shared static OptionPriceModelResultData.Null
default. To keep the alias test deterministic, reset that singleton in the
fixture's SetUp by updating a throwaway contract with a zero-priced trade bar,
and give the tested contract its own price model so its Update doesn't
re-pollute the singleton.
@jhonabreul jhonabreul force-pushed the feature-basecontract-price-value-close branch from fd3986d to 0feb01c Compare July 1, 2026 22:40
@jhonabreul jhonabreul merged commit 1479a1e into QuantConnect:master Jul 2, 2026
7 of 8 checks passed
@jhonabreul jhonabreul deleted the feature-basecontract-price-value-close branch July 2, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants