Initial commit
This commit is contained in:
commit
909846e3ac
|
|
@ -0,0 +1,174 @@
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# UV
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
#uv.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||||
|
.pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# Ruff stuff:
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# PyPI configuration file
|
||||||
|
.pypirc
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,2 @@
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 100
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
[pytest]
|
||||||
|
pythonpath = .
|
||||||
|
testpaths = src
|
||||||
|
python_files = *_test.py
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "initial_id",
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": "import options"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 2
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython2",
|
||||||
|
"version": "2.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,261 @@
|
||||||
|
date,ccy-1,ccy-2
|
||||||
|
14-11-2019,1.1684427,0.886564121
|
||||||
|
13-11-2019,1.165976797,0.884329678
|
||||||
|
12-11-2019,1.16603118,0.883470271
|
||||||
|
11-11-2019,1.166901992,0.87753938
|
||||||
|
8-11-2019,1.160725686,0.877658927
|
||||||
|
7-11-2019,1.160712213,0.876270592
|
||||||
|
6-11-2019,1.162466288,0.877654906
|
||||||
|
5-11-2019,1.162020521,0.876693114
|
||||||
|
4-11-2019,1.158050769,0.881600987
|
||||||
|
1-11-2019,1.159084323,0.881911985
|
||||||
|
31-10-2019,1.160995205,0.885700368
|
||||||
|
30-10-2019,1.156992283,0.886839305
|
||||||
|
29-10-2019,1.160671797,0.878271562
|
||||||
|
28-10-2019,1.159164938,0.879816998
|
||||||
|
25-10-2019,1.157420803,0.881290209
|
||||||
|
24-10-2019,1.157126161,0.880902044
|
||||||
|
23-10-2019,1.158761979,0.88163985
|
||||||
|
22-10-2019,1.15928588,0.878464444
|
||||||
|
21-10-2019,1.164903779,0.87788605
|
||||||
|
18-10-2019,1.157889862,0.879198171
|
||||||
|
17-10-2019,1.155081202,0.883197174
|
||||||
|
16-10-2019,1.158426394,0.879700902
|
||||||
|
15-10-2019,1.157836236,0.881329044
|
||||||
|
14-10-2019,1.141630705,0.885151582
|
||||||
|
11-10-2019,1.148791471,0.88210647
|
||||||
|
10-10-2019,1.115299681,0.879971841
|
||||||
|
9-10-2019,1.112743134,0.875465091
|
||||||
|
8-10-2019,1.114876918,0.876001927
|
||||||
|
7-10-2019,1.12083749,0.876270592
|
||||||
|
4-10-2019,1.119870991,0.876193814
|
||||||
|
3-10-2019,1.129318231,0.876616261
|
||||||
|
2-10-2019,1.124062813,0.876923751
|
||||||
|
1-10-2019,1.119733056,0.874431619
|
||||||
|
30-9-2019,1.128935752,0.873667657
|
||||||
|
27-9-2019,1.124492573,0.880824452
|
||||||
|
26-9-2019,1.12731946,0.877654906
|
||||||
|
25-9-2019,1.129496809,0.876424189
|
||||||
|
24-9-2019,1.130867236,0.872600349
|
||||||
|
23-9-2019,1.133758437,0.873896705
|
||||||
|
20-9-2019,1.135151089,0.868809731
|
||||||
|
19-9-2019,1.129484052,0.867829558
|
||||||
|
18-9-2019,1.128579006,0.871269876
|
||||||
|
17-9-2019,1.129905201,0.872105699
|
||||||
|
16-9-2019,1.129292724,0.874087671
|
||||||
|
13-9-2019,1.124151266,0.87753938
|
||||||
|
12-9-2019,1.123458883,0.878734622
|
||||||
|
11-9-2019,1.122258883,0.87966221
|
||||||
|
10-9-2019,1.118918677,0.879894413
|
||||||
|
9-9-2019,1.116220922,0.88051422
|
||||||
|
6-9-2019,1.11477749,0.878811846
|
||||||
|
5-9-2019,1.116245842,0.880630531
|
||||||
|
4-9-2019,1.105534305,0.877308418
|
||||||
|
3-9-2019,1.103046615,0.874469853
|
||||||
|
2-9-2019,1.099601944,0.87507623
|
||||||
|
30-8-2019,1.103022281,0.875273523
|
||||||
|
29-8-2019,1.10282765,0.87001914
|
||||||
|
28-8-2019,1.103387399,0.871991629
|
||||||
|
27-8-2019,1.010123245,0.874928912
|
||||||
|
26-8-2019,1.099747058,0.876501008
|
||||||
|
23-8-2019,1.104899123,0.878889084
|
||||||
|
22-8-2019,1.105546527,0.880630531
|
||||||
|
21-8-2019,1.093469798,0.882768362
|
||||||
|
20-8-2019,1.094235567,0.886839305
|
||||||
|
19-8-2019,1.093637219,0.884955752
|
||||||
|
16-8-2019,1.093744873,0.886014265
|
||||||
|
15-8-2019,1.090655266,0.886839305
|
||||||
|
14-8-2019,1.082508822,0.887941751
|
||||||
|
13-8-2019,1.078865034,0.884564352
|
||||||
|
12-8-2019,1.077156737,0.882339966
|
||||||
|
9-8-2019,1.07820199,0.881057269
|
||||||
|
8-8-2019,1.083247576,0.881290209
|
||||||
|
7-8-2019,1.083505791,0.881911985
|
||||||
|
6-8-2019,1.087961704,0.881367883
|
||||||
|
5-8-2019,1.085422772,0.88028169
|
||||||
|
2-8-2019,1.091381361,0.878618811
|
||||||
|
1-8-2019,1.098490674,0.876232202
|
||||||
|
31-7-2019,1.096234287,0.878194432
|
||||||
|
30-7-2019,1.090905124,0.883119177
|
||||||
|
29-7-2019,1.098719991,0.884603476
|
||||||
|
26-7-2019,1.113337787,0.883587365
|
||||||
|
25-7-2019,1.119670369,0.890194507
|
||||||
|
24-7-2019,1.121642084,0.890234132
|
||||||
|
23-7-2019,1.11564808,0.890947969
|
||||||
|
22-7-2019,1.113647753,0.88691796
|
||||||
|
19-7-2019,1.114243373,0.884173298
|
||||||
|
18-7-2019,1.112978442,0.884642604
|
||||||
|
17-7-2019,1.107162232,0.883002208
|
||||||
|
16-7-2019,1.106304831,0.882028666
|
||||||
|
15-7-2019,1.111296327,0.881406725
|
||||||
|
12-7-2019,1.116196004,0.880902044
|
||||||
|
11-7-2019,1.114293037,0.88028169
|
||||||
|
10-7-2019,1.1105805,0.886367665
|
||||||
|
9-7-2019,1.112433671,0.883197174
|
||||||
|
8-7-2019,1.115672974,0.886485528
|
||||||
|
5-7-2019,1.114504157,0.888967908
|
||||||
|
4-7-2019,1.114789918,0.88999644
|
||||||
|
3-7-2019,1.113635351,0.890323
|
||||||
|
2-7-2019,1.115038525,0.891067053
|
||||||
|
1-7-2019,1.117006423,0.893535272
|
||||||
|
28-6-2019,1.114050958,0.890511599
|
||||||
|
27-6-2019,1.115050958,0.891583452
|
||||||
|
26-6-2019,1.114541422,0.89098766
|
||||||
|
25-6-2019,1.117355889,0.887981175
|
||||||
|
24-6-2019,1.117218573,0.88711466
|
||||||
|
21-6-2019,1.121453404,0.888809884
|
||||||
|
20-6-2019,1.124985938,0.88711466
|
||||||
|
19-6-2019,1.126164172,0.883821645
|
||||||
|
18-6-2019,1.120925436,0.884407889
|
||||||
|
17-6-2019,1.118480656,0.884955752
|
||||||
|
14-6-2019,1.123204277,0.884760009
|
||||||
|
13-6-2019,1.125365744,0.889363216
|
||||||
|
12-6-2019,1.124163903,0.889086464
|
||||||
|
11-6-2019,1.124075448,0.888533475
|
||||||
|
10-6-2019,1.121239643,0.892299456
|
||||||
|
7-6-2019,1.125163149,0.892538379
|
||||||
|
6-6-2019,1.127116161,0.8942312
|
||||||
|
5-6-2019,1.130467222,0.89512332
|
||||||
|
4-6-2019,1.12847712,0.89561596
|
||||||
|
3-6-2019,1.127471982,0.8952134
|
||||||
|
31-5-2019,1.1281843,0.889600569
|
||||||
|
30-5-2019,1.131528922,0.894134478
|
||||||
|
29-5-2019,1.133542661,0.893894699
|
||||||
|
28-5-2019,1.134404211,0.893255918
|
||||||
|
27-5-2019,1.132964742,0.893854749
|
||||||
|
24-5-2019,1.132618274,0.892538379
|
||||||
|
23-5-2019,1.135976372,0.89047195
|
||||||
|
22-5-2019,1.134803282,0.889263216
|
||||||
|
21-5-2019,1.14310536,0.889363216
|
||||||
|
20-5-2019,1.140706097,0.891901534
|
||||||
|
17-5-2019,1.14087528,0.892259648
|
||||||
|
16-5-2019,1.144348065,0.89465444
|
||||||
|
15-5-2019,1.147802532,0.896137647
|
||||||
|
14-5-2019,1.152113552,0.89561596
|
||||||
|
13-5-2019,1.154921119,0.894374385
|
||||||
|
10-5-2019,1.158842548,0.896619744
|
||||||
|
9-5-2019,1.159393405,0.896901206
|
||||||
|
8-5-2019,1.160294715,0.892458724
|
||||||
|
7-5-2019,1.16638479,0.893575194
|
||||||
|
6-5-2019,1.169590643,0.894854586
|
||||||
|
3-5-2019,1.172525385,0.897504936
|
||||||
|
2-5-2019,1.165324601,0.898714838
|
||||||
|
1-5-2019,1.163995297,0.897021887
|
||||||
|
30-4-2019,1.16132379,0.892618049
|
||||||
|
29-4-2019,1.157407407,0.89031339
|
||||||
|
26-4-2019,1.57284634,0.887862914
|
||||||
|
25-4-2019,1.568324628,0.886406949
|
||||||
|
24-4-2019,1.156590833,0.882067566
|
||||||
|
23-4-2019,1.154227937,0.883704489
|
||||||
|
22-4-2019,1.152963693,0.883743538
|
||||||
|
19-4-2019,1.156122826,0.883431247
|
||||||
|
18-4-2019,1.156925355,0.887232721
|
||||||
|
17-4-2019,1.154521105,0.890868597
|
||||||
|
16-4-2019,1.155214639,0.890789239
|
||||||
|
15-4-2019,1.159729551,0.894054537
|
||||||
|
12-4-2019,1.158158065,0.891583452
|
||||||
|
11-4-2019,1.160739159,0.885778821
|
||||||
|
10-4-2019,1.163277651,0.883314195
|
||||||
|
9-4-2019,1.157420803,0.878040214
|
||||||
|
8-4-2019,1.158721698,0.878425861
|
||||||
|
5-4-2019,1.159218687,0.879043601
|
||||||
|
4-4-2019,1.166412,0.879584836
|
||||||
|
3-4-2019,1.171687347,0.878889084
|
||||||
|
2-4-2019,1.164225674,0.883041194
|
||||||
|
1-4-2019,1.170686022,0.885269122
|
||||||
|
29-3-2019,1.168346532,0.885367665
|
||||||
|
28-3-2019,1.164646006,0.886367665
|
||||||
|
27-3-2019,1.172374175,0.891106755
|
||||||
|
26-3-2019,1.171440286,0.891543708
|
||||||
|
25-3-2019,1.165555504,0.892379083
|
||||||
|
22-3-2019,1.171550078,0.888888889
|
||||||
|
21-3-2019,1.150483203,0.888730892
|
||||||
|
20-3-2019,1.161737029,0.888691402
|
||||||
|
19-3-2019,1.169057389,0.887862914
|
||||||
|
18-3-2019,1.165949608,0.891106755
|
||||||
|
15-3-2019,1.17249789,0.890828916
|
||||||
|
14-3-2019,1.174853437,0.891662951
|
||||||
|
13-3-2019,1.169590643,0.891106755
|
||||||
|
12-3-2019,1.161642563,0.891027355
|
||||||
|
11-3-2019,1.166520852,0.896860987
|
||||||
|
8-3-2019,1.158506916,0.897424392
|
||||||
|
7-3-2019,1.16780138,0.896097495
|
||||||
|
6-3-2019,1.162007019,0.898795614
|
||||||
|
5-3-2019,1.159810255,0.898311175
|
||||||
|
4-3-2019,1.163372384,0.897786955
|
||||||
|
1-3-2019,1.16295297,0.90244334
|
||||||
|
28-2-2019,1.16512094,0.90440445
|
||||||
|
27-2-2019,1.171508903,0.900738606
|
||||||
|
26-2-2019,1.165311022,0.894054537
|
||||||
|
25-2-2019,1.151768541,0.893974611
|
||||||
|
22-2-2019,1.151330939,0.891662951
|
||||||
|
21-2-2019,1.151410478,0.89273758
|
||||||
|
20-2-2019,1.151012891,0.892777431
|
||||||
|
19-2-2019,1.149729239,0.89146423
|
||||||
|
18-2-2019,1.143301397,0.893694982
|
||||||
|
15-2-2019,1.140693085,0.896860987
|
||||||
|
14-2-2019,1.133118796,0.900252071
|
||||||
|
13-2-2019,1.14153948,0.900576369
|
||||||
|
12-2-2019,1.140133852,0.901225667
|
||||||
|
11-2-2019,1.140914329,0.901794571
|
||||||
|
8-2-2019,1.142739604,0.901388138
|
||||||
|
7-2-2019,1.142400183,0.902445628
|
||||||
|
6-2-2019,1.139211666,0.900009
|
||||||
|
5-2-2019,1.134198349,0.899806542
|
||||||
|
4-2-2019,1.144885225,0.901243
|
||||||
|
1-2-2019,1.14187839,0.902934537
|
||||||
|
31-1-2019,1.143379831,0.903628067
|
||||||
|
30-1-2019,1.144112398,0.906043309
|
||||||
|
29-1-2019,1.148349572,0.911701691
|
||||||
|
28-1-2019,1.15036409,0.912325518
|
||||||
|
25-1-2019,1.155374804,0.906618314
|
||||||
|
24-1-2019,1.148567162,0.905387053
|
||||||
|
23-1-2019,1.14825064,0.905223138
|
||||||
|
22-1-2019,1.140797189,0.904486252
|
||||||
|
21-1-2019,1.134751773,0.905715062
|
||||||
|
18-1-2019,1.135383078,0.909338911
|
||||||
|
17-1-2019,1.134134032,0.906700517
|
||||||
|
16-1-2019,1.128515325,0.902282775
|
||||||
|
15-1-2019,1.119482351,0.909256228
|
||||||
|
14-1-2019,1.125707789,0.904977376
|
||||||
|
11-1-2019,1.117143687,0.90424089
|
||||||
|
10-1-2019,1.108696616,0.904568069
|
||||||
|
9-1-2019,1.107125459,0.908265213
|
||||||
|
8-1-2019,1.112644087,0.90962735
|
||||||
|
7-1-2019,1.1141813,0.91124248
|
||||||
|
4-1-2019,1.115026092,0.912575287
|
||||||
|
3-1-2019,1.106060103,0.913993236
|
||||||
|
2-1-2019,1.110592834,0.913408842
|
||||||
|
31-12-2018,1.117156167,0.916674306
|
||||||
|
28-12-2018,1.109299256,0.916086479
|
||||||
|
27-12-2018,1.107910481,0.913575735
|
||||||
|
26-12-2018,1.110975325,0.910332271
|
||||||
|
24-12-2018,1.114305453,0.910829766
|
||||||
|
21-12-2018,1.1105805,0.909545682
|
||||||
|
20-12-2018,1.106831363,0.912825194
|
||||||
|
19-12-2018,1.10702741,0.910705341
|
||||||
|
18-12-2018,1.111716379,0.908182726
|
||||||
|
17-12-2018,1.112334679,0.905879156
|
||||||
|
14-12-2018,1.111790539,0.907029478
|
||||||
|
13-12-2018,1.112099644,0.906084356
|
||||||
|
12-12-2018,1.113833816,0.904813608
|
||||||
|
11-12-2018,1.106427236,0.899523253
|
||||||
|
10-12-2018,1.101770545,0.897585495
|
||||||
|
7-12-2018,1.12027245,0.897182846
|
||||||
|
6-12-2018,1.123048133,0.898391879
|
||||||
|
5-12-2018,1.123078133,0.899523253
|
||||||
|
4-12-2018,1.1212145,0.900414191
|
||||||
|
3-12-2018,1.122498232,0.901631954
|
||||||
|
30-11-2018,1.122384843,0.901550667
|
||||||
|
29-11-2018,1.122120359,0.899604174
|
||||||
|
28-11-2018,1.130671732,0.899118864
|
||||||
|
27-11-2018,1.128387985,0.896539358
|
||||||
|
26-11-2018,1.130965845,0.895255148
|
||||||
|
23-11-2018,1.128795575,0.896458987
|
||||||
|
22-11-2018,1.128349788,0.903097625
|
||||||
|
21-11-2018,1.121730157,0.903056847
|
||||||
|
20-11-2018,1.123898579,0.912825194
|
||||||
|
19-11-2018,1.247645328,0.910705341
|
||||||
|
16-11-2018,1.126722477,0.900414191
|
||||||
|
15-11-2018,1.129598879,0.905879156
|
||||||
|
14-11-2018,1.14998045,0.895255148
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
from scipy.stats import norm
|
||||||
|
|
||||||
|
|
||||||
|
def as_df(option):
|
||||||
|
"""Creates a dataframe holding the option, and calculates time to maturity"""
|
||||||
|
df = pd.DataFrame([option])
|
||||||
|
df["T"] = (df["t1"] - df["t0"]) / np.timedelta64(365, "D")
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def black_scholes_option_price_spot(S, K, T, r, sigma, option_type="call"):
|
||||||
|
"""Calculates option price using Black-Scholes formula with spot price assuming zero dividend"""
|
||||||
|
sigma_scaled = sigma * np.sqrt(T)
|
||||||
|
d1 = (np.log(S / K) + (r + 0.5 * sigma**2) * T) / sigma_scaled
|
||||||
|
d2 = d1 - sigma_scaled
|
||||||
|
|
||||||
|
if option_type == "call":
|
||||||
|
return S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
|
||||||
|
return K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1) # put
|
||||||
|
|
||||||
|
|
||||||
|
def black_scholes_option_price_forward(F, K, T, r, sigma, option_type="call"):
|
||||||
|
"""Calculates option price using Black-Scholes formula with forward price assuming zero dividend"""
|
||||||
|
sigma_scaled = sigma * np.sqrt(T)
|
||||||
|
d1 = (np.log(F / K) + (0.5 * sigma**2) * T) / sigma_scaled
|
||||||
|
d2 = d1 - sigma_scaled
|
||||||
|
|
||||||
|
discount = np.exp(-r * T)
|
||||||
|
|
||||||
|
if option_type == "call":
|
||||||
|
return discount * (F * norm.cdf(d1) - K * norm.cdf(d2))
|
||||||
|
return discount * (K * norm.cdf(-d2) - F * norm.cdf(-d1)) # put
|
||||||
|
|
||||||
|
|
||||||
|
def forward_price(S, T, r):
|
||||||
|
"""Calculates the forward price assuming zero dividend"""
|
||||||
|
return S * np.exp(r * T)
|
||||||
|
|
||||||
|
|
||||||
|
def moneyness(strike_price, current_price, option_type="call", threshold=0.005):
|
||||||
|
"""Calculates if an option is ITM, ATM, or OTM"""
|
||||||
|
fuzzy_price = threshold * strike_price
|
||||||
|
|
||||||
|
if option_type == "put":
|
||||||
|
if current_price < strike_price - fuzzy_price:
|
||||||
|
return "ITM"
|
||||||
|
if current_price > strike_price + fuzzy_price:
|
||||||
|
return "OTM"
|
||||||
|
return "ATM"
|
||||||
|
|
||||||
|
if option_type == "call":
|
||||||
|
if current_price > strike_price + fuzzy_price:
|
||||||
|
return "ITM"
|
||||||
|
if current_price < strike_price - fuzzy_price:
|
||||||
|
return "OTM"
|
||||||
|
return "ATM"
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import pytest
|
||||||
|
import pandas as pd
|
||||||
|
from pandas.testing import assert_series_equal
|
||||||
|
|
||||||
|
from . import options
|
||||||
|
|
||||||
|
|
||||||
|
# https://analystprep.com/study-notes/actuarial-exams/soa/ifm-investment-and-financial-markets/black-scholes-option-pricing-model/
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"S, K, T, r, sigma, option_type, expected", [(100, 90, 0.5, 0.10, 0.25, "call", 16.11)]
|
||||||
|
)
|
||||||
|
def test_black_scholes_option_price_spot(S, K, T, r, sigma, option_type, expected):
|
||||||
|
assert (
|
||||||
|
abs(options.black_scholes_option_price_spot(S, K, T, r, sigma, option_type)) - expected
|
||||||
|
< 0.05
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"F, K, T, r, sigma, option_type, expected", [(100, 90, 0.5, 0.10, 0.25, "call", 16.11)]
|
||||||
|
)
|
||||||
|
def test_black_scholes_option_price_forward(F, K, T, r, sigma, option_type, expected):
|
||||||
|
assert (
|
||||||
|
abs(options.black_scholes_option_price_forward(F, K, T, r, sigma, option_type)) - expected
|
||||||
|
< 0.05
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"current_price, strike_price, option_type, expected",
|
||||||
|
[
|
||||||
|
(1, 10, "call", "ITM"),
|
||||||
|
(10, 1, "call", "OTM"),
|
||||||
|
(10, 10, "call", "ATM"),
|
||||||
|
(1, 10, "put", "OTM"),
|
||||||
|
(10, 1, "put", "ITM"),
|
||||||
|
(10, 10, "put", "ATM"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_moneyness(current_price, strike_price, option_type, expected):
|
||||||
|
assert options.moneyness(current_price, strike_price, option_type) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_end_to_end():
|
||||||
|
option = {
|
||||||
|
"t0": pd.Timestamp("2024-11-23"),
|
||||||
|
"t1": pd.Timestamp("2025-05-10"),
|
||||||
|
"S": 19,
|
||||||
|
"K": 17,
|
||||||
|
"r": 0.005,
|
||||||
|
"sigma": 0.3,
|
||||||
|
}
|
||||||
|
options_df = options.as_df(option)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
"F": 19.04367,
|
||||||
|
"C_F": 2.70,
|
||||||
|
"C_S": 2.70,
|
||||||
|
"P_F": 0.66,
|
||||||
|
"P_PCP": 0.66,
|
||||||
|
}
|
||||||
|
expected_df = pd.DataFrame([expected])
|
||||||
|
|
||||||
|
assert_series_equal(
|
||||||
|
options.forward_price(options_df["S"], options_df["T"], options_df["r"]),
|
||||||
|
expected_df["F"],
|
||||||
|
check_names=False,
|
||||||
|
check_exact=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_series_equal(
|
||||||
|
options.black_scholes_option_price_spot(
|
||||||
|
options_df["S"],
|
||||||
|
options_df["K"],
|
||||||
|
options_df["T"],
|
||||||
|
options_df["r"],
|
||||||
|
options_df["sigma"],
|
||||||
|
"call",
|
||||||
|
),
|
||||||
|
expected_df["C_S"],
|
||||||
|
rtol=0.01,
|
||||||
|
check_names=False,
|
||||||
|
check_exact=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_series_equal(
|
||||||
|
options.black_scholes_option_price_forward(
|
||||||
|
options.forward_price(options_df["S"], options_df["T"], options_df["r"]),
|
||||||
|
options_df["K"],
|
||||||
|
options_df["T"],
|
||||||
|
options_df["r"],
|
||||||
|
options_df["sigma"],
|
||||||
|
"call",
|
||||||
|
),
|
||||||
|
expected_df["C_F"],
|
||||||
|
rtol=0.01,
|
||||||
|
check_names=False,
|
||||||
|
check_exact=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_series_equal(
|
||||||
|
options.black_scholes_option_price_forward(
|
||||||
|
options.forward_price(options_df["S"], options_df["T"], options_df["r"]),
|
||||||
|
options_df["K"],
|
||||||
|
options_df["T"],
|
||||||
|
options_df["r"],
|
||||||
|
options_df["sigma"],
|
||||||
|
"put",
|
||||||
|
),
|
||||||
|
expected_df["P_F"],
|
||||||
|
rtol=0.01,
|
||||||
|
check_names=False,
|
||||||
|
check_exact=False,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_returns(prices, horizon=1, sort="ascending"):
|
||||||
|
step = 1 if sort == "ascending" else -1
|
||||||
|
if horizon == 1:
|
||||||
|
returns = prices / prices.shift(step) - 1
|
||||||
|
else:
|
||||||
|
returns = np.exp(np.log(prices / prices.shift(step)) * np.sqrt(horizon)) - 1
|
||||||
|
return returns.dropna()
|
||||||
|
|
||||||
|
|
||||||
|
def var(portfolio, prices, horizon=1, sort="ascending"):
|
||||||
|
returns = calculate_returns(prices, horizon, sort)
|
||||||
|
pnl = portfolio.dot(returns.T)
|
||||||
|
daily_pnl = pnl.sum(axis=0)
|
||||||
|
daily_pnl_asc = daily_pnl.sort_values(ascending=True)
|
||||||
|
return 0.4 * daily_pnl_asc[1] + 0.6 * daily_pnl_asc[2]
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
import pytest
|
||||||
|
from pandas.testing import assert_series_equal
|
||||||
|
|
||||||
|
from . import var
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"prices, horizon, ascending, expected",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
pd.DataFrame([1, 2, 3, 4, 5]),
|
||||||
|
1,
|
||||||
|
"ascending",
|
||||||
|
pd.Series([1.0, 0.5, 0.33333, 0.25], dtype=float),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_calculate_returns(prices, horizon, ascending, expected):
|
||||||
|
assert_series_equal(
|
||||||
|
var.calculate_returns(prices, horizon, ascending),
|
||||||
|
expected,
|
||||||
|
# rtol=0.01,
|
||||||
|
# check_names=False,
|
||||||
|
# check_exact=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_var():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_end_to_end():
|
||||||
|
portfolio = pd.DataFrame([{"ccy-1": 153084.81, "ccy-2": 95891.51}])
|
||||||
|
fx_prices = pd.read_csv(
|
||||||
|
os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "var_fx_prices.csv"),
|
||||||
|
parse_dates=["date"],
|
||||||
|
index_col="date",
|
||||||
|
dtype=float, # All non-date columns as float
|
||||||
|
)
|
||||||
|
fx_prices.sort_index(inplace=True, ascending=True)
|
||||||
|
assert var.var(portfolio, fx_prices) == pytest.approx(-13572.73)
|
||||||
Loading…
Reference in New Issue