Repository navigation
Use the value-maximising flat trigger in Bjerksund-Stensland - #2963
Merged
lballabio merged 3 commits intoNov 2, 2026
Merged
Conversation
The published trigger is a heuristic that falls below the strike as T approaches T* = (2 sigma/|b|)^2 for negative carry, and the price then collapses to the European one. Every flat trigger gives a lower bound for the American price, so when the value still increases above the published trigger, search for the best one. The trigger drops out of the first-order greeks at the optimum; gamma gets a -V_SI^2/V_II term.
The very-high-volatility put in testBjerksundStenslandValues was priced at its European value; QdFp and CRR give 99.2035. Two Margrabe values from Haug move towards the QdFp values of the equivalent call.
|
Congratulations on your first merged pull request! |
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.
Fixes #2903, implementing option (a1) as discussed there.
Every flat trigger gives a lower bound for the American price; the published trigger is only a heuristic for the best one, and for negative carry it drops below the strike as T approaches T* = (2σ/|b|)², so the price collapses to the European value. The engine now checks whether the value still increases just above max(I, S); if so, it finds the best trigger by golden-section search on log(I) up to B∞ (about 88% of options stop at the check and keep today's price).
Greeks: at the optimum the value is stationary in I, so the trigger-derivative terms in rho, dividend rho and vega drop out. The optimal trigger moves with the spot, so gamma gets a −V_SI²/V_II term (finite differences in I). The existing finite-difference greek test covers 406 options that go through the search; without the gamma term, 90 of its gamma checks fail.
Tests:
testBjerksundStenslandNegativeCarryTriggerwith the cases from BjerksundStensland returns the European value (~97% too low) when the trigger falls below the strike (negative carry, long maturity) #2903 across T*: errors against QdFp were 1%–97% on master, now at most 1.4e-3, and the price no longer decreases with maturity;testBjerksundStenslandValueswas pinned at 95.12289, which is its European value; it's now 99.20350 (QdFp 99.203499, CRR 4001 steps 99.20338);On 10k random options (S/K 0.8–1.2, r, q 0–10%, vol 10–50%, T 30d–3y), 9.9% change (at most 0.68%); every changed price moves towards QdFp, and none goes above it. The full test suite passes.
AI assistance was used for the implementation and analysis; I reviewed every line.