Skip to content

Implement relevanceRates in CallSpecifiedMultiProduct and CallSpecifiedPathwiseMultiProduct - #2852

Open
Nityahapani wants to merge 1 commit into
lballabio:masterfrom
Nityahapani:fix/callspecified-implement-relevance-rates
Open

Nityahapani wants to merge 1 commit into
lballabio:masterfrom
Nityahapani:fix/callspecified-implement-relevance-rates

Conversation

@Nityahapani

Copy link
Copy Markdown

Both constructors merged evolution times from the underlying product, exercise times, rebate product, and strategy times, but passed no relevanceRates to EvolutionDescription, leaving it to default to the full [0, numberOfRates] range for every step:

// TODO: add relevant rates
evolution_ = EvolutionDescription(rateTimes1, mergedEvolutionTimes);

This means downstream simulation engines had no information about which rates are actually needed at each step and were forced to evolve all rates at every merged step, even when only a narrow subset is required.

Implementation:
For each merged evolution step, the relevant rate range is the union of:

  • underlying_.evolution().relevanceRates()[undStep] when isPresent_[0][i]
  • rebate_.evolution().relevanceRates()[rebStep] when isPresent_[2][i]

The step counters undStep and rebStep are advanced independently as we walk through merged steps, mapping each merged step back to its source product's step index via the isPresent_ flags.

For purely structural steps (exercise-only or strategy-only, where neither underlying nor rebate is active), we conservatively fall back to the full rate range [0, numberOfRates] since no narrower bound can be inferred without querying the strategy itself.

The same logic is applied consistently to both CallSpecifiedMultiProduct (multistep) and CallSpecifiedPathwiseMultiProduct (pathwise).

…edPathwiseMultiProduct

Both constructors merged evolution times from the underlying product,
exercise times, rebate product, and strategy times, but passed no
relevanceRates to EvolutionDescription, leaving it to default to the
full [0, numberOfRates] range for every step:

    // TODO: add relevant rates
    evolution_ = EvolutionDescription(rateTimes1, mergedEvolutionTimes);

This means downstream simulation engines had no information about which
rates are actually needed at each step and were forced to evolve all
rates at every merged step, even when only a narrow subset is required.

Implementation:
For each merged evolution step, the relevant rate range is the union of:
- underlying_.evolution().relevanceRates()[undStep] when isPresent_[0][i]
- rebate_.evolution().relevanceRates()[rebStep]   when isPresent_[2][i]

The step counters undStep and rebStep are advanced independently as we
walk through merged steps, mapping each merged step back to its source
product's step index via the isPresent_ flags.

For purely structural steps (exercise-only or strategy-only, where
neither underlying nor rebate is active), we conservatively fall back
to the full rate range [0, numberOfRates] since no narrower bound can
be inferred without querying the strategy itself.

The same logic is applied consistently to both CallSpecifiedMultiProduct
(multistep) and CallSpecifiedPathwiseMultiProduct (pathwise).
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.

1 participant