Changelog
All notable changes to this project should be documented in this file.
The format is based on Keep a Changelog, and this project follows versioned releases.
[Unreleased]
[1.0.16] - 2026-09-12
Added
- Added explicit, vectorized
TargetWeightExecutionModelandInstrumentExecutionSpeccontracts for converting the configured signal and rebalance policy into simulated quantities, settlement legs, and restartable execution progress. - Added composable strategy-owned execution cost models and an offline linear perpetual fixture proving variation-margin settlement and pre-execution funding order.
Changed
- Routed opt-in position-aware portfolios through one coordinated
signal-to-
RebalanceStrategysimulation path while leaving the weight-onlyPortfolioRebalanceand commission path unchanged. - Included execution progress in canonical ledger restart state and made exact incremental retries publish no duplicate ledger tail.
- Refreshed the repository lock, exported requirements, and managed platform skills to Main Sequence SDK 8.1.11.
Removed
- Removed the external execution-fact source from position-aware Portfolio configuration and accounting. Portfolios accept no broker/Account execution ingress, compatibility alias, replay lane, or fallback.
Fixed
- Prevented floating-point noise at exact quantity-step boundaries from rounding a mathematically integral target down by one lot.
- Excluded explicitly closed zero-quantity positions from strict mark requirements while preserving their ledger and state rows.
Documentation
- Corrected ADR 0042 and the portfolio accounting guidance to enforce that a
Portfolio is a backtest model with no Account or broker execution inputs.
The configured signal and
RebalanceStrategyare the sole producer of internal simulated execution facts; issue #11 removes the external-execution ingress from1.0.15without a compatibility fallback.
[1.0.15] - 2026-09-12
Added
- Added the opt-in
PortfolioEngineand purePortfolioAccountingreducer, public directly injected lifecycle-event contracts, columnar event batches, explicit execution-fact conversion, and a built-in dividend entitlement and settlement model. - Added strict multi-currency position, cash, and obligation valuation through explicit price and FX observations, plus ledger-derived completed-cash-flow state, and normalized portfolio-value projections.
- Added strict reducer restart from a complete active ledger, including event digest, record-count, state-chain, and opening-configuration validation.
- Added
PortfolioEventLedgerStorage,PortfolioStateStorage, andPortfolioCashFlowsStoragewith provider migration0017. - Added offline EUR-dividend/USD-NAV and custom vectorized cash-flow examples.
Changed
- Added optional
PortfolioBuildConfiguration.accounting_configurationwhile omitting disabled accounting from legacy serialization. The legacyPortfoliosDataNoderejects enabled accounting instead of mixing histories or silently falling back to weight-only valuation.
Documentation
- Added a dedicated position-aware accounting guide covering engine ownership, configuration, execution/dividend/price/FX input grains, ledger records, retry and restart behavior, projections, custom lifecycle models, failure semantics, examples, and the explicit absence of an SDK blocker. Updated the repository portfolio-workflow skill with the same maintenance invariants.
[1.0.14] - 2026-09-09
Added
- Added the installable
msm.api.httpprovider adapter toolkit with strict Command Center collection, discovery, bulk-action preflight, structured error, and owner-scoped observable-operation contracts and helpers. - Added a provider-neutral HTTP contract example covering discovery metadata and operation creation.
Changed
- Moved the reusable
apps/v1resource and bulk-action implementations behind the publicmsm.api.httpimport boundary while retaining compatibility imports for the repository FastAPI app.
Documentation
- Documented provider adapter reuse, error sanitization, operation ownership, and the explicit single-process durability boundary of the bundled in-memory operation store.
[1.0.13] - 2026-09-09
Fixed
- Unified asset-scope mapping identity on canonical
asset_identifierand removedunique_identifierfallback behavior from mapping and object scopes, so inherited asset-indexed validation and portfolio calendar resolution enforce the same payload. Added regressions for #9. - Discarded out-of-range executed-weight seed rows and enforced unique
(time_index, asset_identifier)coordinates before portfolio weight pivots, while preserving one set-based seed lookup. Added regressions for #10.
Documentation
- Documented canonical mapping scopes and defensive portfolio seed validation in the asset guide, portfolio guide, tutorial, and equal-weight example.
[1.0.12] - 2026-09-08
Fixed
- Made strict portfolio valuation require fresh values only where the current or immediately preceding executed holding is nonzero. Unchanged zero-weight assets can remain in complete signal and weight snapshots without blocking valuation, while entry and exit observations remain mandatory. Added regressions that close #8.
Documentation
- Documented exposure-aware strict valuation in the portfolio guide, tutorial, and equal-weight example.
[1.0.11] - 2026-09-08
Fixed
- Preserved
open_time,first_trade_time,last_trade_time, and intradaytrade_dayas timezone-awaredatetime64[ns, UTC]values throughout price interpolation instead of round-tripping pandas 3 microsecond timestamps through unit-ambiguous integers. Added daily and intraday regressions that close #7. - Replaced the deprecated naive
datetime.utcnow()comparison in intraday interpolation with a timezone-aware UTC timestamp.
Documentation
- Documented the interpolated price timestamp contract and the required upgrade-before-scoped-replay order in the portfolio guide, tutorial, and equal-weight example.
[1.0.10] - 2026-09-08
Changed
- Raised the minimum, locked, and exported Main Sequence SDK dependency plus managed repository skill pin from 8.1.7 to 8.1.8.
Fixed
- Restored the complete SDK dimension-query contract on
AssetIndexedDataNode.get_last_observation(...)while retaining validated optional asset scoping. - Fixed portfolio seed observation reads to include complete multidimensional
coordinates such as
(signal_uid, asset_identifier)in one set-based backend request. Added concrete AssetIndexedDataNode regressions that close #6.
Documentation
- Documented the set-based asset seed-read contract in the asset, portfolio, tutorial, and equal-weight example surfaces.
[1.0.9] - 2026-09-08
Documentation
- Corrected the live README, getting-started guide, and FastAPI package contract documentation to state the required Main Sequence SDK 8.1.7 floor; the published dependency metadata already enforced that floor.
[1.0.8] - 2026-09-08
Added
- Added a source-backed trailing-average-daily-volume participation preview example that performs bounded, asset-filtered reads and reports execution quantities, remaining weights, and daily-cap consumption without persisting portfolio state.
Changed
- Raised the minimum, locked, and exported Main Sequence SDK dependency plus managed repository skill pin from 8.1.5 to 8.1.7 so portfolio configuration durations serialize deterministically during updater hashing.
Fixed
- Restored deterministic updater hashing and configuration reconstruction for
CalendarEventSignal.event_offsetandValuationAlignmentPolicy.maximum_stalenessby requiring Main Sequence SDK 8.1.7 or newer. - Added the repository root to pytest's configured import path so executable
examples can be imported by example-focused tests without shell-specific
PYTHONPATHsetup.
[1.0.7] - 2026-09-08
Added
- Added the generic
PortfolioRebalanceupdater andPortfolioRebalanceStateStorageledger for deterministic active-intent, partial-execution, remaining-target, event-provenance, and restart state. - Added
PortfolioCalendarEventsandPortfolioCalendarEventsStorageso calendar-relative strategies consume an explicit published schedule rather than reading or generating dates behind the dependency graph. - Added supported
TimeWeighted,VolumeParticipation, andLiquidityConstrainedstrategies driven by observed bars, volume, and available liquidity. - Added
TrailingAverageDailyVolumeParticipation, which estimates a bounded per-asset daily notional cap from completed historical daily VWAP and volume while executing only at observable intraday prices and volumes. - Added static migration
0016for calendar-event and rebalance-state storage; it also provisions the previously declared portfolio-analytics storage.
Changed
- Replaced the fixed
execution_timestamps(...)/apply_rebalance_logic(...)strategy API with declared dependencies, required input contracts, strategy-owned event selection, and deterministic per-event state transitions. This is a breaking portfolio execution contract change. - Added the optional
prepare_execution_context()strategy hook and indexed signal/event preparation so rolling inputs are computed once rather than rescanned for every event. - Converted
PortfolioWeightsfrom the strategy executor into a pure projection of rebalance-state events that changed executed allocations. - Updated the SDK lock, exported requirements, and managed repository skills to Main Sequence SDK 8.1.5.
Fixed
- Removed central assumptions that every rebalance strategy uses an immediate
signal, one execution valuation frame, or an optional column named
volume. New strategy categories can declare arbitrary typed observed inputs without changing portfolio valuation code. - Preserved unfinished volume- and liquidity-constrained work as
pendingorpartial, with explicit supersession when a newer signal arrives. - Prevented ex-post current-session VWAP from being treated as an execution price or eligible trailing-capacity observation. Daily participation usage now survives same-session restarts and target supersession.
Documentation
- Marked ADR 0040 implemented and updated the portfolio knowledge page, tutorial, and equal-weight example for the general strategy-driven rebalance graph.
- Documented the trailing daily-liquidity strategy and added a focused public configuration example.
[1.0.6] - 2026-09-07
Added
- Added
CalendarEventSignalwith hash-bearing calendar, session, event, offset, cadence, cutoff, and execution-valuation semantics. - Added
PortfolioAnalyticsand separatePortfolioAnalyticsStoragefor consumer-owned reporting resampling with explicit period boundaries and source-observation lineage. - Added a dry-run-first legacy portfolio timestamp repair that validates midnight rows against persisted calendar sessions, applies only a scoped inclusive tail rollback, and requires deterministic portfolio replay.
Changed
- Promoted
PortfolioWeightsto the execution/rebalance updater and madePortfoliosDataNodea valuation-only consumer of canonical executed weights. Canonical execution and valuation timestamps now originate only from signal, persisted calendar, execution-data, or valuation-source observations. - Made
CalendarEventSignal.calendar_identifierrequired and removed silent fallback from persisted calendar lookup to local pandas or synthetic calendars. Missing, ambiguous, and failed governed lookups now fail visibly. - Replaced portfolio-local price-grid controls with strict, bounded per-asset
ValuationAlignmentPolicyas-of selection. Portfolio configuration no longer acceptsportfolio_prices_frequencyorprice_alignment_policy. - Updated the Main Sequence SDK lock and managed repository skills to 8.1.4.
Fixed
- Chunked long-horizon persisted-calendar reads so daily price interpolation remains within governed operation limits.
- Resolved sparse per-asset valuation seeding, midnight relabeling and rerun duplication, and implicit calendar-event timing semantics tracked in issues #2, #3, and #4.
Removed
- Removed unfinished
TimeWeightedandVolumeParticipationstrategies from the supported public strategy surface until their bar-driven execution contracts are implemented.
Documentation
- Added and implemented ADR 0040, establishing separate temporal ownership for portfolio execution, valuation, and analytics.
[1.0.4] - 2026-09-05
Fixed
- Updated portfolio, asset-snapshot, holdings, virtual-fund, and pricing updater calls for the
Main Sequence SDK 8.1 execution contract.
PortfoliosDataNode.run()now forwards onlyupdate_tree,update_only_tree, andoverride_update_stats; the removed scheduler, debug, and force-update controls are no longer exposed or passed to the SDK runner.
[1.0.3] - 2026-09-04
Fixed
- Replaced the per-asset
AssetCategory.replace_memberships()write loop with one governed multi-row upsert followed by one scoped stale-membership delete. Duplicate asset UIDs are normalized before compilation, empty replacements execute one delete, and the public API returns every row from the bulk upsert. This closes #1.
Changed
- Raised the SDK 8 package floor and validated project lock to
mainsequence>=8.0.7, and refreshed the managed Main Sequence repository scaffold from SDK 8.0.7.
[1.0.2] - 2026-08-30
Fixed
- Aligned the FastAPI deployment-contract test with the backend-validated
workflow API
2.1.0declaration and its explicit three-revision retention policy.
[1.0.1] - 2026-08-30
Changed
- Released the first SDK-8-only
ms-marketsmajor version. Package metadata requiresmainsequence>=8.0.4without an exact SDK patch pin; SDK 6 and SDK 7 are unsupported and no compatibility aliases or mixed-version mode are provided. - Completed the SDK 8 hard cut: repository operations use the canonical
CodeRepository and CodeRepositoryBranch ontology, while updater,
configuration, and reference imports use the
mainsequence.meta_tablestime-index-table API, configuration schema version 2, canonical dependency actions, and read-only table references. - Updated
msm copy-msm-skillsfor the SDK 8 scaffold-copy contract and renamed its JSON target field fromprojecttocode_repository. - Completed OpenAPI documentation metadata for every FastAPI v1 operation and tag, added stable tag groups and the canonical source-repository link, documented the composed Asset schemas, and derived canonical row and field descriptions from existing MetaTable metadata so downstream API references do not maintain a duplicate schema-description inventory.
- Replaced every FastAPI v1 list response with the strict Command Center SDK
command-center.resource_collection@v1contract and added authoritativecommand-center.resource_discovery@v1siblings for all 25 collections. Removedresponse_format, DRF-style pagination, and standalone/bulk-actions/discovery paths; embedded authorized bulk actions in resource discovery; added canonical account and pricing-curve detail operations; and pinned conformance tests to the complete Command Center SDK0.1.13schema and fixture bundle. - Added port 3010 to the development-only FastAPI CORS wrapper so the static-site repository's VS Code full-stack debugger can run the local API on port 8001 and frontend on port 3010 together without changing production application middleware.
- Linked the automatically deployed Markets static site to the stable
mainFastAPI ResourceRelease identity and admitted the supportedhttps://*.site-dev.main-sequence.appbrowser origin. API redeployments now rotate behind the same release UID while the Command Center SDK resolves the current opaque RPC endpoint at request time. - Migrated the automatic
mainFastAPI deployment declaration to the current workflow API2.0.0contract and added regression coverage for every-commit redeployment without a caller-selected project image. - Added the canonical
api/main.pydeployment entrypoint for the existingapps/v1application so the platform can discover and automatically deploy the FastAPI resource without moving application logic out ofapps/v1. Added.mainsequence/workflows/fastapi.yamlto redeploy that release on every synchronized commit, and replaced the machine-local Main Sequence SDK source override with the publishedmainsequence==6.0.35package so remote image builds can resolve the dependency. - Added Command Center SDK bulk-action discovery, preflight, and canonical
execution contracts for asset categories, portfolios, and portfolio groups.
Execution now accepts
{selection, options}, rejects the retired FastAPI bulk payloads, and rechecks missing rows and protected portfolio references immediately before deletion. - Restricted the project runtime to Python 3.13, upgraded the Main Sequence SDK,
removed the obsolete SDK upper-version cap, rebuilt the uv lock and local
environment on Python 3.13, and moved documentation and package-publish
workflows to Python 3.13. Refreshed the installed SDK, dependency lock, and
managed Main Sequence skills to
6.0.36. - Replaced the Index calculation architecture with strict
formulaandcustommethods. Formula expressions use typed Asset/Index identifiers, exact source MetaTable UIDs and observables, an allow-listed arithmetic parser, immutable validity versions, exact or bounded backward as-of alignment, and deterministic DataNode dependencies. AddedFormulaIndex, formula catalog routes, mixed-source and Portfolio-to-custom examples, and revision0015; removed operator/leg/resolved-leg registries, observation units, stateful Index performance operators, and all compatibility aliases. Asset and Index now sharelist_related_meta_tables(uid, numeric=True, timestamped=True)and equivalent FastAPI routes backed by paginated, authoritative-FK catalog discovery. Added the immutable PydanticIndexFormulacontract for historical evaluation of caller-supplied Series or DataFrames without a persisted Index or formula-definition UID. - Removed the untyped
Index.providerattribute and its database index through revision0014. Index create/update payloads, catalog search, ordering, FastAPI filtering, detail badges, examples, and OpenAPI no longer expose it, and legacy payloads containingproviderare rejected rather than accepted through a compatibility shim. Source-native facts such as OpenFIGI details remain in their structured metadata payloads. - Hardened the Index catalog and publication path.
Revision
0013adds rebuildable per-Index dataset availability metadata, a historical one-active-definition invariant, and identifier-first canonical lookup indexes. List filters use indexed availability predicates; dataset lists expose populated, compatible-empty, and unavailable states; direct delete impact is typed without a custom deletion workflow; and producers use post-persistence reconciliation. - Replaced asset-biased curve key-node identity with typed
source_reference={"type": "asset" | "index", "identifier": "..."}provenance. Added the sharedFixedIncomeCurveKeyNodebase across deposit, OIS, futures, bond, FX, and cross-currency basis helper models, updated the reconstruction example to demonstrate asset- and index-sourced inputs, and rejected top-levelasset_identifier/index_identifierkey-node fields. - Changed floating-rate bond and swap pricing to resolve projection and
discount curves independently through market-data-set curve bindings.
Projection curves build floating indexes and forecast coupons; discount
curves feed QuantLib discounting engines. The floating bond example, tutorial,
and pricing docs now demonstrate separate projection and discount curves.
Both role bindings must exist even when they point to the same physical
curve_uid. - Changed
MSDataInterface.get_historical_discount_curve_observations(...)to read multi-curve latest-as-of observations through a backend window query instead of scanning full curve history into pandas. - Changed asset snapshot enrichment services to resolve latest rows through backend queries instead of scanning history and choosing the latest row in Python.
- Removed the legacy
MSDataInterfaceprocess-wide latest-observation environment flag; callers must use explicit latest-curve APIs or bounded historical reads. - Added
msm_pricing.pricing_engine.apply_z_spread_to_curve(...)for strict runtime z-spread overlays that matchBond.z_spread(...)'s continuous decimal spread convention without mutating persisted curve observations. - Added
PreparedInstrument.z_spread(...)so valuation-context prepared instruments propagate the selected market-data set and curve quote side when solving z-spreads. - Added
msm_pricing.valuation.build_valuation_position(...)for strict construction of transient valuation baskets from normalized instrument/unit rows. - Added reusable
latest_portfolio_weights(...),portfolio_values(...), andasset_reference_details(...)services for package-owned portfolio output and asset reference reads. - Added
msm_pricing.scenarios.curveswith typed curve scenario models, key-node basis-point bump helpers, runtime scenario curve-handle construction, andprice_curve_scenario(...)delegation to the preparedprice_scenario(...)path. - Added
price_resolved_curve_scenario(...),prepare_resolved_curve_scenario_runtime_overrides(...), andLineCurveResolutionInputfor caller-resolved curve scenarios that already have explicit base/scenario handles per valuation line, with selected base/scenario handle maps exposed for downstream analytics/reporting reuse. - Added
msm_pricing.scenarios.valuationwith typed valuation scenario workflow orchestration, partial-success line pricing, line/carry impacts, optional analytics and cashflows, observed dirty-price z-spread overlays, and an offline workflow example. - Added
msm_pricing.analytics.spreadswith cross-asset spread primitives, fixed-income DV01 spread metrics, optional dependency diagnostics, and an offline fixed-income spread analytics example. - Added
msm_pricing.pricing_engine.curveswith generic QuantLib rate-helper specs/builders, helper-key-node adapters, helper-based curve reconstruction, and curve observation export, plus resolver/scenario support forbuilder_type="rate_helper_curve"without importing connector-specific code. - Extended generic OIS helper reconstruction to expose QuantLib OIS
schedule/convention fields and to require persisted
builder_payload.helper_schema="rate_helpers@v1"for helper-based curve adapters. - Added generic interest-rate futures helper reconstruction with
sofr_future_rate_helperkey-node support and explicit futures price-unit validation. - Added generic zero-coupon and fixed-rate bond helper reconstruction under
msm_pricing.pricing_engine.curves, including bond-helper key-node parsing,rate_helpers@v1reconstruction support, observation export tests, and strict diagnostics for unsupported yield shocks on price-quoted bond helpers. - Added generic cross-currency helper reconstruction under
msm_pricing.pricing_engine.curves, including FX swap helpers, constant-notional cross-currency basis helpers, context/provenance nodes under the existingrate_helpers@v1schema, explicit FX forward-points and basis-spread normalization,JointCalendardecoding, runtime dependency resolvers, and stable helper quote-error diagnostics. - Added
BondInstrumentTermsandbuild_bond_instrument_from_terms(...)for provider-neutral construction of existing zero-coupon, fixed-rate, and floating-rate bond instrument models without source-row parsing or connector dependencies. - Added
CurveObservationExportConfig.from_curve_building_details(...)so helper-reconstructed curves can export compounded annual zero-rate nodes with explicit front-node days and pillar-date inclusion, using term-structure reconstruction functions when QuantLib pillar dates are required. - Extended
price_curve_scenario(...)to forwardovernight_indexandovernight_index_resolverinto helper-reconstructed scenario curve builds. - Updated swap and floating-bond scenario repricing to use explicit
reset_curves(projection_curve=..., discount_curve=...)role handles. - Added
get_many_by_unique_identifier(...)on typed row APIs such asAssetfor batch canonical-identifier resolution. - Added reusable
command_centerhelpers for ms-markets Command Center tabular frames and Asset Monitor workspace documents, plus theapps/v1getAssetMonitorFramereference endpoint. - Added project-local namespace defaults for ms-markets extension models through
__metatable_namespace__plus__markets_base_identifier__, while keepingMSM_AUTO_REGISTER_NAMESPACEas the test/example override. - Added
msm_pricing.api.add_many_pricing_details(...)andAssetPricingDetails.add_many(...)for chunked bulk persistence of asset/instrument pricing details. - Changed pricing-detail batch writes to set per-operation SDK
max_rowslimits from the submitted chunk size instead of carrying a local response pagination loop. - Removed the obsolete pricing schema-creation bootstrap entrypoint; pricing
startup now uses the attach-only
msm_pricing.bootstrap.attach_pricing_schemas(...)API. - Removed the unused
msm_pricing.streamlithelper package and thepricing-streamlitoptional extra. - Added ADR 0033 to document the pricing valuation-position boundary and the
planned replacement for the legacy in-memory
Positionsurface. - Added ADR 0035 to document the target pricing curve identity model, curve building details, and market-data-set curve binding layer.
- Added ADR 0036 to document the prepared pricing valuation context target, including the requirement that portfolio/scenario valuation use bulk SQLAlchemy-backed resolution instead of hiding per-line backend lookup loops behind a public API, and that prepared instruments are copied or wrapped rather than mutating caller-owned instrument objects.
- Added an implementation task plan for reusable valuation input construction, portfolio and asset read services, curve-keyed scenario pricing, and optional fixed-income spread analytics without copying project-local adapter code into the library.
- Added an implementation task plan for upstreaming generic curve
reconstruction and observation export machinery from Valmer connector code
into
msm_pricing.pricing_engine.curves. - Implemented
PricingValuationContextwith a publicPreparedInstrumentwrapper, frozenPricingValuationContextSpecinput contract, fixed prepared-instrument universe, package-level exports, context-awareValuationPositionmethods,price_scenario(...), set-based row API helpers for pricing market-data bindings, index rows, index convention details, curve bindings, curves, and curve-building details, bulk curve/fixing observation reads, context-owned QuantLib curve handles/indexes, hot-loop resolver injection for prepared floating-rate bond pricing, and a runnable mock curve/fixing valuation-context example. - Implemented ADR 0035 phase-one pricing curve infrastructure with
CurveBuildingDetails,PricingMarketDataSetCurveBinding, nullable legacyCurve.index_uid, resolver cutover to explicit curve bindings, and Alembic revision0007. - Replaced the legacy in-memory
msm_pricing.Positionexport withValuationLineandValuationPositionfor explicit instrument-plus-units valuation. - Added
msm_pricing.api.load_instruments_from_assets(...)for chunked current-instrument loading from asset rows, and documented the account and portfolio normalization boundary for valuation baskets. - Added
MSDataInterface.get_latest_discount_curve(...)for explicit latest discount-curve lookup by curve identity. - Added
DiscountCurvesStorage.key_nodesand rowmetadata_jsoncolumns, withkey_nodestreated as producer-owned JSON construction provenance at publisher/API boundaries and compressed text at rest. - Added the optional
msm_pricing.data_nodes.CurveKeyNodehelper as the recommended key-node shape, including raw quote fields and yield-nativeyieldserialization for discount-curve producers. - Added
DiscountCurvesNode.normalize_key_nodes(...)andset_key_nodes_validator(...)so curve DataNode producers can enforce source-specific key-node provenance schemas without tightening the shared storage contract. - Tightened
DiscountCurvesStorage.curveto a required non-null payload and made discount-curve builders reject missing, null, or empty curve mappings. - Added observation-level discount-curve reads carrying
nodes,key_nodes, andmetadata_json, and exposed those provenance fields in the pricing curve API response. - Refactored the
migrations:migrationprovider, Alembic environment, model registry, and dynamic portfolio example provider onto the SDK-owned MetaTable migration helpers, with revision directories treated as generated Alembic output rather than pre-existing documentation state. - Renamed account allocation APIs and schemas around their actual domain:
AccountModelPortfoliobecameAccountAllocationModel,AccountTargetPortfoliobecameAccountTargetAllocation, and the related fields now useaccount_allocation_model_uidandaccount_target_allocation_uid. - Moved
PortfolioTableidentity and account target-position storage into coremsm;msm_portfoliosnow owns portfolio calculation workflows, while coremsmowns virtual-fund identity, virtual-fund holdings storage, and account allocation planning. - Added the account holdings to virtual-fund allocation planner with
proportional_attributionandstrict_feasiblepolicies, plus an apply step that converts feasible plans intoVirtualFundHoldingsStorageframes. - Extended the account virtual-fund planner with deterministic
position_set_uidinput resolution, notional target conversion through the valuation resolver, deterministic virtual-fund identity helpers, and resolver-level tests plus a dry-run-first account virtual-fund allocation example. - Moved virtual-fund knowledge documentation under the Accounts section as a standalone account allocation document.
- Reorganized DataNode storage contracts by concept: account storage now lives
under
msm.data_nodes.accounts, asset storage undermsm.data_nodes.assets, execution storage undermsm.data_nodes.execution, and portfolio/pricing storage under their matching concept packages. - Renamed the one-pass account and portfolio example to
examples/msm/accounts/account_portfolio_full_workflow.pyand moved the PyCharm run configuration under Accounts because the workflow prepares the reusable portfolio sleeve and then publishes account target positions and holdings. The same full workflow now exposes the virtual-fund allocation extension through dry-run and apply flags. - Added the
apps/v1target-allocation candidate search endpoint for account target-position assignment, returning one paginated asset and portfolio candidate list backed by a compiled MetaTable read. - Added the
apps/v1account target-position write endpoint, deriving parent allocation rows from the account uid and replacing target-position snapshots through one scoped MetaTable upsert operation. - Tightened account target-position validation so portfolio target rows cannot
use
single_asset_quantity. - Tightened
PortfoliosDataNode.run(update_pointers=True)so portfolio pointer updates use explicit DataNodeUpdate UIDs, preserve the existing executed weights pointer when no new weights are produced, and no longer cache a hiddenPortfolioWeightshelper on the portfolio node. - Changed portfolio update-window calculation so the start date comes from this
portfolio's own
PortfoliosStorage.portfolio_identifier, and valuation-source coverage is applied only after reading the actual signal frame. - Added the
apps/v1pricing curve registry list endpoint backed bymsm_pricing.api.Curveand the shared limit-offset pagination envelope. - Added the
apps/v1index delete-impact preflight endpoint so clients can inspect restrictive dependencies, cascade effects, and SET NULL effects before calling the individual index delete route. - Added the FastAPI v1 reusable delete-impact contract and migrated the index
preflight route to the shared
DeleteImpactResponseserializer before additional delete routes copy the index-specific shape. - Added the FastAPI v1 curve-selection reverse lookup endpoint for pricing
curves, removed the curve list
index_uidfilter, and changed index delete-impact to countPricingMarketDataSetCurveBindingindex selectors. - Clarified missing discount-curve API errors so a curve with registry and
market-data binding but no published
DiscountCurvesStorageobservations is reported as missing data, not a generic latest-observation lookup failure. - Changed pricing curve construction to honor
CurveBuildingDetails.interpolation_methodwith native QuantLib curve constructors and reject deprecated methods such aslog_linear_zeroandMonotonicLogCubicDiscountCurve. - Promoted virtual-fund allocation strategy to the first-class
VirtualFundHoldingsStorage.allocation_strategycolumn; low-level explicit publications writeexplicit, and planner-applied rows write the allocation policy mode. - Refactored portfolio construction to consume an explicit
valuation_source_instanceinstead of havingPortfoliosDataNodeconstructInterpolatedPricesfrom portfolioAssetsConfiguration/PricesConfiguration, and updated the equal-weight portfolio example to show the explicit source valuations -> interpolation when needed -> signal -> portfolio dependency graph. - Replaced deprecated builder terminology with portfolio construction wording across README, portfolio docs, ADRs, and internal portfolio logger helper names.
- Changed core portfolio storage identity so portfolio weights, values, FastAPI
latest-weight reads, delete cleanup, and account virtual-fund expansion use
PortfolioTable.unique_identifierasportfolio_identifier; optionalpublished_index_uidremains publication metadata only. - Added nullable
PortfolioTable.signal_uidas a foreign-key pointer toSignalMetadataTable.signal_uid; portfolio workflow pointer updates now persist the resolved signal UID, and portfolio signal-weight API reads use that first-class pointer instead of inferring from shared storage. - Changed portfolio core construction to consume
valuation_source_instanceplus arbitraryvaluation_column: str, replacing the OHLC-boundprice_source_instanceandPriceTypeNamesprice-column contract while keeping bar-specific helpers in contributed price workflows. - Added core portfolio group MetaTables, typed row helpers, FastAPI v1 routes,
docs, examples, and tests for many-to-many portfolio classification through
PortfolioGroupTableandPortfolioGroupMembershipTable. - Extended the full account portfolio example to assign the generated target
sleeve portfolio to an example
PortfolioGroupthrough the public portfolio group API. - Changed portfolio execution to raise a clear calendar materialization error when the rebalance calendar has no sessions for the requested update range, instead of reporting a misleading empty portfolio-weight no-op.
- Changed
msm copy-msm-skillsto delegate its filesystem copy mechanics to the Main Sequence SDK scaffold-skill helper while keeping the same public command UX. Successful copies now write.agents/skills/ms_markets/PINNED_FROM.txt.
Fixed
- Fixed the
apps/v1asset-category detail endpoint soresponse_format=frontend_detailreturns membership-backed detail metadata, includingnumber_of_assetsand the nested asset-listcategories__uidfilter, instead of a bareAssetCategoryrow. - Fixed category-filtered asset lists so
categories__uidresolves membership asset UIDs directly instead of filtering only the first scanned asset page. - Fixed portfolio value row normalization so
PortfoliosDataNoderesolves a real portfolio identifier instead of stringifying its_unique_identifiermethod, and declared thePortfoliosStorage.portfolio_identifierforeign key toPortfolioTable.unique_identifier. - Reworked pricing-details writes so user-facing instrument attachment upserts
AssetPricingDetailsStorage; calls withoutpricing_details_dateusenow()and updateAssetCurrentPricingDetailsTable, while calls with an explicit date upsert only that timestamped snapshot. - Clarified account and portfolio example console output with section titles, corrected portfolio workflow step numbering, and cleaner virtual-fund allocation frame rendering.
- Fixed account virtual-fund planning for portfolio targets so portfolio
sleeves expand from the latest
PortfolioWeightsStoragesnapshot at or before valuation time instead of requiring exact timestamp equality. - Normalized
InterpolatedPrices.update()output time indexes and timestamp columns back todatetime64[ns, UTC]so backend-read microsecond timestamps do not fail SDK DataNode update validation. - Fixed the equal-weight portfolio schema-preparation workflow so it derives the
dynamic revision from the active migration namespace and runs the dynamic
provider upgrade before
--run-after, even when a stale metadata row already exists for the configured interpolation table. - Fixed
PortfoliosDataNodeforced reruns when the latest stored portfolio value is already ahead of usable valuation-source coverage; the portfolio update now returns no new rows before calling calendar scheduling with a reversed date range. - Fixed
ImmediateSignalso portfolio valuation sources only need the configured valuation column; missingvolumenow produces nullable portfolio-weight volume fields instead of failing the rebalance calculation. - Fixed
msm_pricing.api.add_pricing_details(...)so omittingpricing_details_datedelegates the no-date current-update behavior toAssetPricingDetails.add(...)instead of pre-filling a timestamp too early. - Fixed explicit-date pricing detail writes so current pricing details are updated when no current row exists, when the new date is newer than current, or when the same timestamp is being replaced.
- Fixed portfolio update-window selection so source valuation coverage is evaluated only for assets required by the portfolio, instead of taking the oldest progress timestamp across every asset in a large upstream valuation table.
- Fixed portfolio update-window selection for
APIDataNodevaluation sources by loading the API source table update statistics before required asset progress is evaluated. - Made portfolio update-window selection strict when no required asset scope can be determined, instead of falling back to table-wide source progress.
- Fixed portfolio output progress lookup so a shared
PortfoliosStoragetable-wide max from anotherportfolio_identifiercannot move the current portfolio's update start date. - Fixed contributed portfolio signal cursors so shared
SignalWeightsStorageprogress from anothersignal_uidcannot move the current signal's source window.
Removed
- Removed the internal markets MetaTable catalog table, generic
/api/v1/catalogroutes, catalog service layer, and migration catalog refresh hooks. Runtime attachment now stays on direct backendMetaTable/TimeIndexMetaTablelookup by SQLAlchemy table name.
[0.0.39] - 2026-06-06
Highlights
- Split the library into clear package boundaries:
msmfor core market data,msm_portfoliosfor portfolio and virtual-fund workflows, andmsm_pricingfor pricing instruments, pricing market data, curves, fixings, and QuantLib-backed engines. - Completed the storage-first DataNode architecture: DataNode outputs are now
backed by
PlatformTimeIndexMetaTablestorage classes, with schema, dtypes, index grain, metadata, and foreign keys owned by SQLAlchemy/SDK table contracts instead of DataNode-side mirrors. - Moved MetaTable schema lifecycle to the SDK-managed Alembic provider flow and made runtime startup attach to already-registered tables by physical table name rather than using the maintenance catalog as runtime control.
- Reworked portfolio examples into explicit schema-preparation and runtime stages so configured interpolation storage is registered before normal portfolio execution.
- Added cohesive account, asset, portfolio, and pricing documentation, examples, and packaged agent skills that reflect the current package boundaries.
Changed
- Reorganized examples under
examples/msm/,examples/msm_portfolios/, andexamples/msm_pricing/; reorganized knowledge docs under the same package boundaries. - Standardized asset extension naming: public API rows use domain names such as
Bond,Future, andCurrencySpot, while one-to-one MetaTables use<Domain>AssetDetailsTablewithasset_uidas the primary key and FK toAssetTable.uid. - Normalized asset-indexed storage identity columns to explicit names such as
asset_identifier,index_identifier,curve_identifier, andportfolio_identifier, while preserving unique MetaTable business keys such asAssetTable.unique_identifier. - Updated markets, portfolio, and pricing bootstraps to use
start_engine(...)as the public runtime attachment surface. - Replaced deprecated SDK foreign-key helper declarations with normal
SQLAlchemy
ForeignKey(...)declarations. - Added inline SQLAlchemy column labels and descriptions across built-in MetaTables and storage tables.
- Reworked accounts around
Account,AccountGroup,AccountAllocationModel,AccountTargetAllocation,PositionSet, and storage-backed holdings and target positions. - Reworked virtual funds as account-owned allocation views instead of synthetic asset rows.
- Reworked pricing market-data configuration around UID-backed market-data sets and bindings, plus index convention details, index fixings, and curve rows.
- Moved QuantLib pricing engine code under
msm_pricing.pricing_enginesomsm_pricing.modelsremains MetaTable-only. - Raised the Main Sequence SDK dependency floor to
mainsequence>=4.3.8.
Fixed
- Fixed runtime table attachment to resolve
MetaTableandTimeIndexMetaTableresources through POST body filters on physical table names. - Fixed configured
InterpolatedPricesstorage identity so schema preparation and runtime construction derive the same dynamic table from registered source TimeIndexMetaTable UID, source cadence, upsample frequency, and interpolation rule. - Fixed stale source-cadence handling in the equal-weight portfolio schema-preparation workflow.
- Fixed string asset scopes in
InterpolatedPrices.update()so portfolio configurations using asset identifiers work consistently. - Fixed account holdings validation for signed quantity exposure through
quantity * direction. - Blocked
msm copy-msm-skills --path .from running inside the ms-markets source checkout.
Removed
- Removed legacy DataNode schema-bootstrap/fake-row APIs, DataNode-side dtype maps, record definitions, duplicate index-name constants, and compatibility shims that mirrored storage metadata.
- Removed the local
msm migrationscommand group and old migration runner in favor of the SDK Alembic provider flow. - Removed duplicated row-oriented execution fact MetaTables and APIs; execution facts are now storage-first.
- Removed obsolete asset reference-list, pricing, portfolio, account, execution, and utility shims that no longer match the current package boundaries.
- Removed core dependencies that now belong to optional extras, including
QuantLib under
pricingand FastAPI/Uvicorn underpublic_api.
[0.0.1] - 2026-05-25
Added
- Scaffolded the
ms-marketsPython project with the import packagemsm. - Added MkDocs documentation, ADRs, tutorial scaffold, and GitHub Pages deployment workflow.
- Migrated market-domain code from the SDK into
src/msm. - Migrated market-domain examples into
examples/. - Migrated market-domain agent skills into
.agents/skills/. - Added a future CLI package scaffold under
src/cli. - Added the initial
docs/knowledgeconcept documentation area formsmpackage concepts. - Added Apache-2.0 licensing metadata and the full project license.
- Added the
.agents/skills/library_maintenanceOpen Agent skill to enforce library maintenance workflows across implementation, documentation, examples, tutorials, changelog, and validation.
Changed
- Moved asset DataNode schemas from the obsolete
msm.assetspackage boundary intomsm.data_nodes.assets. - Moved OpenFIGI provider helpers into
msm.services.assets.openfigiand kept asset identity on themsm.models.assets.AssetMetaTable model. - Made
msm.servicesandmsm.data_nodespackage exports lazy so provider helpers and lightweight package imports do not initialize unrelated platform dependencies. - Reworked the README into the public project overview, including logo, badges, documentation map, quick start, development commands, metadata, and license information.
- Made README links PyPI-safe by pointing package-page readers to the public documentation site and GitHub project files.
- Added explicit source distribution include rules so PyPI source artifacts do not ship local IDE, workflow, or agent-maintenance files.
- Declared the first release version directly in
pyproject.tomlas0.0.1. - Refactored instrument valuation code into
msm_pricing. - Renamed pricing model helpers from the old
pricing_modelspackage tomsm_pricing.models.
Removed
- Removed migrated market-domain code, examples, and skills from the SDK tree.