02 Black Scholes game.
Explain changes in the price of the option due to changes in the underlying parameters.
BlackScholesCallGame is a demonstration of a game template ParameterChangeExplanation The template is available in shapley_numba.game_templates .
Each “player” is a changing parameter. The payoff of the game is the price of the option given a change in the subset of parameters. There are four players: spot, time to expiry, interest rate and volatility. There is also a fixed parameter that doesn’t change and doesn’t participate as a player - strike of the option.
import numpy as np
from IPython.display import Markdown
from shapley_numba.common import subsets
from shapley_numba.examples.finance import BlackScholesCallGame
from shapley_numba.harsanyi_naive import harsanyi_dividends
from shapley_numba.shapley import shapley
game = BlackScholesCallGame(
old_parameters=np.array([100, 1, 0.05, 0.2]),
new_parameters=np.array([105, 0.75, 0.055, 0.25]),
strike=110.0,
)
old_value = game.value(np.array([0, 0, 0, 0]))
new_value = game.value(np.array([1, 1, 1, 1]))
print('old value', old_value)
print('new value', new_value)
print('Change to explain', new_value - old_value)
old value 6.040088129724225
new value 8.800724823107544
Change to explain 2.7606366933833186
names = ['Spot', 'Time', 'Rate', 'Volatility']
headings = ['Spot increase', 'Time passage', 'Rate increase', 'Vol increase']
s_values = shapley(game, 4)
header = f'| {" | ".join(headings)} |'
separator = f'|{"|".join(["---"] * len(headings))}|'
values = f'| {" | ".join([f"{v:.3f}" for v in s_values])} |'
markdown_table = f'{header}\n{separator}\n{values}'
display(Markdown(markdown_table))
| Spot increase | Time passage | Rate increase | Vol increase | |—|—|—|—| | 2.467 | -1.788 | 0.188 | 1.894 |
for subset in subsets(4):
print(subset, harsanyi_dividends(game, subset))
[0 0 0 0] 6.040088129724225
[1 0 0 0] 2.492871284992276
[0 1 0 0] -1.5180748448761108
[1 1 0 0] -0.20158700033770316
[0 0 1 0] 0.19660963982492063
[1 0 1 0] 0.04974116206298618
[0 1 1 0] -0.06135005304311392
[1 1 1 0] -0.006887445129201808
[0 0 0 1] 1.9862965641291268
[1 0 0 1] 0.0910151216318198
[0 1 0 1] -0.2937219201339829
[1 1 0 1] 0.02782502367695372
[0 0 1 1] 0.0035390589919401805
[1 0 1 1] -0.009964729363701963
[0 1 1 1] 0.0027606583400370255
[1 1 1 1] 0.0015641726170727566
headings = [f'Change in {name}' for name in names]
table_lines = ['|'.join(headings + ['Dividend']), '|'.join([':---:'] * 5)]
content = [
['\u2713' if val == 1 else '-' for val in subset]
+ [f'{harsanyi_dividends(game, subset):3f}']
for subset in subsets(4)
]
content = ['|'.join(line) for line in content]
table = [f'|{line}|' for line in table_lines + content]
display(Markdown('\n'.join(table)))
|Change in Spot|Change in Time|Change in Rate|Change in Volatility|Dividend| |:—:|:—:|:—:|:—:|:—:| |-|-|-|-|6.040088| |✓|-|-|-|2.492871| |-|✓|-|-|-1.518075| |✓|✓|-|-|-0.201587| |-|-|✓|-|0.196610| |✓|-|✓|-|0.049741| |-|✓|✓|-|-0.061350| |✓|✓|✓|-|-0.006887| |-|-|-|✓|1.986297| |✓|-|-|✓|0.091015| |-|✓|-|✓|-0.293722| |✓|✓|-|✓|0.027825| |-|-|✓|✓|0.003539| |✓|-|✓|✓|-0.009965| |-|✓|✓|✓|0.002761| |✓|✓|✓|✓|0.001564|