Spaces:
Runtime error
Runtime error
huggingface112
commited on
Commit
•
576c56b
1
Parent(s):
cd1bf03
remove unused files
Browse files- api_data_samples.ipynb +9 -35
- app.ipynb +0 -0
- appComponents.py +2 -2
- app_ini.ipynb +0 -723
- script/description.py → description.py +1 -0
- index_page.py +6 -28
- instance/local.db +2 -2
- pipeline.py +36 -15
- pipeline/bhb.ipynb +0 -0
- pipeline/create_dumpy_data.ipynb +0 -36
- pipeline/db_operation.py +0 -35
- pipeline/model.py +0 -41
- pipeline/test_db_peration.py +0 -107
- portfolioEditingPage.ipynb +0 -0
- portfolioEditingPage.py +7 -7
- script/__init__.py +0 -0
- script/api_test.ipynb +0 -0
- script/bnb_sector_result.pkl +0 -3
- script/downloadData.ipynb +0 -751
- script/downloadData.py +0 -10
- script/pipeline.ipynb +0 -521
- script/portfolio_eval_df.pkl +0 -3
- script/processing.ipynb +0 -501
- script/processing2.ipynb +0 -1836
- script/sector_eval_df.pkl +0 -3
- script/stream_pricessing.ipynb +0 -617
- script/stream_processing.py +0 -32
- script/styling.py +0 -15
- test.ipynb +0 -47
- test_background_task.py +0 -26
- test_responsive.py +0 -14
- testing_pipeline.ipynb +0 -561
- total_return.ipynb +0 -713
api_data_samples.ipynb
CHANGED
@@ -1,15 +1,20 @@
|
|
1 |
{
|
2 |
"cells": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
"execution_count": 1,
|
6 |
"metadata": {},
|
7 |
"outputs": [],
|
8 |
"source": [
|
9 |
-
"
|
10 |
-
"import pandas as pd\n",
|
11 |
-
"from datetime import timedelta\n",
|
12 |
-
"import jqdatasdk as jq\n"
|
13 |
]
|
14 |
},
|
15 |
{
|
@@ -829,37 +834,6 @@
|
|
829 |
"source": [
|
830 |
"jq.get_all_securities()"
|
831 |
]
|
832 |
-
},
|
833 |
-
{
|
834 |
-
"cell_type": "code",
|
835 |
-
"execution_count": 4,
|
836 |
-
"metadata": {},
|
837 |
-
"outputs": [
|
838 |
-
{
|
839 |
-
"ename": "NameError",
|
840 |
-
"evalue": "name 'engine' is not defined",
|
841 |
-
"output_type": "error",
|
842 |
-
"traceback": [
|
843 |
-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
844 |
-
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
845 |
-
"Cell \u001b[0;32mIn[4], line 9\u001b[0m\n\u001b[1;32m 7\u001b[0m df[\u001b[39m'\u001b[39m\u001b[39mdate\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mto_datetime(df[\u001b[39m'\u001b[39m\u001b[39mdate\u001b[39m\u001b[39m'\u001b[39m])\n\u001b[1;32m 8\u001b[0m \u001b[39mreturn\u001b[39;00m df\n\u001b[0;32m----> 9\u001b[0m get_most_recent_profile(\u001b[39m'\u001b[39;49m\u001b[39mportfolio\u001b[39;49m\u001b[39m'\u001b[39;49m)\n",
|
846 |
-
"Cell \u001b[0;32mIn[4], line 5\u001b[0m, in \u001b[0;36mget_most_recent_profile\u001b[0;34m(type)\u001b[0m\n\u001b[1;32m 3\u001b[0m table_name \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39mbenchmark_profile\u001b[39m\u001b[39m'\u001b[39m \u001b[39mif\u001b[39;00m \u001b[39mtype\u001b[39m \u001b[39m==\u001b[39m \u001b[39m'\u001b[39m\u001b[39mbenchmark\u001b[39m\u001b[39m'\u001b[39m \u001b[39melse\u001b[39;00m \u001b[39m'\u001b[39m\u001b[39mportfolio_profile\u001b[39m\u001b[39m'\u001b[39m\n\u001b[1;32m 4\u001b[0m query \u001b[39m=\u001b[39m \u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mSELECT * FROM \u001b[39m\u001b[39m{\u001b[39;00mtable_name\u001b[39m}\u001b[39;00m\u001b[39m WHERE date = (SELECT MAX(date) FROM \u001b[39m\u001b[39m{\u001b[39;00mtable_name\u001b[39m}\u001b[39;00m\u001b[39m)\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m----> 5\u001b[0m df \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mread_sql(query, con\u001b[39m=\u001b[39mengine)\n\u001b[1;32m 6\u001b[0m \u001b[39m# convert date to datetime object\u001b[39;00m\n\u001b[1;32m 7\u001b[0m df[\u001b[39m'\u001b[39m\u001b[39mdate\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mto_datetime(df[\u001b[39m'\u001b[39m\u001b[39mdate\u001b[39m\u001b[39m'\u001b[39m])\n",
|
847 |
-
"\u001b[0;31mNameError\u001b[0m: name 'engine' is not defined"
|
848 |
-
]
|
849 |
-
}
|
850 |
-
],
|
851 |
-
"source": [
|
852 |
-
"# when update stock price just need the latest portfolio frame\n",
|
853 |
-
"def get_most_recent_profile(type):\n",
|
854 |
-
" table_name = 'benchmark_profile' if type == 'benchmark' else 'portfolio_profile'\n",
|
855 |
-
" query = f\"SELECT * FROM {table_name} WHERE date = (SELECT MAX(date) FROM {table_name})\"\n",
|
856 |
-
" with create_engine(db_url).connect() as conn:\n",
|
857 |
-
" df = pd.read_sql(query, con=engine)\n",
|
858 |
-
" # convert date to datetime object\n",
|
859 |
-
" df['date'] = pd.to_datetime(df['date'])\n",
|
860 |
-
" return df\n",
|
861 |
-
"get_most_recent_profile('portfolio')"
|
862 |
-
]
|
863 |
}
|
864 |
],
|
865 |
"metadata": {
|
|
|
1 |
{
|
2 |
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"metadata": {},
|
6 |
+
"source": [
|
7 |
+
"# Example data from jq api call\n",
|
8 |
+
"### This notebook contain samples of jq api call. The purpose of this is to prvide a reference when developing the pipeline. "
|
9 |
+
]
|
10 |
+
},
|
11 |
{
|
12 |
"cell_type": "code",
|
13 |
"execution_count": 1,
|
14 |
"metadata": {},
|
15 |
"outputs": [],
|
16 |
"source": [
|
17 |
+
"import jqdatasdk as jq"
|
|
|
|
|
|
|
18 |
]
|
19 |
},
|
20 |
{
|
|
|
834 |
"source": [
|
835 |
"jq.get_all_securities()"
|
836 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
837 |
}
|
838 |
],
|
839 |
"metadata": {
|
app.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|
appComponents.py
CHANGED
@@ -8,8 +8,8 @@ import numpy as np
|
|
8 |
import hvplot.pandas # noqa
|
9 |
from panel.viewable import Viewer
|
10 |
import param
|
11 |
-
|
12 |
-
|
13 |
import plotly.graph_objs as go
|
14 |
# import warnings
|
15 |
pn.extension('mathjax')
|
|
|
8 |
import hvplot.pandas # noqa
|
9 |
from panel.viewable import Viewer
|
10 |
import param
|
11 |
+
import styling
|
12 |
+
import description
|
13 |
import plotly.graph_objs as go
|
14 |
# import warnings
|
15 |
pn.extension('mathjax')
|
app_ini.ipynb
DELETED
@@ -1,723 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"data": {
|
10 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
11 |
-
"application/vnd.holoviews_load.v0+json": ""
|
12 |
-
},
|
13 |
-
"metadata": {},
|
14 |
-
"output_type": "display_data"
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"data": {
|
18 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
19 |
-
"application/vnd.holoviews_load.v0+json": ""
|
20 |
-
},
|
21 |
-
"metadata": {},
|
22 |
-
"output_type": "display_data"
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"data": {
|
26 |
-
"text/html": [
|
27 |
-
"<style>*[data-root-id],\n",
|
28 |
-
"*[data-root-id] > * {\n",
|
29 |
-
" box-sizing: border-box;\n",
|
30 |
-
" font-family: var(--jp-ui-font-family);\n",
|
31 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
32 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
33 |
-
"}\n",
|
34 |
-
"\n",
|
35 |
-
"/* Override VSCode background color */\n",
|
36 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
37 |
-
" > .lm-Widget\n",
|
38 |
-
" > *[data-root-id]),\n",
|
39 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
40 |
-
" background-color: transparent !important;\n",
|
41 |
-
"}\n",
|
42 |
-
"</style>"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
"metadata": {},
|
46 |
-
"output_type": "display_data"
|
47 |
-
}
|
48 |
-
],
|
49 |
-
"source": [
|
50 |
-
"import pandas as pd\n",
|
51 |
-
"from datetime import datetime, timedelta\n",
|
52 |
-
"from script import processing\n",
|
53 |
-
"from script import api\n",
|
54 |
-
"from sqlalchemy import create_engine\n",
|
55 |
-
"import pytz\n",
|
56 |
-
"import numpy as np\n",
|
57 |
-
"import hvplot.pandas\n",
|
58 |
-
"db_url = 'sqlite:///instance/local.db'\n",
|
59 |
-
"engine = create_engine(db_url)\n"
|
60 |
-
]
|
61 |
-
},
|
62 |
-
{
|
63 |
-
"cell_type": "code",
|
64 |
-
"execution_count": 14,
|
65 |
-
"metadata": {},
|
66 |
-
"outputs": [
|
67 |
-
{
|
68 |
-
"name": "stdout",
|
69 |
-
"output_type": "stream",
|
70 |
-
"text": [
|
71 |
-
"The autoreload extension is already loaded. To reload it, use:\n",
|
72 |
-
" %reload_ext autoreload\n"
|
73 |
-
]
|
74 |
-
}
|
75 |
-
],
|
76 |
-
"source": [
|
77 |
-
"%load_ext autoreload\n",
|
78 |
-
"%autoreload 2"
|
79 |
-
]
|
80 |
-
},
|
81 |
-
{
|
82 |
-
"cell_type": "code",
|
83 |
-
"execution_count": 2,
|
84 |
-
"metadata": {},
|
85 |
-
"outputs": [
|
86 |
-
{
|
87 |
-
"ename": "FileNotFoundError",
|
88 |
-
"evalue": "[Errno 2] No such file or directory: './data/p_profile.pkl'",
|
89 |
-
"output_type": "error",
|
90 |
-
"traceback": [
|
91 |
-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
92 |
-
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
|
93 |
-
"Cell \u001b[0;32mIn[2], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[39m## initialize by batchprocess to have initial result \u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m p_profile \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39;49mread_pickle(\u001b[39m'\u001b[39;49m\u001b[39m./data/p_profile.pkl\u001b[39;49m\u001b[39m'\u001b[39;49m)\n\u001b[1;32m 3\u001b[0m start_date \u001b[39m=\u001b[39m p_profile\u001b[39m.\u001b[39mdate\u001b[39m.\u001b[39mmin()\n\u001b[1;32m 4\u001b[0m end_date \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mto_datetime(datetime\u001b[39m.\u001b[39mnow()\u001b[39m-\u001b[39mtimedelta(days\u001b[39m=\u001b[39m\u001b[39m7\u001b[39m))\n",
|
94 |
-
"File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/portfolio_risk_assesment/lib/python3.11/site-packages/pandas/io/pickle.py:179\u001b[0m, in \u001b[0;36mread_pickle\u001b[0;34m(filepath_or_buffer, compression, storage_options)\u001b[0m\n\u001b[1;32m 115\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 116\u001b[0m \u001b[39mLoad pickled pandas object (or any object) from file.\u001b[39;00m\n\u001b[1;32m 117\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 176\u001b[0m \u001b[39m4 4 9\u001b[39;00m\n\u001b[1;32m 177\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 178\u001b[0m excs_to_catch \u001b[39m=\u001b[39m (\u001b[39mAttributeError\u001b[39;00m, \u001b[39mImportError\u001b[39;00m, \u001b[39mModuleNotFoundError\u001b[39;00m, \u001b[39mTypeError\u001b[39;00m)\n\u001b[0;32m--> 179\u001b[0m \u001b[39mwith\u001b[39;00m get_handle(\n\u001b[1;32m 180\u001b[0m filepath_or_buffer,\n\u001b[1;32m 181\u001b[0m \u001b[39m\"\u001b[39;49m\u001b[39mrb\u001b[39;49m\u001b[39m\"\u001b[39;49m,\n\u001b[1;32m 182\u001b[0m compression\u001b[39m=\u001b[39;49mcompression,\n\u001b[1;32m 183\u001b[0m is_text\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m 184\u001b[0m storage_options\u001b[39m=\u001b[39;49mstorage_options,\n\u001b[1;32m 185\u001b[0m ) \u001b[39mas\u001b[39;00m handles:\n\u001b[1;32m 186\u001b[0m \u001b[39m# 1) try standard library Pickle\u001b[39;00m\n\u001b[1;32m 187\u001b[0m \u001b[39m# 2) try pickle_compat (older pandas version) to handle subclass changes\u001b[39;00m\n\u001b[1;32m 188\u001b[0m \u001b[39m# 3) try pickle_compat with latin-1 encoding upon a UnicodeDecodeError\u001b[39;00m\n\u001b[1;32m 190\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 191\u001b[0m \u001b[39m# TypeError for Cython complaints about object.__new__ vs Tick.__new__\u001b[39;00m\n\u001b[1;32m 192\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
|
95 |
-
"File \u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/portfolio_risk_assesment/lib/python3.11/site-packages/pandas/io/common.py:868\u001b[0m, in \u001b[0;36mget_handle\u001b[0;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[1;32m 859\u001b[0m handle \u001b[39m=\u001b[39m \u001b[39mopen\u001b[39m(\n\u001b[1;32m 860\u001b[0m handle,\n\u001b[1;32m 861\u001b[0m ioargs\u001b[39m.\u001b[39mmode,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 864\u001b[0m newline\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m\"\u001b[39m,\n\u001b[1;32m 865\u001b[0m )\n\u001b[1;32m 866\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 867\u001b[0m \u001b[39m# Binary mode\u001b[39;00m\n\u001b[0;32m--> 868\u001b[0m handle \u001b[39m=\u001b[39m \u001b[39mopen\u001b[39;49m(handle, ioargs\u001b[39m.\u001b[39;49mmode)\n\u001b[1;32m 869\u001b[0m handles\u001b[39m.\u001b[39mappend(handle)\n\u001b[1;32m 871\u001b[0m \u001b[39m# Convert BytesIO or file objects passed with an encoding\u001b[39;00m\n",
|
96 |
-
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: './data/p_profile.pkl'"
|
97 |
-
]
|
98 |
-
}
|
99 |
-
],
|
100 |
-
"source": [
|
101 |
-
"## initialize by batchprocess to have initial result \n",
|
102 |
-
"p_profile = pd.read_pickle('./data/p_profile.pkl')\n",
|
103 |
-
"start_date = p_profile.date.min()\n",
|
104 |
-
"end_date = pd.to_datetime(datetime.now()-timedelta(days=7))\n",
|
105 |
-
"# collect data upto 7 days ago \n",
|
106 |
-
"b_profile, error = api.update_benchmark_profile(start_date, end_date)\n",
|
107 |
-
"p_stocks, error = api.get_stocks_price(p_profile, start_date, end_date)\n",
|
108 |
-
"b_stocks, error = api.get_stocks_price(b_profile, start_date, end_date)"
|
109 |
-
]
|
110 |
-
},
|
111 |
-
{
|
112 |
-
"cell_type": "code",
|
113 |
-
"execution_count": 13,
|
114 |
-
"metadata": {},
|
115 |
-
"outputs": [],
|
116 |
-
"source": [
|
117 |
-
"# save result \n",
|
118 |
-
"# p_profile.to_pickle('./data/p_profile.pkl')\n",
|
119 |
-
"# b_profile.to_pickle('./data/b_profile.pkl')\n",
|
120 |
-
"p_stocks.to_pickle('./data/p_stocks.pkl')\n",
|
121 |
-
"b_stocks.to_pickle('./data/b_stocks.pkl')\n"
|
122 |
-
]
|
123 |
-
},
|
124 |
-
{
|
125 |
-
"cell_type": "code",
|
126 |
-
"execution_count": 12,
|
127 |
-
"metadata": {},
|
128 |
-
"outputs": [
|
129 |
-
{
|
130 |
-
"name": "stderr",
|
131 |
-
"output_type": "stream",
|
132 |
-
"text": [
|
133 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:262: SettingWithCopyWarning: \n",
|
134 |
-
"A value is trying to be set on a copy of a slice from a DataFrame\n",
|
135 |
-
"\n",
|
136 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
137 |
-
" df.fillna(0, inplace=True)\n",
|
138 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:263: SettingWithCopyWarning: \n",
|
139 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
140 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
141 |
-
"\n",
|
142 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
143 |
-
" df['active_return'] = df.pct_p * \\\n",
|
144 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:266: SettingWithCopyWarning: \n",
|
145 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
146 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
147 |
-
"\n",
|
148 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
149 |
-
" df['allocation'] = (df.prev_w_in_p_p - df.prev_w_in_p_b) * df.pct_b\n",
|
150 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:267: SettingWithCopyWarning: \n",
|
151 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
152 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
153 |
-
"\n",
|
154 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
155 |
-
" df['selection'] = (df.pct_p - df.pct_b) * df.prev_w_in_p_b\n",
|
156 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:268: SettingWithCopyWarning: \n",
|
157 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
158 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
159 |
-
"\n",
|
160 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
161 |
-
" df['interaction'] = (df.pct_p - df.pct_b) * \\\n",
|
162 |
-
"/Users/lamonkey/Desktop/risk monitor/script/processing.py:270: SettingWithCopyWarning: \n",
|
163 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
164 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
165 |
-
"\n",
|
166 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
167 |
-
" df['notinal_return'] = df.allocation + df.selection + df.interaction\n"
|
168 |
-
]
|
169 |
-
}
|
170 |
-
],
|
171 |
-
"source": [
|
172 |
-
"## batch processing \n",
|
173 |
-
"calculated_p_stock = processing.get_processing_result_of_stocks_df(p_stocks, p_profile)\n",
|
174 |
-
"calculated_b_stock = processing.get_processing_result_of_stocks_df(b_stocks, b_profile)\n",
|
175 |
-
"p_eval_df = processing.get_portfolio_evaluation(calculated_p_stock, calculated_b_stock, p_profile)\n",
|
176 |
-
"sector_eval_df = processing.get_portfolio_sector_evaluation(calculated_p_stock, calculated_b_stock)\n",
|
177 |
-
"attribution_result_df = processing.calculate_total_attribution(calculated_p_stock, calculated_b_stock)\n",
|
178 |
-
"s_attribution_result_df = processing.calculate_total_attribution_by_sector(calculated_p_stock, calculated_b_stock)"
|
179 |
-
]
|
180 |
-
},
|
181 |
-
{
|
182 |
-
"cell_type": "code",
|
183 |
-
"execution_count": 15,
|
184 |
-
"metadata": {},
|
185 |
-
"outputs": [],
|
186 |
-
"source": [
|
187 |
-
"## save result to db\n",
|
188 |
-
"with engine.connect() as connection:\n",
|
189 |
-
" # all_stock_info.to_sql('all_stock_info', con=connection, if_exists='replace', index=False)\n",
|
190 |
-
" calculated_b_stock.to_sql('calculated_b_stock', con=connection, if_exists='replace', index=False)\n",
|
191 |
-
" calculated_p_stock.to_sql('calculated_p_stock', con=connection, if_exists='replace', index=False)\n",
|
192 |
-
" p_eval_df.to_sql('p_eval_result', con=connection, if_exists='replace', index=False)\n",
|
193 |
-
" sector_eval_df.to_sql('sector_eval_result', con=connection, if_exists='replace', index=False)\n",
|
194 |
-
" attribution_result_df.to_sql('attribution_result', con=connection, if_exists='replace', index=False)\n",
|
195 |
-
" s_attribution_result_df.to_sql('s_attribution_result', con=connection, if_exists='replace', index=False)"
|
196 |
-
]
|
197 |
-
},
|
198 |
-
{
|
199 |
-
"cell_type": "code",
|
200 |
-
"execution_count": 63,
|
201 |
-
"metadata": {},
|
202 |
-
"outputs": [],
|
203 |
-
"source": [
|
204 |
-
"# load from sql\n",
|
205 |
-
"name_df_map = dict()\n",
|
206 |
-
"with engine.connect() as connection:\n",
|
207 |
-
" for table in ['calculated_b_stock','calculated_p_stock','p_eval_result','sector_eval_result']:\n",
|
208 |
-
" try:\n",
|
209 |
-
" df = pd.read_sql_table(table, con=connection)\n",
|
210 |
-
" name_df_map[table] = df\n",
|
211 |
-
" except:\n",
|
212 |
-
" pass\n",
|
213 |
-
" # TODO load data from api and calculate result \n",
|
214 |
-
" "
|
215 |
-
]
|
216 |
-
},
|
217 |
-
{
|
218 |
-
"cell_type": "code",
|
219 |
-
"execution_count": 91,
|
220 |
-
"metadata": {},
|
221 |
-
"outputs": [],
|
222 |
-
"source": [
|
223 |
-
"# load data upto now\n",
|
224 |
-
"# Get the current time in UTC\n",
|
225 |
-
"current_time = datetime.datetime.utcnow()\n",
|
226 |
-
"# Set the timezone to Beijing\n",
|
227 |
-
"beijing_timezone = pytz.timezone('Asia/Shanghai')\n",
|
228 |
-
"# Convert the current time to Beijing time\n",
|
229 |
-
"end_time = pd.to_datetime(current_time.astimezone(beijing_timezone).date())\n",
|
230 |
-
"start_time = name_df_map['p_eval_result'].date.max() + timedelta(days=1)\n",
|
231 |
-
"\n",
|
232 |
-
"# get data up to today\n",
|
233 |
-
"b_profile, error = api.update_benchmark_profile(start_time, end_time)\n",
|
234 |
-
"p_stocks, error = api.get_stocks_price(p_profile, start_time, end_time)\n",
|
235 |
-
"b_stocks, error = api.get_stocks_price(b_profile, start_time, end_time)"
|
236 |
-
]
|
237 |
-
},
|
238 |
-
{
|
239 |
-
"cell_type": "code",
|
240 |
-
"execution_count": 185,
|
241 |
-
"metadata": {},
|
242 |
-
"outputs": [
|
243 |
-
{
|
244 |
-
"ename": "ValueError",
|
245 |
-
"evalue": "The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().",
|
246 |
-
"output_type": "error",
|
247 |
-
"traceback": [
|
248 |
-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
249 |
-
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
|
250 |
-
"\u001b[0;32m/var/folders/v5/2108rh5964q9j741wg_s8r1w0000gn/T/ipykernel_35506/2587190678.py\u001b[0m in \u001b[0;36m?\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmost_recent_df\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mname_df_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'calculated_p_stock'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'ticker'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlast\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreset_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mconcat_df\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconcat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmost_recent_df\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp_stocks\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjoin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'outer'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprocessing\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_processing_result_of_stocks_df\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconcat_df\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp_profile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
251 |
-
"\u001b[0;32m~/Desktop/risk monitor/script/processing.py\u001b[0m in \u001b[0;36m?\u001b[0;34m(stock_df, profile_df)\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrow\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miterrows\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0mcur_w\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'nan'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0;31m# if has initial weight, the following row all use this initial weight\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 42\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'initial_weight'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 43\u001b[0m \u001b[0mini_w\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'initial_weight'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[0mcur_w\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mini_w\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
|
252 |
-
"\u001b[0;32m/opt/homebrew/Caskroom/miniforge/base/envs/portfolio_risk_assesment/lib/python3.11/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m?\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1464\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mfinal\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1465\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__nonzero__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mNoReturn\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1466\u001b[0;31m raise ValueError(\n\u001b[0m\u001b[1;32m 1467\u001b[0m \u001b[0;34mf\"The truth value of a {type(self).__name__} is ambiguous. \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1468\u001b[0m \u001b[0;34m\"Use a.empty, a.bool(), a.item(), a.any() or a.all().\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1469\u001b[0m )\n",
|
253 |
-
"\u001b[0;31mValueError\u001b[0m: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()."
|
254 |
-
]
|
255 |
-
}
|
256 |
-
],
|
257 |
-
"source": [
|
258 |
-
"most_recent_df = name_df_map['calculated_p_stock'].groupby('ticker').last().reset_index()\n",
|
259 |
-
"concat_df = pd.concat([most_recent_df, p_stocks], axis=0, join='outer')\n",
|
260 |
-
"processing.get_processing_result_of_stocks_df(concat_df, p_profile)"
|
261 |
-
]
|
262 |
-
},
|
263 |
-
{
|
264 |
-
"cell_type": "code",
|
265 |
-
"execution_count": 182,
|
266 |
-
"metadata": {},
|
267 |
-
"outputs": [
|
268 |
-
{
|
269 |
-
"data": {
|
270 |
-
"text/html": [
|
271 |
-
"<div>\n",
|
272 |
-
"<style scoped>\n",
|
273 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
274 |
-
" vertical-align: middle;\n",
|
275 |
-
" }\n",
|
276 |
-
"\n",
|
277 |
-
" .dataframe tbody tr th {\n",
|
278 |
-
" vertical-align: top;\n",
|
279 |
-
" }\n",
|
280 |
-
"\n",
|
281 |
-
" .dataframe thead th {\n",
|
282 |
-
" text-align: right;\n",
|
283 |
-
" }\n",
|
284 |
-
"</style>\n",
|
285 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
286 |
-
" <thead>\n",
|
287 |
-
" <tr style=\"text-align: right;\">\n",
|
288 |
-
" <th></th>\n",
|
289 |
-
" <th>date</th>\n",
|
290 |
-
" <th>ticker</th>\n",
|
291 |
-
" <th>open</th>\n",
|
292 |
-
" <th>close</th>\n",
|
293 |
-
" <th>high</th>\n",
|
294 |
-
" <th>low</th>\n",
|
295 |
-
" <th>volume</th>\n",
|
296 |
-
" <th>money</th>\n",
|
297 |
-
" <th>display_name</th>\n",
|
298 |
-
" <th>name</th>\n",
|
299 |
-
" <th>...</th>\n",
|
300 |
-
" <th>portfolio_pct</th>\n",
|
301 |
-
" <th>prev_w_in_sectore</th>\n",
|
302 |
-
" <th>ini_w_in_sector</th>\n",
|
303 |
-
" <th>sector_pct</th>\n",
|
304 |
-
" <th>portfolio_return</th>\n",
|
305 |
-
" <th>cum_pct</th>\n",
|
306 |
-
" <th>return</th>\n",
|
307 |
-
" <th>sector_return</th>\n",
|
308 |
-
" <th>cur_w_in_p</th>\n",
|
309 |
-
" <th>pre_w_in_sector</th>\n",
|
310 |
-
" </tr>\n",
|
311 |
-
" </thead>\n",
|
312 |
-
" <tbody>\n",
|
313 |
-
" <tr>\n",
|
314 |
-
" <th>0</th>\n",
|
315 |
-
" <td>2021-01-05</td>\n",
|
316 |
-
" <td>600409.XSHG</td>\n",
|
317 |
-
" <td>9.23</td>\n",
|
318 |
-
" <td>9.57</td>\n",
|
319 |
-
" <td>9.66</td>\n",
|
320 |
-
" <td>9.08</td>\n",
|
321 |
-
" <td>82669289.0</td>\n",
|
322 |
-
" <td>7.803391e+08</td>\n",
|
323 |
-
" <td>三友化工</td>\n",
|
324 |
-
" <td>SYHG</td>\n",
|
325 |
-
" <td>...</td>\n",
|
326 |
-
" <td>NaN</td>\n",
|
327 |
-
" <td>NaN</td>\n",
|
328 |
-
" <td>1.0</td>\n",
|
329 |
-
" <td>NaN</td>\n",
|
330 |
-
" <td>NaN</td>\n",
|
331 |
-
" <td>NaN</td>\n",
|
332 |
-
" <td>NaN</td>\n",
|
333 |
-
" <td>NaN</td>\n",
|
334 |
-
" <td>NaN</td>\n",
|
335 |
-
" <td>NaN</td>\n",
|
336 |
-
" </tr>\n",
|
337 |
-
" <tr>\n",
|
338 |
-
" <th>1</th>\n",
|
339 |
-
" <td>2021-01-05</td>\n",
|
340 |
-
" <td>300274.XSHE</td>\n",
|
341 |
-
" <td>76.03</td>\n",
|
342 |
-
" <td>76.45</td>\n",
|
343 |
-
" <td>80.20</td>\n",
|
344 |
-
" <td>75.27</td>\n",
|
345 |
-
" <td>51384827.0</td>\n",
|
346 |
-
" <td>3.961995e+09</td>\n",
|
347 |
-
" <td>阳光电源</td>\n",
|
348 |
-
" <td>YGDY</td>\n",
|
349 |
-
" <td>...</td>\n",
|
350 |
-
" <td>NaN</td>\n",
|
351 |
-
" <td>NaN</td>\n",
|
352 |
-
" <td>0.5</td>\n",
|
353 |
-
" <td>NaN</td>\n",
|
354 |
-
" <td>NaN</td>\n",
|
355 |
-
" <td>NaN</td>\n",
|
356 |
-
" <td>NaN</td>\n",
|
357 |
-
" <td>NaN</td>\n",
|
358 |
-
" <td>NaN</td>\n",
|
359 |
-
" <td>NaN</td>\n",
|
360 |
-
" </tr>\n",
|
361 |
-
" <tr>\n",
|
362 |
-
" <th>2</th>\n",
|
363 |
-
" <td>2021-01-05</td>\n",
|
364 |
-
" <td>002920.XSHE</td>\n",
|
365 |
-
" <td>85.44</td>\n",
|
366 |
-
" <td>87.25</td>\n",
|
367 |
-
" <td>87.95</td>\n",
|
368 |
-
" <td>84.07</td>\n",
|
369 |
-
" <td>3852674.0</td>\n",
|
370 |
-
" <td>3.322598e+08</td>\n",
|
371 |
-
" <td>德赛西威</td>\n",
|
372 |
-
" <td>DSXW</td>\n",
|
373 |
-
" <td>...</td>\n",
|
374 |
-
" <td>NaN</td>\n",
|
375 |
-
" <td>NaN</td>\n",
|
376 |
-
" <td>1.0</td>\n",
|
377 |
-
" <td>NaN</td>\n",
|
378 |
-
" <td>NaN</td>\n",
|
379 |
-
" <td>NaN</td>\n",
|
380 |
-
" <td>NaN</td>\n",
|
381 |
-
" <td>NaN</td>\n",
|
382 |
-
" <td>NaN</td>\n",
|
383 |
-
" <td>NaN</td>\n",
|
384 |
-
" </tr>\n",
|
385 |
-
" <tr>\n",
|
386 |
-
" <th>3</th>\n",
|
387 |
-
" <td>2021-01-05</td>\n",
|
388 |
-
" <td>002709.XSHE</td>\n",
|
389 |
-
" <td>32.54</td>\n",
|
390 |
-
" <td>33.89</td>\n",
|
391 |
-
" <td>34.22</td>\n",
|
392 |
-
" <td>31.39</td>\n",
|
393 |
-
" <td>59152352.0</td>\n",
|
394 |
-
" <td>1.942406e+09</td>\n",
|
395 |
-
" <td>天赐材料</td>\n",
|
396 |
-
" <td>TCCL</td>\n",
|
397 |
-
" <td>...</td>\n",
|
398 |
-
" <td>NaN</td>\n",
|
399 |
-
" <td>NaN</td>\n",
|
400 |
-
" <td>0.5</td>\n",
|
401 |
-
" <td>NaN</td>\n",
|
402 |
-
" <td>NaN</td>\n",
|
403 |
-
" <td>NaN</td>\n",
|
404 |
-
" <td>NaN</td>\n",
|
405 |
-
" <td>NaN</td>\n",
|
406 |
-
" <td>NaN</td>\n",
|
407 |
-
" <td>NaN</td>\n",
|
408 |
-
" </tr>\n",
|
409 |
-
" <tr>\n",
|
410 |
-
" <th>4</th>\n",
|
411 |
-
" <td>2021-01-05</td>\n",
|
412 |
-
" <td>603882.XSHG</td>\n",
|
413 |
-
" <td>125.25</td>\n",
|
414 |
-
" <td>124.64</td>\n",
|
415 |
-
" <td>128.31</td>\n",
|
416 |
-
" <td>121.68</td>\n",
|
417 |
-
" <td>6803710.0</td>\n",
|
418 |
-
" <td>8.458543e+08</td>\n",
|
419 |
-
" <td>金域医学</td>\n",
|
420 |
-
" <td>JYYX</td>\n",
|
421 |
-
" <td>...</td>\n",
|
422 |
-
" <td>NaN</td>\n",
|
423 |
-
" <td>NaN</td>\n",
|
424 |
-
" <td>1.0</td>\n",
|
425 |
-
" <td>NaN</td>\n",
|
426 |
-
" <td>NaN</td>\n",
|
427 |
-
" <td>NaN</td>\n",
|
428 |
-
" <td>NaN</td>\n",
|
429 |
-
" <td>NaN</td>\n",
|
430 |
-
" <td>NaN</td>\n",
|
431 |
-
" <td>NaN</td>\n",
|
432 |
-
" </tr>\n",
|
433 |
-
" <tr>\n",
|
434 |
-
" <th>...</th>\n",
|
435 |
-
" <td>...</td>\n",
|
436 |
-
" <td>...</td>\n",
|
437 |
-
" <td>...</td>\n",
|
438 |
-
" <td>...</td>\n",
|
439 |
-
" <td>...</td>\n",
|
440 |
-
" <td>...</td>\n",
|
441 |
-
" <td>...</td>\n",
|
442 |
-
" <td>...</td>\n",
|
443 |
-
" <td>...</td>\n",
|
444 |
-
" <td>...</td>\n",
|
445 |
-
" <td>...</td>\n",
|
446 |
-
" <td>...</td>\n",
|
447 |
-
" <td>...</td>\n",
|
448 |
-
" <td>...</td>\n",
|
449 |
-
" <td>...</td>\n",
|
450 |
-
" <td>...</td>\n",
|
451 |
-
" <td>...</td>\n",
|
452 |
-
" <td>...</td>\n",
|
453 |
-
" <td>...</td>\n",
|
454 |
-
" <td>...</td>\n",
|
455 |
-
" <td>...</td>\n",
|
456 |
-
" </tr>\n",
|
457 |
-
" <tr>\n",
|
458 |
-
" <th>3609</th>\n",
|
459 |
-
" <td>2023-06-27</td>\n",
|
460 |
-
" <td>600415.XSHG</td>\n",
|
461 |
-
" <td>8.52</td>\n",
|
462 |
-
" <td>8.69</td>\n",
|
463 |
-
" <td>8.78</td>\n",
|
464 |
-
" <td>8.40</td>\n",
|
465 |
-
" <td>151396630.0</td>\n",
|
466 |
-
" <td>1.305075e+09</td>\n",
|
467 |
-
" <td>小商品城</td>\n",
|
468 |
-
" <td>XSPC</td>\n",
|
469 |
-
" <td>...</td>\n",
|
470 |
-
" <td>NaN</td>\n",
|
471 |
-
" <td>NaN</td>\n",
|
472 |
-
" <td>NaN</td>\n",
|
473 |
-
" <td>0.027187</td>\n",
|
474 |
-
" <td>NaN</td>\n",
|
475 |
-
" <td>NaN</td>\n",
|
476 |
-
" <td>NaN</td>\n",
|
477 |
-
" <td>NaN</td>\n",
|
478 |
-
" <td>0.301143</td>\n",
|
479 |
-
" <td>1.0</td>\n",
|
480 |
-
" </tr>\n",
|
481 |
-
" <tr>\n",
|
482 |
-
" <th>3610</th>\n",
|
483 |
-
" <td>2023-06-28</td>\n",
|
484 |
-
" <td>600415.XSHG</td>\n",
|
485 |
-
" <td>8.60</td>\n",
|
486 |
-
" <td>8.63</td>\n",
|
487 |
-
" <td>8.68</td>\n",
|
488 |
-
" <td>8.37</td>\n",
|
489 |
-
" <td>103167271.0</td>\n",
|
490 |
-
" <td>8.798186e+08</td>\n",
|
491 |
-
" <td>小商品城</td>\n",
|
492 |
-
" <td>XSPC</td>\n",
|
493 |
-
" <td>...</td>\n",
|
494 |
-
" <td>NaN</td>\n",
|
495 |
-
" <td>NaN</td>\n",
|
496 |
-
" <td>NaN</td>\n",
|
497 |
-
" <td>-0.006904</td>\n",
|
498 |
-
" <td>NaN</td>\n",
|
499 |
-
" <td>NaN</td>\n",
|
500 |
-
" <td>NaN</td>\n",
|
501 |
-
" <td>NaN</td>\n",
|
502 |
-
" <td>0.299958</td>\n",
|
503 |
-
" <td>1.0</td>\n",
|
504 |
-
" </tr>\n",
|
505 |
-
" <tr>\n",
|
506 |
-
" <th>3611</th>\n",
|
507 |
-
" <td>2023-06-29</td>\n",
|
508 |
-
" <td>600415.XSHG</td>\n",
|
509 |
-
" <td>8.60</td>\n",
|
510 |
-
" <td>8.74</td>\n",
|
511 |
-
" <td>8.88</td>\n",
|
512 |
-
" <td>8.58</td>\n",
|
513 |
-
" <td>128969467.0</td>\n",
|
514 |
-
" <td>1.125704e+09</td>\n",
|
515 |
-
" <td>小商品城</td>\n",
|
516 |
-
" <td>XSPC</td>\n",
|
517 |
-
" <td>...</td>\n",
|
518 |
-
" <td>NaN</td>\n",
|
519 |
-
" <td>NaN</td>\n",
|
520 |
-
" <td>NaN</td>\n",
|
521 |
-
" <td>0.012746</td>\n",
|
522 |
-
" <td>NaN</td>\n",
|
523 |
-
" <td>NaN</td>\n",
|
524 |
-
" <td>NaN</td>\n",
|
525 |
-
" <td>NaN</td>\n",
|
526 |
-
" <td>0.301804</td>\n",
|
527 |
-
" <td>1.0</td>\n",
|
528 |
-
" </tr>\n",
|
529 |
-
" <tr>\n",
|
530 |
-
" <th>3612</th>\n",
|
531 |
-
" <td>2023-06-30</td>\n",
|
532 |
-
" <td>600415.XSHG</td>\n",
|
533 |
-
" <td>8.74</td>\n",
|
534 |
-
" <td>8.53</td>\n",
|
535 |
-
" <td>8.77</td>\n",
|
536 |
-
" <td>8.48</td>\n",
|
537 |
-
" <td>103029932.0</td>\n",
|
538 |
-
" <td>8.844883e+08</td>\n",
|
539 |
-
" <td>小商品城</td>\n",
|
540 |
-
" <td>XSPC</td>\n",
|
541 |
-
" <td>...</td>\n",
|
542 |
-
" <td>NaN</td>\n",
|
543 |
-
" <td>NaN</td>\n",
|
544 |
-
" <td>NaN</td>\n",
|
545 |
-
" <td>-0.024027</td>\n",
|
546 |
-
" <td>NaN</td>\n",
|
547 |
-
" <td>NaN</td>\n",
|
548 |
-
" <td>NaN</td>\n",
|
549 |
-
" <td>NaN</td>\n",
|
550 |
-
" <td>0.293612</td>\n",
|
551 |
-
" <td>1.0</td>\n",
|
552 |
-
" </tr>\n",
|
553 |
-
" <tr>\n",
|
554 |
-
" <th>3613</th>\n",
|
555 |
-
" <td>2023-07-03</td>\n",
|
556 |
-
" <td>600415.XSHG</td>\n",
|
557 |
-
" <td>8.45</td>\n",
|
558 |
-
" <td>8.37</td>\n",
|
559 |
-
" <td>8.46</td>\n",
|
560 |
-
" <td>8.05</td>\n",
|
561 |
-
" <td>133732493.0</td>\n",
|
562 |
-
" <td>1.108033e+09</td>\n",
|
563 |
-
" <td>小商品城</td>\n",
|
564 |
-
" <td>XSPC</td>\n",
|
565 |
-
" <td>...</td>\n",
|
566 |
-
" <td>NaN</td>\n",
|
567 |
-
" <td>NaN</td>\n",
|
568 |
-
" <td>NaN</td>\n",
|
569 |
-
" <td>-0.018757</td>\n",
|
570 |
-
" <td>NaN</td>\n",
|
571 |
-
" <td>NaN</td>\n",
|
572 |
-
" <td>NaN</td>\n",
|
573 |
-
" <td>NaN</td>\n",
|
574 |
-
" <td>0.286010</td>\n",
|
575 |
-
" <td>1.0</td>\n",
|
576 |
-
" </tr>\n",
|
577 |
-
" </tbody>\n",
|
578 |
-
"</table>\n",
|
579 |
-
"<p>3614 rows × 27 columns</p>\n",
|
580 |
-
"</div>"
|
581 |
-
],
|
582 |
-
"text/plain": [
|
583 |
-
" date ticker open close high low volume \\\n",
|
584 |
-
"0 2021-01-05 600409.XSHG 9.23 9.57 9.66 9.08 82669289.0 \n",
|
585 |
-
"1 2021-01-05 300274.XSHE 76.03 76.45 80.20 75.27 51384827.0 \n",
|
586 |
-
"2 2021-01-05 002920.XSHE 85.44 87.25 87.95 84.07 3852674.0 \n",
|
587 |
-
"3 2021-01-05 002709.XSHE 32.54 33.89 34.22 31.39 59152352.0 \n",
|
588 |
-
"4 2021-01-05 603882.XSHG 125.25 124.64 128.31 121.68 6803710.0 \n",
|
589 |
-
"... ... ... ... ... ... ... ... \n",
|
590 |
-
"3609 2023-06-27 600415.XSHG 8.52 8.69 8.78 8.40 151396630.0 \n",
|
591 |
-
"3610 2023-06-28 600415.XSHG 8.60 8.63 8.68 8.37 103167271.0 \n",
|
592 |
-
"3611 2023-06-29 600415.XSHG 8.60 8.74 8.88 8.58 128969467.0 \n",
|
593 |
-
"3612 2023-06-30 600415.XSHG 8.74 8.53 8.77 8.48 103029932.0 \n",
|
594 |
-
"3613 2023-07-03 600415.XSHG 8.45 8.37 8.46 8.05 133732493.0 \n",
|
595 |
-
"\n",
|
596 |
-
" money display_name name ... portfolio_pct prev_w_in_sectore \\\n",
|
597 |
-
"0 7.803391e+08 三友化工 SYHG ... NaN NaN \n",
|
598 |
-
"1 3.961995e+09 阳光电源 YGDY ... NaN NaN \n",
|
599 |
-
"2 3.322598e+08 德赛西威 DSXW ... NaN NaN \n",
|
600 |
-
"3 1.942406e+09 天赐材料 TCCL ... NaN NaN \n",
|
601 |
-
"4 8.458543e+08 金域医学 JYYX ... NaN NaN \n",
|
602 |
-
"... ... ... ... ... ... ... \n",
|
603 |
-
"3609 1.305075e+09 小商品城 XSPC ... NaN NaN \n",
|
604 |
-
"3610 8.798186e+08 小商品城 XSPC ... NaN NaN \n",
|
605 |
-
"3611 1.125704e+09 小商品城 XSPC ... NaN NaN \n",
|
606 |
-
"3612 8.844883e+08 小商品城 XSPC ... NaN NaN \n",
|
607 |
-
"3613 1.108033e+09 小商品城 XSPC ... NaN NaN \n",
|
608 |
-
"\n",
|
609 |
-
" ini_w_in_sector sector_pct portfolio_return cum_pct return \\\n",
|
610 |
-
"0 1.0 NaN NaN NaN NaN \n",
|
611 |
-
"1 0.5 NaN NaN NaN NaN \n",
|
612 |
-
"2 1.0 NaN NaN NaN NaN \n",
|
613 |
-
"3 0.5 NaN NaN NaN NaN \n",
|
614 |
-
"4 1.0 NaN NaN NaN NaN \n",
|
615 |
-
"... ... ... ... ... ... \n",
|
616 |
-
"3609 NaN 0.027187 NaN NaN NaN \n",
|
617 |
-
"3610 NaN -0.006904 NaN NaN NaN \n",
|
618 |
-
"3611 NaN 0.012746 NaN NaN NaN \n",
|
619 |
-
"3612 NaN -0.024027 NaN NaN NaN \n",
|
620 |
-
"3613 NaN -0.018757 NaN NaN NaN \n",
|
621 |
-
"\n",
|
622 |
-
" sector_return cur_w_in_p pre_w_in_sector \n",
|
623 |
-
"0 NaN NaN NaN \n",
|
624 |
-
"1 NaN NaN NaN \n",
|
625 |
-
"2 NaN NaN NaN \n",
|
626 |
-
"3 NaN NaN NaN \n",
|
627 |
-
"4 NaN NaN NaN \n",
|
628 |
-
"... ... ... ... \n",
|
629 |
-
"3609 NaN 0.301143 1.0 \n",
|
630 |
-
"3610 NaN 0.299958 1.0 \n",
|
631 |
-
"3611 NaN 0.301804 1.0 \n",
|
632 |
-
"3612 NaN 0.293612 1.0 \n",
|
633 |
-
"3613 NaN 0.286010 1.0 \n",
|
634 |
-
"\n",
|
635 |
-
"[3614 rows x 27 columns]"
|
636 |
-
]
|
637 |
-
},
|
638 |
-
"execution_count": 182,
|
639 |
-
"metadata": {},
|
640 |
-
"output_type": "execute_result"
|
641 |
-
}
|
642 |
-
],
|
643 |
-
"source": [
|
644 |
-
"most_recent_df = name_df_map['calculated_p_stock'].groupby('ticker').last().reset_index()\n",
|
645 |
-
"\n",
|
646 |
-
"def get_last_values(row):\n",
|
647 |
-
" ticker = row['ticker']\n",
|
648 |
-
" if ticker in p_profile['ticker'].values:\n",
|
649 |
-
" return p_profile.loc[p_profile['ticker'] == ticker, ['display_name', 'name', 'aggregate_sector']].iloc[-1]\n",
|
650 |
-
" else:\n",
|
651 |
-
" return pd.Series([np.nan, np.nan, np.nan], index=['display_name', 'name', 'aggregate_sector'])\n",
|
652 |
-
"# dispaly_name, name and aggregate_sector\n",
|
653 |
-
"p_stocks[['display_name', 'name', 'aggregate_sector']] = p_stocks.apply(get_last_values, axis=1)\n",
|
654 |
-
"\n",
|
655 |
-
"# use the most recent result to resume calculation\n",
|
656 |
-
"concat_df = pd.concat([most_recent_df, p_stocks], axis=0, join='outer')\n",
|
657 |
-
"\n",
|
658 |
-
"# pct\n",
|
659 |
-
"concat_df['pct'] = concat_df.groupby('ticker')['close'].pct_change()\n",
|
660 |
-
"\n",
|
661 |
-
"# calculate not normalized previous weight and current weight\n",
|
662 |
-
"groups = concat_df.groupby('ticker')\n",
|
663 |
-
"for _, group in groups:\n",
|
664 |
-
" cur_weight = np.nan\n",
|
665 |
-
" for index, row in group.iterrows():\n",
|
666 |
-
" if pd.notna(row['current_weight']):\n",
|
667 |
-
" cur_weight = row['current_weight']\n",
|
668 |
-
" else:\n",
|
669 |
-
" concat_df.loc[index, 'previous_weight'] = cur_weight\n",
|
670 |
-
" cur_weight = cur_weight * (1 + row['pct'])\n",
|
671 |
-
" concat_df.loc[index, 'current_weight'] = cur_weight\n",
|
672 |
-
"\n",
|
673 |
-
"# calculate normalized previous and current weight\n",
|
674 |
-
"concat_df['prev_w_in_p'] = concat_df['previous_weight'] / \\\n",
|
675 |
-
" concat_df.groupby('date')['previous_weight'].transform('sum')\n",
|
676 |
-
"concat_df['cur_w_in_p'] = concat_df['current_weight'] / \\\n",
|
677 |
-
" concat_df.groupby('date')['current_weight'].transform('sum')\n",
|
678 |
-
"\n",
|
679 |
-
"# calculate previous weight in sector\n",
|
680 |
-
"concat_df['pre_w_in_sector'] = concat_df['prev_w_in_p'] / \\\n",
|
681 |
-
" concat_df.groupby(['date', 'aggregate_sector'])['prev_w_in_p'].transform('sum')\n",
|
682 |
-
"\n",
|
683 |
-
"# calculate pct in sector\n",
|
684 |
-
"concat_df['sector_pct'] = concat_df['pct'] * concat_df['pre_w_in_sector']\n",
|
685 |
-
"\n",
|
686 |
-
"\n",
|
687 |
-
"\n",
|
688 |
-
"\n",
|
689 |
-
"\n",
|
690 |
-
"# remove group with first date\n",
|
691 |
-
"min_date_group = concat_df.groupby('date')['date'].idxmin()\n",
|
692 |
-
"concat_df = concat_df.drop(min_date_group)\n",
|
693 |
-
"\n",
|
694 |
-
"# merge back to calculated_stock\n",
|
695 |
-
"pd.concat([name_df_map['calculated_p_stock'],concat_df]).reset_index(drop=True)\n",
|
696 |
-
"\n",
|
697 |
-
"# concat_df[concat_df.ticker == '002709.XSHE'][['date','pct','current_weight','previous_weight','prev_w_in_p','cur_w_in_p']]"
|
698 |
-
]
|
699 |
-
}
|
700 |
-
],
|
701 |
-
"metadata": {
|
702 |
-
"kernelspec": {
|
703 |
-
"display_name": "portfolio_risk_assesment",
|
704 |
-
"language": "python",
|
705 |
-
"name": "python3"
|
706 |
-
},
|
707 |
-
"language_info": {
|
708 |
-
"codemirror_mode": {
|
709 |
-
"name": "ipython",
|
710 |
-
"version": 3
|
711 |
-
},
|
712 |
-
"file_extension": ".py",
|
713 |
-
"mimetype": "text/x-python",
|
714 |
-
"name": "python",
|
715 |
-
"nbconvert_exporter": "python",
|
716 |
-
"pygments_lexer": "ipython3",
|
717 |
-
"version": "3.11.4"
|
718 |
-
},
|
719 |
-
"orig_nbformat": 4
|
720 |
-
},
|
721 |
-
"nbformat": 4,
|
722 |
-
"nbformat_minor": 2
|
723 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/description.py → description.py
RENAMED
@@ -3,6 +3,7 @@ This file store the tooltip to show in the GUI
|
|
3 |
|
4 |
'''
|
5 |
#周期回报
|
|
|
6 |
periodic_return_report = '''
|
7 |
选择周期查看每个周期的回报率,以及每个周期主动回报的归因。
|
8 |
周期回报的数据点代表周期结束。
|
|
|
3 |
|
4 |
'''
|
5 |
#周期回报
|
6 |
+
|
7 |
periodic_return_report = '''
|
8 |
选择周期查看每个周期的回报率,以及每个周期主动回报的归因。
|
9 |
周期回报的数据点代表周期结束。
|
index_page.py
CHANGED
@@ -1,57 +1,35 @@
|
|
1 |
import panel as pn
|
2 |
-
import pandas as pd
|
3 |
-
from datetime import datetime, timedelta
|
4 |
-
import plotly.express as px
|
5 |
-
import holoviews as hv
|
6 |
-
import numpy as np
|
7 |
from sidebar import SideNavBar
|
8 |
-
import random
|
9 |
-
import scipy.stats as stats
|
10 |
-
import hvplot.pandas # noqa
|
11 |
from sqlalchemy import create_engine
|
12 |
-
import api
|
13 |
-
# from backgroundTask import stocks_stream
|
14 |
-
from functools import partial
|
15 |
-
import plotly.graph_objects as go
|
16 |
-
from panel.viewable import Viewer
|
17 |
-
import processing
|
18 |
import appComponents
|
19 |
-
import param
|
20 |
import db_operation as db
|
21 |
-
|
22 |
pn.extension('mathjax')
|
23 |
-
|
24 |
pn.extension('plotly')
|
25 |
pn.extension('tabulator')
|
26 |
db_url = 'sqlite:///instance/local.db'
|
27 |
engine = create_engine(db_url)
|
28 |
|
29 |
|
30 |
-
|
31 |
analytic_p = db.get_portfolio_analytic_df()
|
32 |
analytic_b = db.get_benchmark_analytic_df()
|
33 |
-
# load benchmark stock
|
34 |
-
# with engine.connect() as connection:
|
35 |
-
# analytics_df = pd.read
|
36 |
-
# calculated_b_stock = pd.read_sql('calculated_b_stock', con=connection)
|
37 |
-
# calculated_p_stock = pd.read_sql('calculated_p_stock', con=connection)
|
38 |
-
# p_eval_df = pd.read_sql('p_eval_result', con=connection)
|
39 |
|
40 |
stock_overview = appComponents.BestAndWorstStocks(
|
41 |
analytic_df=analytic_p)
|
42 |
composation_card = appComponents.PortfolioComposationCard(
|
43 |
analytic_p)
|
44 |
monthly_return_card = appComponents.HistReturnCard(
|
45 |
-
|
46 |
-
total_return_card = appComponents.TotalReturnCard(name='Range',
|
47 |
b_stock_df=analytic_b,
|
48 |
p_stock_df=analytic_p,
|
49 |
value=(0, 20))
|
50 |
drawdown_card = appComponents.DrawDownCard(
|
51 |
-
|
52 |
|
53 |
top_header = appComponents.TopHeader(
|
54 |
-
eval_df
|
55 |
)
|
56 |
|
57 |
template = pn.template.FastListTemplate(
|
|
|
1 |
import panel as pn
|
|
|
|
|
|
|
|
|
|
|
2 |
from sidebar import SideNavBar
|
|
|
|
|
|
|
3 |
from sqlalchemy import create_engine
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import appComponents
|
|
|
5 |
import db_operation as db
|
6 |
+
|
7 |
pn.extension('mathjax')
|
8 |
+
|
9 |
pn.extension('plotly')
|
10 |
pn.extension('tabulator')
|
11 |
db_url = 'sqlite:///instance/local.db'
|
12 |
engine = create_engine(db_url)
|
13 |
|
14 |
|
|
|
15 |
analytic_p = db.get_portfolio_analytic_df()
|
16 |
analytic_b = db.get_benchmark_analytic_df()
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
stock_overview = appComponents.BestAndWorstStocks(
|
19 |
analytic_df=analytic_p)
|
20 |
composation_card = appComponents.PortfolioComposationCard(
|
21 |
analytic_p)
|
22 |
monthly_return_card = appComponents.HistReturnCard(
|
23 |
+
calculated_p_stock=analytic_p, calculated_b_stock=analytic_b)
|
24 |
+
total_return_card = appComponents.TotalReturnCard(name='Range',
|
25 |
b_stock_df=analytic_b,
|
26 |
p_stock_df=analytic_p,
|
27 |
value=(0, 20))
|
28 |
drawdown_card = appComponents.DrawDownCard(
|
29 |
+
calculated_p_stock=analytic_p)
|
30 |
|
31 |
top_header = appComponents.TopHeader(
|
32 |
+
eval_df=analytic_p,
|
33 |
)
|
34 |
|
35 |
template = pn.template.FastListTemplate(
|
instance/local.db
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:77911978f609eea6d1dc9285228549b79a1f05a040207d28af2abb4fe7a37063
|
3 |
+
size 261677056
|
pipeline.py
CHANGED
@@ -12,7 +12,7 @@ import processing
|
|
12 |
# import settings
|
13 |
# fetch new stock price
|
14 |
stock_price_stream = Stream()
|
15 |
-
|
16 |
|
17 |
# log
|
18 |
log = Log('instance/log.json')
|
@@ -187,7 +187,9 @@ def save_stock_price_to_db(df: pd.DataFrame):
|
|
187 |
|
188 |
|
189 |
def update_portfolio_profile_to_db(portfolio_df):
|
190 |
-
'''overwrite the portfolio profile table in db
|
|
|
|
|
191 |
|
192 |
if (_validate_schema(portfolio_df, ts.PORTFOLIO_TABLE_SCHEMA)):
|
193 |
raise ValueError(
|
@@ -198,10 +200,14 @@ def update_portfolio_profile_to_db(portfolio_df):
|
|
198 |
try:
|
199 |
portfolio_df[ts.PORTFOLIO_TABLE_SCHEMA.keys()].to_sql(
|
200 |
ts.PORTFOLIO_TABLE, con=conn, if_exists='append', index=False)
|
|
|
|
|
|
|
|
|
201 |
return True
|
202 |
except:
|
203 |
return False
|
204 |
-
|
205 |
|
206 |
|
207 |
def right_fill_stock_price():
|
@@ -413,6 +419,26 @@ def batch_processing():
|
|
413 |
db.save_benchmark_analytic_df(analytic_b)
|
414 |
|
415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
async def daily_update():
|
417 |
'''
|
418 |
left and right fill stock price and benchmark weight based on portfolio
|
@@ -423,7 +449,7 @@ async def daily_update():
|
|
423 |
|
424 |
'''
|
425 |
last_update = log.get_time('daily_update')
|
426 |
-
#
|
427 |
if last_update is None or utils.time_in_beijing() - last_update >= dt.timedelta(days=1):
|
428 |
print("running daily update")
|
429 |
|
@@ -475,16 +501,11 @@ async def run():
|
|
475 |
# print(stock_df)
|
476 |
stock_price_stream.emit(stock_df)
|
477 |
|
478 |
-
# # latest stock price
|
479 |
-
# stock_df = update_stocks_price()
|
480 |
-
# # add display name and sector to stock_df
|
481 |
-
# stock_df = add_details_to_stock_df(stock_df)
|
482 |
-
# save_stock_price_to_db(stock_df)
|
483 |
-
# stock_price_stream.emit(stock_df)
|
484 |
-
# update sotck_price
|
485 |
-
|
486 |
-
# send fetched data
|
487 |
|
488 |
-
|
|
|
|
|
|
|
|
|
489 |
|
490 |
-
|
|
|
12 |
# import settings
|
13 |
# fetch new stock price
|
14 |
stock_price_stream = Stream()
|
15 |
+
event = Stream()
|
16 |
|
17 |
# log
|
18 |
log = Log('instance/log.json')
|
|
|
187 |
|
188 |
|
189 |
def update_portfolio_profile_to_db(portfolio_df):
|
190 |
+
'''overwrite the portfolio profile table in db, and trigger a left fill on benchmark, stock price
|
191 |
+
and recomputation of analysis
|
192 |
+
'''
|
193 |
|
194 |
if (_validate_schema(portfolio_df, ts.PORTFOLIO_TABLE_SCHEMA)):
|
195 |
raise ValueError(
|
|
|
200 |
try:
|
201 |
portfolio_df[ts.PORTFOLIO_TABLE_SCHEMA.keys()].to_sql(
|
202 |
ts.PORTFOLIO_TABLE, con=conn, if_exists='append', index=False)
|
203 |
+
|
204 |
+
event.emit('update_portfolio')
|
205 |
+
# handle_portfolio_update()
|
206 |
+
|
207 |
return True
|
208 |
except:
|
209 |
return False
|
210 |
+
|
211 |
|
212 |
|
213 |
def right_fill_stock_price():
|
|
|
419 |
db.save_benchmark_analytic_df(analytic_b)
|
420 |
|
421 |
|
422 |
+
def left_fill():
|
423 |
+
left_fill_benchmark_profile()
|
424 |
+
left_fill_stocks_price()
|
425 |
+
|
426 |
+
|
427 |
+
def handle_portfolio_update():
|
428 |
+
'''
|
429 |
+
execute when portfolio is updated,
|
430 |
+
left fill benchmark and stock price
|
431 |
+
|
432 |
+
update method is idempotent, so it is safe to call multiple times
|
433 |
+
'''
|
434 |
+
left_fill_benchmark_profile()
|
435 |
+
print("left fill benchmark profile")
|
436 |
+
left_fill_stocks_price()
|
437 |
+
print('left fill stock price db')
|
438 |
+
batch_processing()
|
439 |
+
print('done processing')
|
440 |
+
|
441 |
+
|
442 |
async def daily_update():
|
443 |
'''
|
444 |
left and right fill stock price and benchmark weight based on portfolio
|
|
|
449 |
|
450 |
'''
|
451 |
last_update = log.get_time('daily_update')
|
452 |
+
# less than today 9am, since it need to force to update at 9
|
453 |
if last_update is None or utils.time_in_beijing() - last_update >= dt.timedelta(days=1):
|
454 |
print("running daily update")
|
455 |
|
|
|
501 |
# print(stock_df)
|
502 |
stock_price_stream.emit(stock_df)
|
503 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
504 |
|
505 |
+
def handle_event(e):
|
506 |
+
if e == "update_portfolio":
|
507 |
+
print("handling portfolio update")
|
508 |
+
handle_portfolio_update()
|
509 |
+
print("done handling portfolio update")
|
510 |
|
511 |
+
event.sink(handle_event)
|
pipeline/bhb.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|
pipeline/create_dumpy_data.ipynb
DELETED
@@ -1,36 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"from test_db_peration import db_operator\n",
|
10 |
-
"from datetime import datetime\n"
|
11 |
-
]
|
12 |
-
}
|
13 |
-
],
|
14 |
-
"metadata": {
|
15 |
-
"kernelspec": {
|
16 |
-
"display_name": "portfolio_risk_assesment",
|
17 |
-
"language": "python",
|
18 |
-
"name": "python3"
|
19 |
-
},
|
20 |
-
"language_info": {
|
21 |
-
"codemirror_mode": {
|
22 |
-
"name": "ipython",
|
23 |
-
"version": 3
|
24 |
-
},
|
25 |
-
"file_extension": ".py",
|
26 |
-
"mimetype": "text/x-python",
|
27 |
-
"name": "python",
|
28 |
-
"nbconvert_exporter": "python",
|
29 |
-
"pygments_lexer": "ipython3",
|
30 |
-
"version": "3.11.4"
|
31 |
-
},
|
32 |
-
"orig_nbformat": 4
|
33 |
-
},
|
34 |
-
"nbformat": 4,
|
35 |
-
"nbformat_minor": 2
|
36 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pipeline/db_operation.py
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
from model import Stock
|
2 |
-
from sqlalchemy import create_engine
|
3 |
-
from sqlalchemy.orm import Session
|
4 |
-
|
5 |
-
|
6 |
-
class db_operator():
|
7 |
-
def __init__(self, db_url):
|
8 |
-
self.engine = create_engine(db_url)
|
9 |
-
|
10 |
-
def get_stocks_between(self, d1, d2):
|
11 |
-
with Session(self.engine) as session:
|
12 |
-
return session.query(Stock).filter(
|
13 |
-
Stock.date.between(d1, d2)
|
14 |
-
).all()
|
15 |
-
|
16 |
-
def add_stock(self, stock_data: dict):
|
17 |
-
with Session(self.engine) as session:
|
18 |
-
new_stock = Stock(**stock_data)
|
19 |
-
session.add(new_stock)
|
20 |
-
session.commit()
|
21 |
-
|
22 |
-
def delete_stocks_between(self, d1, d2):
|
23 |
-
with Session(self.engine) as session:
|
24 |
-
session.query(Stock).filter(
|
25 |
-
Stock.date.between(d1, d2)
|
26 |
-
).delete()
|
27 |
-
session.commit()
|
28 |
-
|
29 |
-
def delete_all_stocks(self):
|
30 |
-
with Session(self.engine) as session:
|
31 |
-
session.query(Stock).delete()
|
32 |
-
session.commit()
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pipeline/model.py
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
from sqlalchemy import Column, Integer, String, Float, create_engine, DateTime, PickleType
|
2 |
-
from sqlalchemy.ext.declarative import declarative_base
|
3 |
-
from sqlalchemy.orm import sessionmaker
|
4 |
-
|
5 |
-
Base = declarative_base()
|
6 |
-
|
7 |
-
class Stock(Base):
|
8 |
-
__tablename__ = 'stock'
|
9 |
-
|
10 |
-
id = Column(Integer, primary_key=True)
|
11 |
-
ticker = Column(String(50))
|
12 |
-
weight = Column(Float, nullable=True)
|
13 |
-
display_name = Column(String(50), nullable=False)
|
14 |
-
date = Column(DateTime, nullable=False)
|
15 |
-
order = Column(Integer, autoincrement=True, nullable=True)
|
16 |
-
|
17 |
-
def __repr__(self):
|
18 |
-
return f"<{self.ticker}\
|
19 |
-
{self.date}\
|
20 |
-
{self.display_name}\
|
21 |
-
{round(self.weight * 100)}%>"
|
22 |
-
|
23 |
-
|
24 |
-
class Portfolio(Base):
|
25 |
-
__tablename__ = 'portfolio'
|
26 |
-
|
27 |
-
id = Column(Integer, primary_key=True)
|
28 |
-
stocks = Column(PickleType, nullable=False)
|
29 |
-
cached_result = Column(PickleType, nullable=True)
|
30 |
-
# data = Column(PickleType, nullable=False)
|
31 |
-
date = Column(DateTime, nullable=False)
|
32 |
-
order = Column(Integer, autoincrement=True, nullable=True)
|
33 |
-
|
34 |
-
|
35 |
-
# db_url = 'sqlite:///local_db.db' # Replace 'stocks.db' with the desired database name and location
|
36 |
-
|
37 |
-
# engine = create_engine(db_url)
|
38 |
-
# Base.metadata.create_all(engine)
|
39 |
-
|
40 |
-
# Session = sessionmaker(bind=engine)
|
41 |
-
# session = Session()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pipeline/test_db_peration.py
DELETED
@@ -1,107 +0,0 @@
|
|
1 |
-
from unittest import TestCase, main
|
2 |
-
from db_operation import db_operator
|
3 |
-
from datetime import datetime
|
4 |
-
class test_db_operation(TestCase):
|
5 |
-
def setUp(self) -> None:
|
6 |
-
self.db_operator = db_operator('sqlite:///local_db.db')
|
7 |
-
self.db_operator.delete_all_stocks()
|
8 |
-
self.stock1 = {
|
9 |
-
"ticker": 'AAPL',
|
10 |
-
"weight": 1.0,
|
11 |
-
"display_name": 'Apple Inc.',
|
12 |
-
"date": datetime(2021, 1, 1)
|
13 |
-
}
|
14 |
-
self.stock2 = {
|
15 |
-
"ticker": 'MSFT',
|
16 |
-
"weight": 1.0,
|
17 |
-
"display_name": 'Microsoft Corporation',
|
18 |
-
"date": datetime(2021, 1, 1)
|
19 |
-
}
|
20 |
-
|
21 |
-
def test_insert(self):
|
22 |
-
stock1 = {
|
23 |
-
"ticker": 'AAPL',
|
24 |
-
"weight": 1.0,
|
25 |
-
"display_name": 'Apple Inc.',
|
26 |
-
"date": datetime(2021, 1, 1)
|
27 |
-
}
|
28 |
-
self.db_operator.add_stock(stock1)
|
29 |
-
retrieved_stock = self.db_operator.get_stocks_between(datetime(2021, 1, 1), datetime(2021, 1, 1))[0]
|
30 |
-
self.assertEqual(retrieved_stock.ticker, 'AAPL')
|
31 |
-
self.assertEqual(retrieved_stock.weight, 1.0)
|
32 |
-
self.assertEqual(retrieved_stock.display_name, 'Apple Inc.')
|
33 |
-
self.assertEqual(retrieved_stock.date, datetime(2021, 1, 1))
|
34 |
-
|
35 |
-
def test_delete(self):
|
36 |
-
self.db_operator.add_stock(self.stock1)
|
37 |
-
self.db_operator.add_stock(self.stock2)
|
38 |
-
self.db_operator.delete_stocks_between(
|
39 |
-
datetime(2021, 1, 1),
|
40 |
-
datetime(2021, 1, 1))
|
41 |
-
retrieved_stocks = self.db_operator.get_stocks_between(
|
42 |
-
datetime(2021, 1, 1),
|
43 |
-
datetime(2021, 1, 1))
|
44 |
-
self.assertEqual(len(retrieved_stocks), 0)
|
45 |
-
|
46 |
-
def test_query_window_1d(self):
|
47 |
-
# insert 2 stocks between 2021-01-01 and 2021-01-01 every hour
|
48 |
-
for i in range(24):
|
49 |
-
self.stock1['date'] = datetime(2021, 1, 1, i)
|
50 |
-
self.stock2['date'] = datetime(2021, 1, 1, i)
|
51 |
-
self.db_operator.add_stock(self.stock1)
|
52 |
-
self.db_operator.add_stock(self.stock2)
|
53 |
-
# insert two on 2021-01-02
|
54 |
-
self.stock1['date'] = datetime(2021, 1, 2)
|
55 |
-
self.stock2['date'] = datetime(2021, 1, 2)
|
56 |
-
self.db_operator.add_stock(self.stock1)
|
57 |
-
self.db_operator.add_stock(self.stock2)
|
58 |
-
# query 1d
|
59 |
-
retrieved_stocks = self.db_operator.get_stocks_between(
|
60 |
-
datetime(2021, 1, 1),
|
61 |
-
datetime(2021, 1, 2))
|
62 |
-
self.assertEqual(len(retrieved_stocks), 50)
|
63 |
-
|
64 |
-
def test_query_window_12h(self):
|
65 |
-
# insert 2 stocks every hour between 2021-01-01 and 2021-01-01
|
66 |
-
for i in range(24):
|
67 |
-
self.stock1['date'] = datetime(2021, 1, 1, i)
|
68 |
-
self.stock2['date'] = datetime(2021, 1, 1, i)
|
69 |
-
self.db_operator.add_stock(self.stock1)
|
70 |
-
self.db_operator.add_stock(self.stock2)
|
71 |
-
# query 12h
|
72 |
-
retrieved_stocks = self.db_operator.get_stocks_between(
|
73 |
-
datetime(2021, 1, 1, 0),
|
74 |
-
datetime(2021, 1, 1, 12))
|
75 |
-
self.assertEqual(len(retrieved_stocks), 26)
|
76 |
-
# self.assertTrue(False)
|
77 |
-
|
78 |
-
def test_query_window_1h(self):
|
79 |
-
# insert 2 stocks every mins between 2021-01-01 and 2021-01-01
|
80 |
-
for i in range(60):
|
81 |
-
self.stock1['date'] = datetime(2021, 1, 1, 0, i)
|
82 |
-
self.stock2['date'] = datetime(2021, 1, 1, 0, i)
|
83 |
-
self.db_operator.add_stock(self.stock1)
|
84 |
-
self.db_operator.add_stock(self.stock2)
|
85 |
-
# query 1h
|
86 |
-
retrieved_stocks = self.db_operator.get_stocks_between(
|
87 |
-
datetime(2021, 1, 1, 0),
|
88 |
-
datetime(2021, 1, 1, 1))
|
89 |
-
self.assertEqual(len(retrieved_stocks), 120)
|
90 |
-
|
91 |
-
def test_query_window_30m(self):
|
92 |
-
# insert 2 stocks every 1 between 2021-01-01-00:00 and 2021-01-01-00:20
|
93 |
-
for i in range(20):
|
94 |
-
self.stock1['date'] = datetime(2021, 1, 1, 0, i)
|
95 |
-
self.stock2['date'] = datetime(2021, 1, 1, 0, i)
|
96 |
-
self.db_operator.add_stock(self.stock1)
|
97 |
-
self.db_operator.add_stock(self.stock2)
|
98 |
-
# query 30m
|
99 |
-
retrieved_stocks = self.db_operator.get_stocks_between(
|
100 |
-
datetime(2021, 1, 1, 0),
|
101 |
-
datetime(2021, 1, 1, 0, 30))
|
102 |
-
self.assertEqual(len(retrieved_stocks), 40)
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
if __name__ == '__main__':
|
107 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
portfolioEditingPage.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|
portfolioEditingPage.py
CHANGED
@@ -160,9 +160,9 @@ def app():
|
|
160 |
# patch all synced_to_db to true
|
161 |
indices = history_tabulator.value[
|
162 |
~history_tabulator.value['change_saved']].index.to_list()
|
163 |
-
|
164 |
# add an offset to address the issue when df is empty index start from 1
|
165 |
-
|
166 |
history_tabulator.patch({
|
167 |
'change_saved': [(index, True) for index in indices]
|
168 |
}, as_index=True)
|
@@ -237,11 +237,11 @@ def app():
|
|
237 |
shares=row[2].value,
|
238 |
ave_price=row[3].value,
|
239 |
date=datetime_picker.value) for row in stock_column]
|
240 |
-
|
241 |
if len(new_entry) == 0:
|
242 |
print("no entry added")
|
243 |
-
return
|
244 |
-
|
245 |
new_profile = pipeline.create_portfolio_profile_df(new_entry)
|
246 |
# calculate share changes
|
247 |
tmp_profile = pd.concat([p_profile, new_profile], ignore_index=True)
|
@@ -294,12 +294,12 @@ def app():
|
|
294 |
# update history tabulator and portfolio tabulator
|
295 |
if successed:
|
296 |
# mark changes as saved
|
297 |
-
indices = selected_portfolio[~selected_portfolio['change_saved']].index.to_list(
|
|
|
298 |
portfolio_tabulator.patch({
|
299 |
'change_saved': [(index, True) for index in indices]
|
300 |
}, as_index=True)
|
301 |
|
302 |
-
|
303 |
_update_history_tabulator('sync')
|
304 |
|
305 |
def handle_edit_portfolio_tabulator(e):
|
|
|
160 |
# patch all synced_to_db to true
|
161 |
indices = history_tabulator.value[
|
162 |
~history_tabulator.value['change_saved']].index.to_list()
|
163 |
+
|
164 |
# add an offset to address the issue when df is empty index start from 1
|
165 |
+
|
166 |
history_tabulator.patch({
|
167 |
'change_saved': [(index, True) for index in indices]
|
168 |
}, as_index=True)
|
|
|
237 |
shares=row[2].value,
|
238 |
ave_price=row[3].value,
|
239 |
date=datetime_picker.value) for row in stock_column]
|
240 |
+
|
241 |
if len(new_entry) == 0:
|
242 |
print("no entry added")
|
243 |
+
return
|
244 |
+
|
245 |
new_profile = pipeline.create_portfolio_profile_df(new_entry)
|
246 |
# calculate share changes
|
247 |
tmp_profile = pd.concat([p_profile, new_profile], ignore_index=True)
|
|
|
294 |
# update history tabulator and portfolio tabulator
|
295 |
if successed:
|
296 |
# mark changes as saved
|
297 |
+
indices = selected_portfolio[~selected_portfolio['change_saved']].index.to_list(
|
298 |
+
)
|
299 |
portfolio_tabulator.patch({
|
300 |
'change_saved': [(index, True) for index in indices]
|
301 |
}, as_index=True)
|
302 |
|
|
|
303 |
_update_history_tabulator('sync')
|
304 |
|
305 |
def handle_edit_portfolio_tabulator(e):
|
script/__init__.py
DELETED
File without changes
|
script/api_test.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|
script/bnb_sector_result.pkl
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:dc104daae7afcd56a05f8aff9fa4d80d139a7db33d271fd69fbacb29db22283a
|
3 |
-
size 152021
|
|
|
|
|
|
|
|
script/downloadData.ipynb
DELETED
@@ -1,751 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import pandas as pd\n",
|
10 |
-
"from api import create_portfolio, get_portfile_data, get_benchmark_portfolio\n",
|
11 |
-
"from datetime import datetime"
|
12 |
-
]
|
13 |
-
},
|
14 |
-
{
|
15 |
-
"cell_type": "code",
|
16 |
-
"execution_count": 2,
|
17 |
-
"metadata": {},
|
18 |
-
"outputs": [],
|
19 |
-
"source": [
|
20 |
-
"# df = pd.read_pickle('../dummy_portfolio.pkl')\n",
|
21 |
-
"# df.head(20)"
|
22 |
-
]
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"cell_type": "code",
|
26 |
-
"execution_count": 3,
|
27 |
-
"metadata": {},
|
28 |
-
"outputs": [],
|
29 |
-
"source": [
|
30 |
-
"# ## create a portfolio\n",
|
31 |
-
"\n",
|
32 |
-
"# # weight can use mony\n",
|
33 |
-
"# portfolio_profile_data = [\n",
|
34 |
-
"# {'ticker': '002709.XSHE', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
35 |
-
"# {'ticker': '002920.XSHE', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
36 |
-
"# {'ticker': '300274.XSHE', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
37 |
-
"# {'ticker': '600409.XSHG', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
38 |
-
"# {'ticker': '600415.XSHG', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
39 |
-
"# {'ticker': '603882.XSHG', 'date': datetime(2021, 1, 5), 'weight': 100},\n",
|
40 |
-
"# ]\n",
|
41 |
-
"# # ten thousand\n",
|
42 |
-
"# mkt_cap = 100000\n",
|
43 |
-
"# portfolio_profile, error = create_portfolio(portfolio_profile_data, mkt_cap)"
|
44 |
-
]
|
45 |
-
},
|
46 |
-
{
|
47 |
-
"cell_type": "code",
|
48 |
-
"execution_count": 4,
|
49 |
-
"metadata": {},
|
50 |
-
"outputs": [],
|
51 |
-
"source": [
|
52 |
-
"# print(error)\n",
|
53 |
-
"# # save \n",
|
54 |
-
"# portfolio_profile.to_pickle('../data/portfolio_portfile.pkl')\n",
|
55 |
-
"# portfolio_profile.head(10)"
|
56 |
-
]
|
57 |
-
},
|
58 |
-
{
|
59 |
-
"cell_type": "code",
|
60 |
-
"execution_count": 5,
|
61 |
-
"metadata": {},
|
62 |
-
"outputs": [
|
63 |
-
{
|
64 |
-
"data": {
|
65 |
-
"text/html": [
|
66 |
-
"<div>\n",
|
67 |
-
"<style scoped>\n",
|
68 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
69 |
-
" vertical-align: middle;\n",
|
70 |
-
" }\n",
|
71 |
-
"\n",
|
72 |
-
" .dataframe tbody tr th {\n",
|
73 |
-
" vertical-align: top;\n",
|
74 |
-
" }\n",
|
75 |
-
"\n",
|
76 |
-
" .dataframe thead th {\n",
|
77 |
-
" text-align: right;\n",
|
78 |
-
" }\n",
|
79 |
-
"</style>\n",
|
80 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
81 |
-
" <thead>\n",
|
82 |
-
" <tr style=\"text-align: right;\">\n",
|
83 |
-
" <th></th>\n",
|
84 |
-
" <th>ticker</th>\n",
|
85 |
-
" <th>date</th>\n",
|
86 |
-
" <th>weight</th>\n",
|
87 |
-
" <th>display_name</th>\n",
|
88 |
-
" <th>name</th>\n",
|
89 |
-
" <th>sector</th>\n",
|
90 |
-
" <th>aggregate_sector</th>\n",
|
91 |
-
" </tr>\n",
|
92 |
-
" </thead>\n",
|
93 |
-
" <tbody>\n",
|
94 |
-
" <tr>\n",
|
95 |
-
" <th>0</th>\n",
|
96 |
-
" <td>002709.XSHE</td>\n",
|
97 |
-
" <td>2021-01-05</td>\n",
|
98 |
-
" <td>100</td>\n",
|
99 |
-
" <td>天赐材料</td>\n",
|
100 |
-
" <td>TCCL</td>\n",
|
101 |
-
" <td>电气设备I 电池II 电池化学品III 化学原料和化学制品制造业 电池部件及材料 工业</td>\n",
|
102 |
-
" <td>工业</td>\n",
|
103 |
-
" </tr>\n",
|
104 |
-
" <tr>\n",
|
105 |
-
" <th>1</th>\n",
|
106 |
-
" <td>002920.XSHE</td>\n",
|
107 |
-
" <td>2021-01-05</td>\n",
|
108 |
-
" <td>100</td>\n",
|
109 |
-
" <td>德赛西威</td>\n",
|
110 |
-
" <td>DSXW</td>\n",
|
111 |
-
" <td>计算机I 软件开发II 垂直应用软件III 汽车制造业 汽车电子 可选消费</td>\n",
|
112 |
-
" <td>信息与通信</td>\n",
|
113 |
-
" </tr>\n",
|
114 |
-
" <tr>\n",
|
115 |
-
" <th>2</th>\n",
|
116 |
-
" <td>300274.XSHE</td>\n",
|
117 |
-
" <td>2021-01-05</td>\n",
|
118 |
-
" <td>100</td>\n",
|
119 |
-
" <td>阳光电源</td>\n",
|
120 |
-
" <td>YGDY</td>\n",
|
121 |
-
" <td>电气设备I 光伏设备II 逆变器III 电气机械和器材制造业 光伏设备 工业</td>\n",
|
122 |
-
" <td>工业</td>\n",
|
123 |
-
" </tr>\n",
|
124 |
-
" <tr>\n",
|
125 |
-
" <th>3</th>\n",
|
126 |
-
" <td>600409.XSHG</td>\n",
|
127 |
-
" <td>2021-01-05</td>\n",
|
128 |
-
" <td>100</td>\n",
|
129 |
-
" <td>三友化工</td>\n",
|
130 |
-
" <td>SYHG</td>\n",
|
131 |
-
" <td>化工I 化学原料II 纯碱III 化学原料和化学制品制造业 粘胶 原材料</td>\n",
|
132 |
-
" <td>原料与能源</td>\n",
|
133 |
-
" </tr>\n",
|
134 |
-
" <tr>\n",
|
135 |
-
" <th>4</th>\n",
|
136 |
-
" <td>600415.XSHG</td>\n",
|
137 |
-
" <td>2021-01-05</td>\n",
|
138 |
-
" <td>100</td>\n",
|
139 |
-
" <td>小商品城</td>\n",
|
140 |
-
" <td>XSPC</td>\n",
|
141 |
-
" <td>商业贸易I 一般零售II 商业物业经营III 商务服务业 市场服务 工业</td>\n",
|
142 |
-
" <td>消费</td>\n",
|
143 |
-
" </tr>\n",
|
144 |
-
" <tr>\n",
|
145 |
-
" <th>5</th>\n",
|
146 |
-
" <td>603882.XSHG</td>\n",
|
147 |
-
" <td>2021-01-05</td>\n",
|
148 |
-
" <td>100</td>\n",
|
149 |
-
" <td>金域医学</td>\n",
|
150 |
-
" <td>JYYX</td>\n",
|
151 |
-
" <td>医药生物I 医疗服务II 诊断服务III 卫生 体外诊断 医药卫生</td>\n",
|
152 |
-
" <td>医药卫生</td>\n",
|
153 |
-
" </tr>\n",
|
154 |
-
" </tbody>\n",
|
155 |
-
"</table>\n",
|
156 |
-
"</div>"
|
157 |
-
],
|
158 |
-
"text/plain": [
|
159 |
-
" ticker date weight display_name name \\\n",
|
160 |
-
"0 002709.XSHE 2021-01-05 100 天赐材料 TCCL \n",
|
161 |
-
"1 002920.XSHE 2021-01-05 100 德赛西威 DSXW \n",
|
162 |
-
"2 300274.XSHE 2021-01-05 100 阳光电源 YGDY \n",
|
163 |
-
"3 600409.XSHG 2021-01-05 100 三友化工 SYHG \n",
|
164 |
-
"4 600415.XSHG 2021-01-05 100 小商品城 XSPC \n",
|
165 |
-
"5 603882.XSHG 2021-01-05 100 金域医学 JYYX \n",
|
166 |
-
"\n",
|
167 |
-
" sector aggregate_sector \n",
|
168 |
-
"0 电气设备I 电池II 电池化学品III 化学原料和化学制品制造业 电池部件及材料 工业 工业 \n",
|
169 |
-
"1 计算机I 软件开发II 垂直应用软件III 汽车制造业 汽车电子 可选消费 信息与通信 \n",
|
170 |
-
"2 电气设备I 光伏设备II 逆变器III 电气机械和器材制造业 光伏设备 工业 工业 \n",
|
171 |
-
"3 化工I 化学原料II 纯碱III 化学原料和化学制品制造业 粘胶 原材料 原料与能源 \n",
|
172 |
-
"4 商业贸易I 一般零售II 商业物业经营III 商务服务业 市场服务 工业 消费 \n",
|
173 |
-
"5 医药生物I 医疗服务II 诊断服务III 卫生 体外诊断 医药卫生 医药卫生 "
|
174 |
-
]
|
175 |
-
},
|
176 |
-
"execution_count": 5,
|
177 |
-
"metadata": {},
|
178 |
-
"output_type": "execute_result"
|
179 |
-
}
|
180 |
-
],
|
181 |
-
"source": [
|
182 |
-
"## load portfolio_profile\n",
|
183 |
-
"portfolio_profile = pd.read_pickle('../data/portfolio_portfile.pkl')\n",
|
184 |
-
"portfolio_profile.head(10)"
|
185 |
-
]
|
186 |
-
},
|
187 |
-
{
|
188 |
-
"cell_type": "code",
|
189 |
-
"execution_count": 6,
|
190 |
-
"metadata": {},
|
191 |
-
"outputs": [],
|
192 |
-
"source": [
|
193 |
-
"start_date = datetime(2021, 1, 5)\n",
|
194 |
-
"end_date = datetime(2022, 1, 10)"
|
195 |
-
]
|
196 |
-
},
|
197 |
-
{
|
198 |
-
"cell_type": "code",
|
199 |
-
"execution_count": 7,
|
200 |
-
"metadata": {},
|
201 |
-
"outputs": [
|
202 |
-
{
|
203 |
-
"name": "stdout",
|
204 |
-
"output_type": "stream",
|
205 |
-
"text": [
|
206 |
-
"auth success \n"
|
207 |
-
]
|
208 |
-
}
|
209 |
-
],
|
210 |
-
"source": [
|
211 |
-
"# get portfolio data\n",
|
212 |
-
"portfile_data, error = get_portfile_data(portfolio_profile, start_date, end_date)"
|
213 |
-
]
|
214 |
-
},
|
215 |
-
{
|
216 |
-
"cell_type": "code",
|
217 |
-
"execution_count": 8,
|
218 |
-
"metadata": {},
|
219 |
-
"outputs": [
|
220 |
-
{
|
221 |
-
"name": "stdout",
|
222 |
-
"output_type": "stream",
|
223 |
-
"text": [
|
224 |
-
"[]\n",
|
225 |
-
"(1482, 8)\n"
|
226 |
-
]
|
227 |
-
},
|
228 |
-
{
|
229 |
-
"data": {
|
230 |
-
"text/html": [
|
231 |
-
"<div>\n",
|
232 |
-
"<style scoped>\n",
|
233 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
234 |
-
" vertical-align: middle;\n",
|
235 |
-
" }\n",
|
236 |
-
"\n",
|
237 |
-
" .dataframe tbody tr th {\n",
|
238 |
-
" vertical-align: top;\n",
|
239 |
-
" }\n",
|
240 |
-
"\n",
|
241 |
-
" .dataframe thead th {\n",
|
242 |
-
" text-align: right;\n",
|
243 |
-
" }\n",
|
244 |
-
"</style>\n",
|
245 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
246 |
-
" <thead>\n",
|
247 |
-
" <tr style=\"text-align: right;\">\n",
|
248 |
-
" <th></th>\n",
|
249 |
-
" <th>ticker</th>\n",
|
250 |
-
" <th>date</th>\n",
|
251 |
-
" <th>open</th>\n",
|
252 |
-
" <th>close</th>\n",
|
253 |
-
" <th>high</th>\n",
|
254 |
-
" <th>low</th>\n",
|
255 |
-
" <th>volume</th>\n",
|
256 |
-
" <th>money</th>\n",
|
257 |
-
" </tr>\n",
|
258 |
-
" </thead>\n",
|
259 |
-
" <tbody>\n",
|
260 |
-
" <tr>\n",
|
261 |
-
" <th>2022-01-07</th>\n",
|
262 |
-
" <td>603882.XSHG</td>\n",
|
263 |
-
" <td>2022-01-07</td>\n",
|
264 |
-
" <td>91.13</td>\n",
|
265 |
-
" <td>87.99</td>\n",
|
266 |
-
" <td>91.17</td>\n",
|
267 |
-
" <td>87.72</td>\n",
|
268 |
-
" <td>6971998.0</td>\n",
|
269 |
-
" <td>6.176535e+08</td>\n",
|
270 |
-
" </tr>\n",
|
271 |
-
" <tr>\n",
|
272 |
-
" <th>2022-01-07</th>\n",
|
273 |
-
" <td>002709.XSHE</td>\n",
|
274 |
-
" <td>2022-01-07</td>\n",
|
275 |
-
" <td>51.28</td>\n",
|
276 |
-
" <td>51.72</td>\n",
|
277 |
-
" <td>52.62</td>\n",
|
278 |
-
" <td>50.47</td>\n",
|
279 |
-
" <td>32210458.0</td>\n",
|
280 |
-
" <td>1.661823e+09</td>\n",
|
281 |
-
" </tr>\n",
|
282 |
-
" <tr>\n",
|
283 |
-
" <th>2022-01-07</th>\n",
|
284 |
-
" <td>600409.XSHG</td>\n",
|
285 |
-
" <td>2022-01-07</td>\n",
|
286 |
-
" <td>8.23</td>\n",
|
287 |
-
" <td>8.22</td>\n",
|
288 |
-
" <td>8.29</td>\n",
|
289 |
-
" <td>8.19</td>\n",
|
290 |
-
" <td>35003739.0</td>\n",
|
291 |
-
" <td>2.884990e+08</td>\n",
|
292 |
-
" </tr>\n",
|
293 |
-
" <tr>\n",
|
294 |
-
" <th>2022-01-07</th>\n",
|
295 |
-
" <td>600415.XSHG</td>\n",
|
296 |
-
" <td>2022-01-07</td>\n",
|
297 |
-
" <td>4.74</td>\n",
|
298 |
-
" <td>4.70</td>\n",
|
299 |
-
" <td>4.79</td>\n",
|
300 |
-
" <td>4.68</td>\n",
|
301 |
-
" <td>24902567.0</td>\n",
|
302 |
-
" <td>1.178837e+08</td>\n",
|
303 |
-
" </tr>\n",
|
304 |
-
" <tr>\n",
|
305 |
-
" <th>2022-01-10</th>\n",
|
306 |
-
" <td>300274.XSHE</td>\n",
|
307 |
-
" <td>2022-01-10</td>\n",
|
308 |
-
" <td>127.49</td>\n",
|
309 |
-
" <td>124.09</td>\n",
|
310 |
-
" <td>127.49</td>\n",
|
311 |
-
" <td>123.29</td>\n",
|
312 |
-
" <td>17238708.0</td>\n",
|
313 |
-
" <td>2.148032e+09</td>\n",
|
314 |
-
" </tr>\n",
|
315 |
-
" <tr>\n",
|
316 |
-
" <th>2022-01-10</th>\n",
|
317 |
-
" <td>600409.XSHG</td>\n",
|
318 |
-
" <td>2022-01-10</td>\n",
|
319 |
-
" <td>8.24</td>\n",
|
320 |
-
" <td>8.35</td>\n",
|
321 |
-
" <td>8.39</td>\n",
|
322 |
-
" <td>8.21</td>\n",
|
323 |
-
" <td>32516017.0</td>\n",
|
324 |
-
" <td>2.699300e+08</td>\n",
|
325 |
-
" </tr>\n",
|
326 |
-
" <tr>\n",
|
327 |
-
" <th>2022-01-10</th>\n",
|
328 |
-
" <td>002920.XSHE</td>\n",
|
329 |
-
" <td>2022-01-10</td>\n",
|
330 |
-
" <td>130.36</td>\n",
|
331 |
-
" <td>138.43</td>\n",
|
332 |
-
" <td>141.96</td>\n",
|
333 |
-
" <td>130.11</td>\n",
|
334 |
-
" <td>5005400.0</td>\n",
|
335 |
-
" <td>6.901614e+08</td>\n",
|
336 |
-
" </tr>\n",
|
337 |
-
" <tr>\n",
|
338 |
-
" <th>2022-01-10</th>\n",
|
339 |
-
" <td>002709.XSHE</td>\n",
|
340 |
-
" <td>2022-01-10</td>\n",
|
341 |
-
" <td>51.63</td>\n",
|
342 |
-
" <td>50.73</td>\n",
|
343 |
-
" <td>51.93</td>\n",
|
344 |
-
" <td>50.03</td>\n",
|
345 |
-
" <td>29821246.0</td>\n",
|
346 |
-
" <td>1.518902e+09</td>\n",
|
347 |
-
" </tr>\n",
|
348 |
-
" <tr>\n",
|
349 |
-
" <th>2022-01-10</th>\n",
|
350 |
-
" <td>600415.XSHG</td>\n",
|
351 |
-
" <td>2022-01-10</td>\n",
|
352 |
-
" <td>4.70</td>\n",
|
353 |
-
" <td>4.75</td>\n",
|
354 |
-
" <td>4.85</td>\n",
|
355 |
-
" <td>4.67</td>\n",
|
356 |
-
" <td>39278041.0</td>\n",
|
357 |
-
" <td>1.859827e+08</td>\n",
|
358 |
-
" </tr>\n",
|
359 |
-
" <tr>\n",
|
360 |
-
" <th>2022-01-10</th>\n",
|
361 |
-
" <td>603882.XSHG</td>\n",
|
362 |
-
" <td>2022-01-10</td>\n",
|
363 |
-
" <td>88.45</td>\n",
|
364 |
-
" <td>95.53</td>\n",
|
365 |
-
" <td>95.59</td>\n",
|
366 |
-
" <td>88.39</td>\n",
|
367 |
-
" <td>6991445.0</td>\n",
|
368 |
-
" <td>6.468392e+08</td>\n",
|
369 |
-
" </tr>\n",
|
370 |
-
" </tbody>\n",
|
371 |
-
"</table>\n",
|
372 |
-
"</div>"
|
373 |
-
],
|
374 |
-
"text/plain": [
|
375 |
-
" ticker date open close high low \\\n",
|
376 |
-
"2022-01-07 603882.XSHG 2022-01-07 91.13 87.99 91.17 87.72 \n",
|
377 |
-
"2022-01-07 002709.XSHE 2022-01-07 51.28 51.72 52.62 50.47 \n",
|
378 |
-
"2022-01-07 600409.XSHG 2022-01-07 8.23 8.22 8.29 8.19 \n",
|
379 |
-
"2022-01-07 600415.XSHG 2022-01-07 4.74 4.70 4.79 4.68 \n",
|
380 |
-
"2022-01-10 300274.XSHE 2022-01-10 127.49 124.09 127.49 123.29 \n",
|
381 |
-
"2022-01-10 600409.XSHG 2022-01-10 8.24 8.35 8.39 8.21 \n",
|
382 |
-
"2022-01-10 002920.XSHE 2022-01-10 130.36 138.43 141.96 130.11 \n",
|
383 |
-
"2022-01-10 002709.XSHE 2022-01-10 51.63 50.73 51.93 50.03 \n",
|
384 |
-
"2022-01-10 600415.XSHG 2022-01-10 4.70 4.75 4.85 4.67 \n",
|
385 |
-
"2022-01-10 603882.XSHG 2022-01-10 88.45 95.53 95.59 88.39 \n",
|
386 |
-
"\n",
|
387 |
-
" volume money \n",
|
388 |
-
"2022-01-07 6971998.0 6.176535e+08 \n",
|
389 |
-
"2022-01-07 32210458.0 1.661823e+09 \n",
|
390 |
-
"2022-01-07 35003739.0 2.884990e+08 \n",
|
391 |
-
"2022-01-07 24902567.0 1.178837e+08 \n",
|
392 |
-
"2022-01-10 17238708.0 2.148032e+09 \n",
|
393 |
-
"2022-01-10 32516017.0 2.699300e+08 \n",
|
394 |
-
"2022-01-10 5005400.0 6.901614e+08 \n",
|
395 |
-
"2022-01-10 29821246.0 1.518902e+09 \n",
|
396 |
-
"2022-01-10 39278041.0 1.859827e+08 \n",
|
397 |
-
"2022-01-10 6991445.0 6.468392e+08 "
|
398 |
-
]
|
399 |
-
},
|
400 |
-
"execution_count": 8,
|
401 |
-
"metadata": {},
|
402 |
-
"output_type": "execute_result"
|
403 |
-
}
|
404 |
-
],
|
405 |
-
"source": [
|
406 |
-
"print(error)\n",
|
407 |
-
"print(portfile_data.shape)\n",
|
408 |
-
"portfile_data.sort_values(by=['date'], inplace=True)\n",
|
409 |
-
"portfile_data.tail(10)"
|
410 |
-
]
|
411 |
-
},
|
412 |
-
{
|
413 |
-
"cell_type": "code",
|
414 |
-
"execution_count": 26,
|
415 |
-
"metadata": {},
|
416 |
-
"outputs": [],
|
417 |
-
"source": [
|
418 |
-
"# save\n",
|
419 |
-
"portfile_data.to_pickle('../data/portfolio_data.pkl')"
|
420 |
-
]
|
421 |
-
},
|
422 |
-
{
|
423 |
-
"cell_type": "code",
|
424 |
-
"execution_count": 27,
|
425 |
-
"metadata": {},
|
426 |
-
"outputs": [],
|
427 |
-
"source": [
|
428 |
-
"# load benchmark portfolio\n",
|
429 |
-
"benchmark_portfolio, error = get_benchmark_portfolio(start_date, end_date)"
|
430 |
-
]
|
431 |
-
},
|
432 |
-
{
|
433 |
-
"cell_type": "code",
|
434 |
-
"execution_count": 28,
|
435 |
-
"metadata": {},
|
436 |
-
"outputs": [
|
437 |
-
{
|
438 |
-
"name": "stdout",
|
439 |
-
"output_type": "stream",
|
440 |
-
"text": [
|
441 |
-
"[]\n",
|
442 |
-
"(185500, 15)\n"
|
443 |
-
]
|
444 |
-
},
|
445 |
-
{
|
446 |
-
"data": {
|
447 |
-
"text/html": [
|
448 |
-
"<div>\n",
|
449 |
-
"<style scoped>\n",
|
450 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
451 |
-
" vertical-align: middle;\n",
|
452 |
-
" }\n",
|
453 |
-
"\n",
|
454 |
-
" .dataframe tbody tr th {\n",
|
455 |
-
" vertical-align: top;\n",
|
456 |
-
" }\n",
|
457 |
-
"\n",
|
458 |
-
" .dataframe thead th {\n",
|
459 |
-
" text-align: right;\n",
|
460 |
-
" }\n",
|
461 |
-
"</style>\n",
|
462 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
463 |
-
" <thead>\n",
|
464 |
-
" <tr style=\"text-align: right;\">\n",
|
465 |
-
" <th></th>\n",
|
466 |
-
" <th>date</th>\n",
|
467 |
-
" <th>weight</th>\n",
|
468 |
-
" <th>display_name_x</th>\n",
|
469 |
-
" <th>actual_data</th>\n",
|
470 |
-
" <th>ticker</th>\n",
|
471 |
-
" <th>open</th>\n",
|
472 |
-
" <th>close</th>\n",
|
473 |
-
" <th>high</th>\n",
|
474 |
-
" <th>low</th>\n",
|
475 |
-
" <th>volume</th>\n",
|
476 |
-
" <th>money</th>\n",
|
477 |
-
" <th>display_name_y</th>\n",
|
478 |
-
" <th>name</th>\n",
|
479 |
-
" <th>sector</th>\n",
|
480 |
-
" <th>aggregate_sector</th>\n",
|
481 |
-
" </tr>\n",
|
482 |
-
" </thead>\n",
|
483 |
-
" <tbody>\n",
|
484 |
-
" <tr>\n",
|
485 |
-
" <th>185163</th>\n",
|
486 |
-
" <td>2022-01-10</td>\n",
|
487 |
-
" <td>0.274</td>\n",
|
488 |
-
" <td>厦门钨业</td>\n",
|
489 |
-
" <td>2021-12-31</td>\n",
|
490 |
-
" <td>600549.XSHG</td>\n",
|
491 |
-
" <td>21.50</td>\n",
|
492 |
-
" <td>21.59</td>\n",
|
493 |
-
" <td>21.75</td>\n",
|
494 |
-
" <td>21.43</td>\n",
|
495 |
-
" <td>10451128.0</td>\n",
|
496 |
-
" <td>2.254199e+08</td>\n",
|
497 |
-
" <td>厦门钨业</td>\n",
|
498 |
-
" <td>XMWY</td>\n",
|
499 |
-
" <td>有色金属I 稀有金属II 钨III 有色金属冶炼和压延加工业 钨钼 原材料</td>\n",
|
500 |
-
" <td>原料与能源</td>\n",
|
501 |
-
" </tr>\n",
|
502 |
-
" <tr>\n",
|
503 |
-
" <th>185162</th>\n",
|
504 |
-
" <td>2022-01-10</td>\n",
|
505 |
-
" <td>0.116</td>\n",
|
506 |
-
" <td>山煤国际</td>\n",
|
507 |
-
" <td>2021-12-31</td>\n",
|
508 |
-
" <td>600546.XSHG</td>\n",
|
509 |
-
" <td>6.74</td>\n",
|
510 |
-
" <td>6.86</td>\n",
|
511 |
-
" <td>6.86</td>\n",
|
512 |
-
" <td>6.71</td>\n",
|
513 |
-
" <td>66929559.0</td>\n",
|
514 |
-
" <td>4.539690e+08</td>\n",
|
515 |
-
" <td>山煤国际</td>\n",
|
516 |
-
" <td>SMGJ</td>\n",
|
517 |
-
" <td>煤炭I 煤炭开采II 动力煤III 批发业 煤炭 能源</td>\n",
|
518 |
-
" <td>原料与能源</td>\n",
|
519 |
-
" </tr>\n",
|
520 |
-
" <tr>\n",
|
521 |
-
" <th>185161</th>\n",
|
522 |
-
" <td>2022-01-10</td>\n",
|
523 |
-
" <td>0.211</td>\n",
|
524 |
-
" <td>中国软件</td>\n",
|
525 |
-
" <td>2021-12-31</td>\n",
|
526 |
-
" <td>600536.XSHG</td>\n",
|
527 |
-
" <td>29.01</td>\n",
|
528 |
-
" <td>30.90</td>\n",
|
529 |
-
" <td>31.45</td>\n",
|
530 |
-
" <td>28.98</td>\n",
|
531 |
-
" <td>35489167.0</td>\n",
|
532 |
-
" <td>1.087404e+09</td>\n",
|
533 |
-
" <td>中国软件</td>\n",
|
534 |
-
" <td>ZGRJ</td>\n",
|
535 |
-
" <td>计算机I IT服务II IT服务III 软件和信息技术服务业 行业应用软件 信息技术</td>\n",
|
536 |
-
" <td>信息与通信</td>\n",
|
537 |
-
" </tr>\n",
|
538 |
-
" <tr>\n",
|
539 |
-
" <th>185160</th>\n",
|
540 |
-
" <td>2022-01-10</td>\n",
|
541 |
-
" <td>0.205</td>\n",
|
542 |
-
" <td>天士力</td>\n",
|
543 |
-
" <td>2021-12-31</td>\n",
|
544 |
-
" <td>600535.XSHG</td>\n",
|
545 |
-
" <td>15.04</td>\n",
|
546 |
-
" <td>15.52</td>\n",
|
547 |
-
" <td>15.75</td>\n",
|
548 |
-
" <td>14.95</td>\n",
|
549 |
-
" <td>46823950.0</td>\n",
|
550 |
-
" <td>7.247465e+08</td>\n",
|
551 |
-
" <td>天士力</td>\n",
|
552 |
-
" <td>TSL</td>\n",
|
553 |
-
" <td>医药生物I 中药II 中药III 医药制造业 中成药 医药卫生</td>\n",
|
554 |
-
" <td>医药卫生</td>\n",
|
555 |
-
" </tr>\n",
|
556 |
-
" <tr>\n",
|
557 |
-
" <th>185159</th>\n",
|
558 |
-
" <td>2022-01-10</td>\n",
|
559 |
-
" <td>0.297</td>\n",
|
560 |
-
" <td>山东药玻</td>\n",
|
561 |
-
" <td>2021-12-31</td>\n",
|
562 |
-
" <td>600529.XSHG</td>\n",
|
563 |
-
" <td>42.39</td>\n",
|
564 |
-
" <td>40.14</td>\n",
|
565 |
-
" <td>42.39</td>\n",
|
566 |
-
" <td>39.47</td>\n",
|
567 |
-
" <td>12543641.0</td>\n",
|
568 |
-
" <td>5.049473e+08</td>\n",
|
569 |
-
" <td>山东药玻</td>\n",
|
570 |
-
" <td>SDYB</td>\n",
|
571 |
-
" <td>医药生物I 医疗器械II 医疗耗材III 非金属矿物制品业 医疗耗材 医药卫生</td>\n",
|
572 |
-
" <td>医药卫生</td>\n",
|
573 |
-
" </tr>\n",
|
574 |
-
" <tr>\n",
|
575 |
-
" <th>185158</th>\n",
|
576 |
-
" <td>2022-01-10</td>\n",
|
577 |
-
" <td>0.156</td>\n",
|
578 |
-
" <td>中铁工业</td>\n",
|
579 |
-
" <td>2021-12-31</td>\n",
|
580 |
-
" <td>600528.XSHG</td>\n",
|
581 |
-
" <td>8.69</td>\n",
|
582 |
-
" <td>9.08</td>\n",
|
583 |
-
" <td>9.26</td>\n",
|
584 |
-
" <td>8.68</td>\n",
|
585 |
-
" <td>98213530.0</td>\n",
|
586 |
-
" <td>8.961637e+08</td>\n",
|
587 |
-
" <td>中铁工业</td>\n",
|
588 |
-
" <td>ZTGY</td>\n",
|
589 |
-
" <td>机械设备I 运输设备II 铁路设备III 专用设备制造业 城轨铁路 工业</td>\n",
|
590 |
-
" <td>工业</td>\n",
|
591 |
-
" </tr>\n",
|
592 |
-
" <tr>\n",
|
593 |
-
" <th>185157</th>\n",
|
594 |
-
" <td>2022-01-10</td>\n",
|
595 |
-
" <td>0.642</td>\n",
|
596 |
-
" <td>中天科技</td>\n",
|
597 |
-
" <td>2021-12-31</td>\n",
|
598 |
-
" <td>600522.XSHG</td>\n",
|
599 |
-
" <td>15.21</td>\n",
|
600 |
-
" <td>14.76</td>\n",
|
601 |
-
" <td>15.26</td>\n",
|
602 |
-
" <td>14.53</td>\n",
|
603 |
-
" <td>112744173.0</td>\n",
|
604 |
-
" <td>1.670952e+09</td>\n",
|
605 |
-
" <td>中天科技</td>\n",
|
606 |
-
" <td>ZTKJ</td>\n",
|
607 |
-
" <td>通信I 通信设备II 通信线缆及配套III 电气机械和器材制造业 通信系统设备及组件 通信服务</td>\n",
|
608 |
-
" <td>信息与通信</td>\n",
|
609 |
-
" </tr>\n",
|
610 |
-
" <tr>\n",
|
611 |
-
" <th>185156</th>\n",
|
612 |
-
" <td>2022-01-10</td>\n",
|
613 |
-
" <td>0.276</td>\n",
|
614 |
-
" <td>华海药业</td>\n",
|
615 |
-
" <td>2021-12-31</td>\n",
|
616 |
-
" <td>600521.XSHG</td>\n",
|
617 |
-
" <td>22.32</td>\n",
|
618 |
-
" <td>23.32</td>\n",
|
619 |
-
" <td>23.43</td>\n",
|
620 |
-
" <td>21.90</td>\n",
|
621 |
-
" <td>29810065.0</td>\n",
|
622 |
-
" <td>6.827298e+08</td>\n",
|
623 |
-
" <td>华海药业</td>\n",
|
624 |
-
" <td>HHYY</td>\n",
|
625 |
-
" <td>医药生物I 化学制药II 化学制剂III 医药制造业 药品制剂 医药卫生</td>\n",
|
626 |
-
" <td>医药卫生</td>\n",
|
627 |
-
" </tr>\n",
|
628 |
-
" <tr>\n",
|
629 |
-
" <th>185169</th>\n",
|
630 |
-
" <td>2022-01-10</td>\n",
|
631 |
-
" <td>0.240</td>\n",
|
632 |
-
" <td>卧龙电驱</td>\n",
|
633 |
-
" <td>2021-12-31</td>\n",
|
634 |
-
" <td>600580.XSHG</td>\n",
|
635 |
-
" <td>16.66</td>\n",
|
636 |
-
" <td>16.51</td>\n",
|
637 |
-
" <td>16.68</td>\n",
|
638 |
-
" <td>16.23</td>\n",
|
639 |
-
" <td>19294606.0</td>\n",
|
640 |
-
" <td>3.175398e+08</td>\n",
|
641 |
-
" <td>卧龙电驱</td>\n",
|
642 |
-
" <td>WLDQ</td>\n",
|
643 |
-
" <td>电气设备I 电机II 电机III 电气机械和器材制造业 电动机与工控自动化 工业</td>\n",
|
644 |
-
" <td>工业</td>\n",
|
645 |
-
" </tr>\n",
|
646 |
-
" <tr>\n",
|
647 |
-
" <th>185499</th>\n",
|
648 |
-
" <td>2022-01-10</td>\n",
|
649 |
-
" <td>0.350</td>\n",
|
650 |
-
" <td>思瑞浦</td>\n",
|
651 |
-
" <td>2021-12-31</td>\n",
|
652 |
-
" <td>688536.XSHG</td>\n",
|
653 |
-
" <td>476.70</td>\n",
|
654 |
-
" <td>463.10</td>\n",
|
655 |
-
" <td>476.70</td>\n",
|
656 |
-
" <td>446.03</td>\n",
|
657 |
-
" <td>924992.0</td>\n",
|
658 |
-
" <td>4.254053e+08</td>\n",
|
659 |
-
" <td>思瑞浦</td>\n",
|
660 |
-
" <td>SRP</td>\n",
|
661 |
-
" <td>电子I 半导体II 模拟芯片设计III 软件和信息技术服务业 集成电路设计 信息技术</td>\n",
|
662 |
-
" <td>信息与通信</td>\n",
|
663 |
-
" </tr>\n",
|
664 |
-
" </tbody>\n",
|
665 |
-
"</table>\n",
|
666 |
-
"</div>"
|
667 |
-
],
|
668 |
-
"text/plain": [
|
669 |
-
" date weight display_name_x actual_data ticker open \\\n",
|
670 |
-
"185163 2022-01-10 0.274 厦门钨业 2021-12-31 600549.XSHG 21.50 \n",
|
671 |
-
"185162 2022-01-10 0.116 山煤国际 2021-12-31 600546.XSHG 6.74 \n",
|
672 |
-
"185161 2022-01-10 0.211 中国软件 2021-12-31 600536.XSHG 29.01 \n",
|
673 |
-
"185160 2022-01-10 0.205 天士力 2021-12-31 600535.XSHG 15.04 \n",
|
674 |
-
"185159 2022-01-10 0.297 山东药玻 2021-12-31 600529.XSHG 42.39 \n",
|
675 |
-
"185158 2022-01-10 0.156 中铁工业 2021-12-31 600528.XSHG 8.69 \n",
|
676 |
-
"185157 2022-01-10 0.642 中天科技 2021-12-31 600522.XSHG 15.21 \n",
|
677 |
-
"185156 2022-01-10 0.276 华海药业 2021-12-31 600521.XSHG 22.32 \n",
|
678 |
-
"185169 2022-01-10 0.240 卧龙电驱 2021-12-31 600580.XSHG 16.66 \n",
|
679 |
-
"185499 2022-01-10 0.350 思瑞浦 2021-12-31 688536.XSHG 476.70 \n",
|
680 |
-
"\n",
|
681 |
-
" close high low volume money display_name_y \\\n",
|
682 |
-
"185163 21.59 21.75 21.43 10451128.0 2.254199e+08 厦门钨业 \n",
|
683 |
-
"185162 6.86 6.86 6.71 66929559.0 4.539690e+08 山煤国际 \n",
|
684 |
-
"185161 30.90 31.45 28.98 35489167.0 1.087404e+09 中国软件 \n",
|
685 |
-
"185160 15.52 15.75 14.95 46823950.0 7.247465e+08 天士力 \n",
|
686 |
-
"185159 40.14 42.39 39.47 12543641.0 5.049473e+08 山东药玻 \n",
|
687 |
-
"185158 9.08 9.26 8.68 98213530.0 8.961637e+08 中铁工业 \n",
|
688 |
-
"185157 14.76 15.26 14.53 112744173.0 1.670952e+09 中天科技 \n",
|
689 |
-
"185156 23.32 23.43 21.90 29810065.0 6.827298e+08 华海药业 \n",
|
690 |
-
"185169 16.51 16.68 16.23 19294606.0 3.175398e+08 卧龙电驱 \n",
|
691 |
-
"185499 463.10 476.70 446.03 924992.0 4.254053e+08 思瑞浦 \n",
|
692 |
-
"\n",
|
693 |
-
" name sector aggregate_sector \n",
|
694 |
-
"185163 XMWY 有色金属I 稀有金属II 钨III 有色金属冶炼和压延加工业 钨钼 原材料 原料与能源 \n",
|
695 |
-
"185162 SMGJ 煤炭I 煤炭开采II 动力煤III 批发业 煤炭 能源 原料与能源 \n",
|
696 |
-
"185161 ZGRJ 计算机I IT服务II IT服务III 软件和信息技术服务业 行业应用软件 信息技术 信息与通信 \n",
|
697 |
-
"185160 TSL 医药生物I 中药II 中药III 医药制造业 中成药 医药卫生 医药卫生 \n",
|
698 |
-
"185159 SDYB 医药生物I 医疗器械II 医疗耗材III 非金属矿物制品业 医疗耗材 医药卫生 医药卫生 \n",
|
699 |
-
"185158 ZTGY 机械设备I 运输设备II 铁路设备III 专用设备制造业 城轨铁路 工业 工业 \n",
|
700 |
-
"185157 ZTKJ 通信I 通信设备II 通信线缆及配套III 电气机械和器材制造业 通信系统设备及组件 通信服务 信息与通信 \n",
|
701 |
-
"185156 HHYY 医药生物I 化学制药II 化学制剂III 医药制造业 药品制剂 医药卫生 医药卫生 \n",
|
702 |
-
"185169 WLDQ 电气设备I 电机II 电机III 电气机械和器材制造业 电动机与工控自动化 工业 工业 \n",
|
703 |
-
"185499 SRP 电子I 半导体II 模拟芯片设计III 软件和信息技术服务业 集成电路设计 信息技术 信息与通信 "
|
704 |
-
]
|
705 |
-
},
|
706 |
-
"execution_count": 28,
|
707 |
-
"metadata": {},
|
708 |
-
"output_type": "execute_result"
|
709 |
-
}
|
710 |
-
],
|
711 |
-
"source": [
|
712 |
-
"print(error)\n",
|
713 |
-
"print(benchmark_portfolio.shape)\n",
|
714 |
-
"benchmark_portfolio.sort_values(by=['date'], inplace=True)\n",
|
715 |
-
"benchmark_portfolio.tail(10)\n"
|
716 |
-
]
|
717 |
-
},
|
718 |
-
{
|
719 |
-
"cell_type": "code",
|
720 |
-
"execution_count": 29,
|
721 |
-
"metadata": {},
|
722 |
-
"outputs": [],
|
723 |
-
"source": [
|
724 |
-
"# save\n",
|
725 |
-
"benchmark_portfolio.to_pickle('../data/benchmark_portfolio.pkl')"
|
726 |
-
]
|
727 |
-
}
|
728 |
-
],
|
729 |
-
"metadata": {
|
730 |
-
"kernelspec": {
|
731 |
-
"display_name": "portfolio_risk_assesment",
|
732 |
-
"language": "python",
|
733 |
-
"name": "python3"
|
734 |
-
},
|
735 |
-
"language_info": {
|
736 |
-
"codemirror_mode": {
|
737 |
-
"name": "ipython",
|
738 |
-
"version": 3
|
739 |
-
},
|
740 |
-
"file_extension": ".py",
|
741 |
-
"mimetype": "text/x-python",
|
742 |
-
"name": "python",
|
743 |
-
"nbconvert_exporter": "python",
|
744 |
-
"pygments_lexer": "ipython3",
|
745 |
-
"version": "3.11.4"
|
746 |
-
},
|
747 |
-
"orig_nbformat": 4
|
748 |
-
},
|
749 |
-
"nbformat": 4,
|
750 |
-
"nbformat_minor": 2
|
751 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/downloadData.py
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
import pandas as pd
|
2 |
-
from api import update_portfolio_profile, get_stocks_price, get_benchmark_portfolio
|
3 |
-
|
4 |
-
portfolio_profile_data = [
|
5 |
-
|
6 |
-
]
|
7 |
-
|
8 |
-
|
9 |
-
def main():
|
10 |
-
# create a portfolio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/pipeline.ipynb
DELETED
@@ -1,521 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 36,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import pandas as pd\n",
|
10 |
-
"import math\n",
|
11 |
-
"from datetime import datetime\n",
|
12 |
-
"import hvplot.pandas\n",
|
13 |
-
"import math\n",
|
14 |
-
"import numpy as np\n",
|
15 |
-
"# load data\n",
|
16 |
-
"profile_df = pd.read_pickle('../data/portfolio_portfile.pkl')\n",
|
17 |
-
"benchmark_df = pd.read_pickle('../data/benchmark_portfolio.pkl')\n",
|
18 |
-
"portfolio_df = pd.read_pickle('../data/portfolio_data.pkl')"
|
19 |
-
]
|
20 |
-
},
|
21 |
-
{
|
22 |
-
"attachments": {},
|
23 |
-
"cell_type": "markdown",
|
24 |
-
"metadata": {},
|
25 |
-
"source": [
|
26 |
-
"## This section transfrom benchmark_df and creat an benchmark profile to accomadate current pipeline"
|
27 |
-
]
|
28 |
-
},
|
29 |
-
{
|
30 |
-
"cell_type": "code",
|
31 |
-
"execution_count": 37,
|
32 |
-
"metadata": {},
|
33 |
-
"outputs": [],
|
34 |
-
"source": [
|
35 |
-
"# drop weight\n",
|
36 |
-
"# benchmark_df = benchmark_df.drop(columns=['weight'])\n",
|
37 |
-
"\n",
|
38 |
-
"## simulate update potfolio weigth at 2021-01-10\n",
|
39 |
-
"update_profile_df = profile_df.copy()\n",
|
40 |
-
"update_profile_df['date'] = datetime(2021,1,10)\n",
|
41 |
-
"update_profile_df['weight'] = [50,100,200,300,400,500]\n",
|
42 |
-
"profile_df = pd.concat([profile_df, update_profile_df])\n"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
{
|
46 |
-
"cell_type": "code",
|
47 |
-
"execution_count": 38,
|
48 |
-
"metadata": {},
|
49 |
-
"outputs": [],
|
50 |
-
"source": [
|
51 |
-
"## create a profile for benchmark\n",
|
52 |
-
"b_profile = benchmark_df.drop_duplicates(subset=['ticker', 'actual_data'])\n",
|
53 |
-
"# df_unique[df_unique.ticker == \"000008.XSHE\"]\n",
|
54 |
-
"# only keep ticker\tdate\tweight\tdisplay_name\tname\tsector\taggregate_sector column\n",
|
55 |
-
"b_profile = b_profile[['ticker','date','weight','name','sector','aggregate_sector','display_name_x']]\n",
|
56 |
-
"b_profile.rename(columns={'display_name_x': 'display_name'}, inplace=True)"
|
57 |
-
]
|
58 |
-
},
|
59 |
-
{
|
60 |
-
"cell_type": "code",
|
61 |
-
"execution_count": 39,
|
62 |
-
"metadata": {},
|
63 |
-
"outputs": [
|
64 |
-
{
|
65 |
-
"data": {
|
66 |
-
"text/html": [
|
67 |
-
"<div>\n",
|
68 |
-
"<style scoped>\n",
|
69 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
70 |
-
" vertical-align: middle;\n",
|
71 |
-
" }\n",
|
72 |
-
"\n",
|
73 |
-
" .dataframe tbody tr th {\n",
|
74 |
-
" vertical-align: top;\n",
|
75 |
-
" }\n",
|
76 |
-
"\n",
|
77 |
-
" .dataframe thead th {\n",
|
78 |
-
" text-align: right;\n",
|
79 |
-
" }\n",
|
80 |
-
"</style>\n",
|
81 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
82 |
-
" <thead>\n",
|
83 |
-
" <tr style=\"text-align: right;\">\n",
|
84 |
-
" <th></th>\n",
|
85 |
-
" <th>date</th>\n",
|
86 |
-
" <th>ticker</th>\n",
|
87 |
-
" <th>open</th>\n",
|
88 |
-
" <th>close</th>\n",
|
89 |
-
" <th>high</th>\n",
|
90 |
-
" <th>low</th>\n",
|
91 |
-
" <th>volume</th>\n",
|
92 |
-
" <th>money</th>\n",
|
93 |
-
" </tr>\n",
|
94 |
-
" </thead>\n",
|
95 |
-
" <tbody>\n",
|
96 |
-
" <tr>\n",
|
97 |
-
" <th>0</th>\n",
|
98 |
-
" <td>2021-01-05</td>\n",
|
99 |
-
" <td>000008.XSHE</td>\n",
|
100 |
-
" <td>2.52</td>\n",
|
101 |
-
" <td>2.57</td>\n",
|
102 |
-
" <td>2.67</td>\n",
|
103 |
-
" <td>2.49</td>\n",
|
104 |
-
" <td>33215803.0</td>\n",
|
105 |
-
" <td>85358605.99</td>\n",
|
106 |
-
" </tr>\n",
|
107 |
-
" </tbody>\n",
|
108 |
-
"</table>\n",
|
109 |
-
"</div>"
|
110 |
-
],
|
111 |
-
"text/plain": [
|
112 |
-
" date ticker open close high low volume money\n",
|
113 |
-
"0 2021-01-05 000008.XSHE 2.52 2.57 2.67 2.49 33215803.0 85358605.99"
|
114 |
-
]
|
115 |
-
},
|
116 |
-
"execution_count": 39,
|
117 |
-
"metadata": {},
|
118 |
-
"output_type": "execute_result"
|
119 |
-
}
|
120 |
-
],
|
121 |
-
"source": [
|
122 |
-
"# drop weight in benchmark\n",
|
123 |
-
"benchmark_df = benchmark_df.drop(columns=['weight'])\n",
|
124 |
-
"benchmark_df = benchmark_df.drop(columns=['display_name_x'])\n",
|
125 |
-
"# drop display_name_y\n",
|
126 |
-
"benchmark_df = benchmark_df.drop(columns=['display_name_y'])\n",
|
127 |
-
"# drop actual_data\n",
|
128 |
-
"benchmark_df = benchmark_df.drop(columns=['actual_data'])\n",
|
129 |
-
"# drop name\n",
|
130 |
-
"benchmark_df = benchmark_df.drop(columns=['name'])\n",
|
131 |
-
"# drop aggregate_sector\n",
|
132 |
-
"benchmark_df = benchmark_df.drop(columns=['aggregate_sector'])\n",
|
133 |
-
"# drop sector\n",
|
134 |
-
"benchmark_df = benchmark_df.drop(columns=['sector'])\n",
|
135 |
-
"benchmark_df.head(1)"
|
136 |
-
]
|
137 |
-
},
|
138 |
-
{
|
139 |
-
"cell_type": "code",
|
140 |
-
"execution_count": 40,
|
141 |
-
"metadata": {},
|
142 |
-
"outputs": [],
|
143 |
-
"source": [
|
144 |
-
"for col_name in benchmark_df.columns:\n",
|
145 |
-
" if (col_name not in portfolio_df.columns):\n",
|
146 |
-
" print(f'portfolio does not have {col_name}')\n",
|
147 |
-
" \n",
|
148 |
-
"\n",
|
149 |
-
"for col_name in portfolio_df.columns:\n",
|
150 |
-
" if (col_name not in benchmark_df.columns):\n",
|
151 |
-
" print(f'benchmark does not have {col_name}')"
|
152 |
-
]
|
153 |
-
},
|
154 |
-
{
|
155 |
-
"cell_type": "code",
|
156 |
-
"execution_count": 41,
|
157 |
-
"metadata": {},
|
158 |
-
"outputs": [
|
159 |
-
{
|
160 |
-
"name": "stdout",
|
161 |
-
"output_type": "stream",
|
162 |
-
"text": [
|
163 |
-
"True\n",
|
164 |
-
"True\n",
|
165 |
-
"True\n",
|
166 |
-
"True\n",
|
167 |
-
"True\n",
|
168 |
-
"True\n",
|
169 |
-
"True\n",
|
170 |
-
"True\n",
|
171 |
-
"True\n",
|
172 |
-
"True\n",
|
173 |
-
"True\n",
|
174 |
-
"True\n",
|
175 |
-
"True\n",
|
176 |
-
"True\n"
|
177 |
-
]
|
178 |
-
}
|
179 |
-
],
|
180 |
-
"source": [
|
181 |
-
"for col_name in b_profile.columns:\n",
|
182 |
-
" print(col_name in profile_df.columns)\n",
|
183 |
-
"\n",
|
184 |
-
"for col_name in profile_df.columns:\n",
|
185 |
-
" print(col_name in b_profile.columns)"
|
186 |
-
]
|
187 |
-
},
|
188 |
-
{
|
189 |
-
"attachments": {},
|
190 |
-
"cell_type": "markdown",
|
191 |
-
"metadata": {},
|
192 |
-
"source": [
|
193 |
-
"## calculate result for each individual stock this part should return a table"
|
194 |
-
]
|
195 |
-
},
|
196 |
-
{
|
197 |
-
"cell_type": "code",
|
198 |
-
"execution_count": 42,
|
199 |
-
"metadata": {},
|
200 |
-
"outputs": [],
|
201 |
-
"source": [
|
202 |
-
"def get_processing_result_of_stocks_df(stock_df, profile_df):\n",
|
203 |
-
" ## add sector_name display_name name\n",
|
204 |
-
" ticker_sector_map = dict(zip(profile_df['ticker'], profile_df['aggregate_sector']))\n",
|
205 |
-
" ticker_display_name_map = dict(zip(profile_df['ticker'], profile_df['display_name']))\n",
|
206 |
-
" ticker_name_map = dict(zip(profile_df['ticker'], profile_df['name']))\n",
|
207 |
-
"\n",
|
208 |
-
" stock_df['display_name'] = stock_df['ticker'].map(ticker_display_name_map)\n",
|
209 |
-
" stock_df['name'] = stock_df['ticker'].map(ticker_name_map)\n",
|
210 |
-
" stock_df['aggregate_sector'] = stock_df['ticker'].map(ticker_sector_map)\n",
|
211 |
-
"\n",
|
212 |
-
" ## calculate pct using closing price\n",
|
213 |
-
" stock_df.sort_values(by=['date'], inplace=True)\n",
|
214 |
-
" stock_df['pct'] = stock_df.groupby('ticker')['close'].pct_change()\n",
|
215 |
-
"\n",
|
216 |
-
" ## calculate weight TODO: think about how to optimize this\n",
|
217 |
-
" stock_df = stock_df.merge(profile_df[['weight', 'date', 'ticker']], on=['ticker', 'date'], how='outer')\n",
|
218 |
-
" stock_df.rename(columns={'weight': 'initial_weight'}, inplace=True)\n",
|
219 |
-
" stock_df['current_weight'] = float('nan')\n",
|
220 |
-
" stock_df['previous_weight'] = float('nan')\n",
|
221 |
-
" df_grouped = stock_df.groupby('ticker')\n",
|
222 |
-
" for _, group in df_grouped:\n",
|
223 |
-
" pre_w = float('nan')\n",
|
224 |
-
" ini_w = float('nan')\n",
|
225 |
-
" for index, row in group.iterrows():\n",
|
226 |
-
" cur_w = float('nan')\n",
|
227 |
-
"\n",
|
228 |
-
" # if has initial weight, the following row all use this initial weight\n",
|
229 |
-
" if not pd.isna(row['initial_weight']):\n",
|
230 |
-
" ini_w = row['initial_weight']\n",
|
231 |
-
" cur_w = ini_w\n",
|
232 |
-
"\n",
|
233 |
-
" # just calculate current weight based on previous weight\n",
|
234 |
-
" else:\n",
|
235 |
-
" cur_w = pre_w * (1 + row['pct'])\n",
|
236 |
-
"\n",
|
237 |
-
" stock_df.loc[index, 'current_weight'] = cur_w \n",
|
238 |
-
" stock_df.loc[index, 'previous_weight'] = pre_w\n",
|
239 |
-
" stock_df.loc[index, 'initial_weight'] = ini_w\n",
|
240 |
-
" pre_w = cur_w\n",
|
241 |
-
"\n",
|
242 |
-
" stock_df.rename(columns={'weight': 'initial_weight'}, inplace=True)\n",
|
243 |
-
" stock_df.dropna(subset=['close'], inplace=True)\n",
|
244 |
-
"\n",
|
245 |
-
" ## normalize weight\n",
|
246 |
-
" stock_df['prev_w_in_p'] = stock_df['previous_weight'] / \\\n",
|
247 |
-
" stock_df.groupby('date')['previous_weight'].transform('sum')\n",
|
248 |
-
"\n",
|
249 |
-
" stock_df['ini_w_in_p'] = stock_df['initial_weight'] / \\\n",
|
250 |
-
" stock_df.groupby('date')['initial_weight'].transform('sum')\n",
|
251 |
-
"\n",
|
252 |
-
" ## calculate weighted pct in portfolio\n",
|
253 |
-
" stock_df['portfolio_pct'] = stock_df['pct'] * stock_df['prev_w_in_p']\n",
|
254 |
-
"\n",
|
255 |
-
" ## calculate weight in sector TODO: remove\n",
|
256 |
-
" stock_df['prev_w_in_sectore'] = stock_df['previous_weight'] / \\\n",
|
257 |
-
" stock_df.groupby(['date', 'aggregate_sector'])['previous_weight'].transform('sum')\n",
|
258 |
-
" stock_df['ini_w_in_sector'] = stock_df['initial_weight'] / \\\n",
|
259 |
-
" stock_df.groupby(['date', 'aggregate_sector'])['initial_weight'].transform('sum')\n",
|
260 |
-
" ## weighted pct in sector TODO: remove\n",
|
261 |
-
" stock_df['sector_pct'] = stock_df['pct'] * stock_df['prev_w_in_sectore']\n",
|
262 |
-
"\n",
|
263 |
-
" ## portfolio return\n",
|
264 |
-
" stock_df['cum_p_pct'] = stock_df.groupby('ticker')['portfolio_pct'].cumsum()\n",
|
265 |
-
" stock_df['portfolio_return'] = np.exp(stock_df['cum_p_pct']) -1 \n",
|
266 |
-
" # drop intermediate columns\n",
|
267 |
-
" stock_df = stock_df.drop(columns=['cum_p_pct'])\n",
|
268 |
-
"\n",
|
269 |
-
"\n",
|
270 |
-
" ## sector return TODO:remove \n",
|
271 |
-
" # stock_df['sector_return'] = stock_df['ini_w_in_sector'] * stock_df['return']\n",
|
272 |
-
"\n",
|
273 |
-
" return stock_df\n"
|
274 |
-
]
|
275 |
-
},
|
276 |
-
{
|
277 |
-
"cell_type": "code",
|
278 |
-
"execution_count": 43,
|
279 |
-
"metadata": {},
|
280 |
-
"outputs": [],
|
281 |
-
"source": [
|
282 |
-
"# portfolio_stock = get_processing_result_of_stocks_df(portfolio_df, profile_df)\n",
|
283 |
-
"# portfolio_stock[portfolio_stock.ticker == '002709.XSHE'][['date','portfolio_pct','prev_w_in_p','portfolio_return']]\n",
|
284 |
-
"# # benchmark_stock = get_processing_result_of_stocks_df(benchmark_df, b_profile)"
|
285 |
-
]
|
286 |
-
},
|
287 |
-
{
|
288 |
-
"cell_type": "code",
|
289 |
-
"execution_count": 44,
|
290 |
-
"metadata": {},
|
291 |
-
"outputs": [],
|
292 |
-
"source": [
|
293 |
-
"# profile_df.groupby('date')['weight'].sum()"
|
294 |
-
]
|
295 |
-
},
|
296 |
-
{
|
297 |
-
"cell_type": "code",
|
298 |
-
"execution_count": 45,
|
299 |
-
"metadata": {},
|
300 |
-
"outputs": [],
|
301 |
-
"source": [
|
302 |
-
"## total return by date\n",
|
303 |
-
"def get_portfolio_evaluation(portfolio_stock, benchmark_stock, profile_df):\n",
|
304 |
-
" # add pct of benchmark \n",
|
305 |
-
" merged_df = portfolio_stock.merge(benchmark_stock[['ticker','date','portfolio_pct','portfolio_return']], \n",
|
306 |
-
" on=['ticker','date'],how='left',suffixes=('_p','_b'))\n",
|
307 |
-
"\n",
|
308 |
-
" # sum up pct and return from portfolio and benchmark\n",
|
309 |
-
" merged_df = merged_df.groupby('date',as_index=False).agg({'portfolio_return_p':'sum',\n",
|
310 |
-
" 'portfolio_return_b':'sum',\n",
|
311 |
-
" 'portfolio_pct_p':'sum',\n",
|
312 |
-
" 'portfolio_pct_b':'sum'})\n",
|
313 |
-
"\n",
|
314 |
-
" # portfolio mkt cap\n",
|
315 |
-
" mkt_adjustment = pd.DataFrame(profile_df.groupby('date')['weight'].sum())\n",
|
316 |
-
" mkt_adjustment.rename(columns={'weight':'mkt_cap'}, inplace=True)\n",
|
317 |
-
" merged_df = merged_df.merge(mkt_adjustment, on=['date'], how='outer')\n",
|
318 |
-
"\n",
|
319 |
-
" for i in range(len(merged_df)):\n",
|
320 |
-
" if pd.isna(merged_df.loc[i, 'mkt_cap']):\n",
|
321 |
-
" merged_df.loc[i, 'mkt_cap'] = merged_df.loc[i-1, 'mkt_cap'] * (1 + merged_df.loc[i, 'portfolio_pct_p'])\n",
|
322 |
-
" # drop where portfolio_return_p is nan\n",
|
323 |
-
" merged_df.dropna(subset=['portfolio_return_p'], inplace=True)\n",
|
324 |
-
" # portfolio pnl TODO seem I can just use current wegith to do this\n",
|
325 |
-
" merged_df['prev_mkt_cap'] = merged_df['mkt_cap'].shift(1)\n",
|
326 |
-
" merged_df['pnl'] = merged_df['prev_mkt_cap'] * merged_df['portfolio_pct_p']\n",
|
327 |
-
"\n",
|
328 |
-
" # risk std(pct)\n",
|
329 |
-
" merged_df['risk'] = merged_df['portfolio_pct_p'].rolling(len(merged_df), min_periods=1).std() * math.sqrt(252)\n",
|
330 |
-
"\n",
|
331 |
-
" # active return\n",
|
332 |
-
" merged_df['active_return'] = merged_df['portfolio_pct_p'] - merged_df['portfolio_pct_b']\n",
|
333 |
-
"\n",
|
334 |
-
" # tracking errro std(active return)\n",
|
335 |
-
" merged_df['tracking_error'] = merged_df['active_return'].rolling(len(merged_df), min_periods=1).std() * math.sqrt(252)\n",
|
336 |
-
"\n",
|
337 |
-
" # cum pnl\n",
|
338 |
-
" merged_df['cum_pnl'] = merged_df['pnl'].cumsum()\n",
|
339 |
-
"\n",
|
340 |
-
" return merged_df\n"
|
341 |
-
]
|
342 |
-
},
|
343 |
-
{
|
344 |
-
"cell_type": "code",
|
345 |
-
"execution_count": 46,
|
346 |
-
"metadata": {},
|
347 |
-
"outputs": [],
|
348 |
-
"source": [
|
349 |
-
"# portfolio_eval_df = get_portfolio_evaluation(portfolio_stock, benchmark_stock, profile_df)"
|
350 |
-
]
|
351 |
-
},
|
352 |
-
{
|
353 |
-
"cell_type": "code",
|
354 |
-
"execution_count": 47,
|
355 |
-
"metadata": {},
|
356 |
-
"outputs": [],
|
357 |
-
"source": [
|
358 |
-
"# portfolio_stock.columns"
|
359 |
-
]
|
360 |
-
},
|
361 |
-
{
|
362 |
-
"cell_type": "code",
|
363 |
-
"execution_count": 48,
|
364 |
-
"metadata": {},
|
365 |
-
"outputs": [],
|
366 |
-
"source": [
|
367 |
-
"## TODO convert below to funciton\n",
|
368 |
-
"\n",
|
369 |
-
"def get_portfolio_sector_evaluation(portfolio_stock,benchmark_df):\n",
|
370 |
-
"# aggregate on sector and day\n",
|
371 |
-
" p_sector_df = portfolio_stock.groupby(['date','aggregate_sector'], as_index=False)\\\n",
|
372 |
-
" .agg({'prev_w_in_p': 'sum','ini_w_in_p':\"sum\",\"current_weight\":'sum',\\\n",
|
373 |
-
" \"portfolio_pct\":\"sum\", \"portfolio_return\":\"sum\"})\n",
|
374 |
-
" # TODO shrink it down before aggregate\n",
|
375 |
-
" b_sector_df = benchmark_df.groupby(['date','aggregate_sector'], as_index=False)\\\n",
|
376 |
-
" .agg({'prev_w_in_p': 'sum','ini_w_in_p':\"sum\",\"current_weight\":'sum',\\\n",
|
377 |
-
" \"portfolio_pct\":\"sum\", \"portfolio_return\":\"sum\"})\n",
|
378 |
-
" \n",
|
379 |
-
" # merge portfolio and benchmark\n",
|
380 |
-
" merge_df = p_sector_df.merge(b_sector_df, on=['date','aggregate_sector'], how='left', suffixes=('_p','_b'))\n",
|
381 |
-
"\n",
|
382 |
-
" return merge_df"
|
383 |
-
]
|
384 |
-
},
|
385 |
-
{
|
386 |
-
"cell_type": "code",
|
387 |
-
"execution_count": 49,
|
388 |
-
"metadata": {},
|
389 |
-
"outputs": [],
|
390 |
-
"source": [
|
391 |
-
"# sector_eval_df = get_portfolio_sector_evaluation(portfolio_stock, benchmark_stock)\n",
|
392 |
-
"# sector_eval_df[sector_eval_df.date == datetime(2021, 10,13)].hvplot.bar(x='aggregate_sector', y=['portfolio_pct_p','portfolio_pct_b'], stacked=True, rot=90, title='sector pct')"
|
393 |
-
]
|
394 |
-
},
|
395 |
-
{
|
396 |
-
"cell_type": "code",
|
397 |
-
"execution_count": 50,
|
398 |
-
"metadata": {},
|
399 |
-
"outputs": [],
|
400 |
-
"source": [
|
401 |
-
"def merge_on_date(portfolio_stock, benchmark_df):\n",
|
402 |
-
" p_selected = portfolio_stock.reset_index()[['ini_w_in_p', 'portfolio_return', 'date', 'ticker', 'display_name']]\n",
|
403 |
-
" b_selected = benchmark_df.reset_index()[['ini_w_in_p', 'portfolio_return', 'date', 'ticker']]\n",
|
404 |
-
" merged_stock_df = pd.merge(p_selected, b_selected, on=['date', 'ticker'], how='outer', suffixes=('_p', '_b'))\n",
|
405 |
-
" return merged_stock_df"
|
406 |
-
]
|
407 |
-
},
|
408 |
-
{
|
409 |
-
"cell_type": "code",
|
410 |
-
"execution_count": 51,
|
411 |
-
"metadata": {},
|
412 |
-
"outputs": [],
|
413 |
-
"source": [
|
414 |
-
"# merged_df = merge_on_date(portfolio_stock, benchmark_stock)"
|
415 |
-
]
|
416 |
-
},
|
417 |
-
{
|
418 |
-
"cell_type": "code",
|
419 |
-
"execution_count": 52,
|
420 |
-
"metadata": {},
|
421 |
-
"outputs": [],
|
422 |
-
"source": [
|
423 |
-
"def get_bhb_result(merged_stock_df):\n",
|
424 |
-
" # merged_stock_df['ini_w_in_p_p'].fillna(0, inplace=True)\n",
|
425 |
-
" # merged_stock_df['ini_w_in_p_b'].fillna(0, inplace=True)\n",
|
426 |
-
" # merged_stock_df['portfolio_return_b'].fillna(0, inplace=True)\n",
|
427 |
-
" # merged_stock_df['portfolio_return_p'].fillna(0, inplace=True)\n",
|
428 |
-
" # allocation\n",
|
429 |
-
" merged_stock_df['allocation'] = (merged_stock_df['ini_w_in_p_p'] - merged_stock_df['ini_w_in_p_b']) \\\n",
|
430 |
-
" * merged_stock_df['portfolio_return_b']\n",
|
431 |
-
"\n",
|
432 |
-
" # selection\n",
|
433 |
-
" merged_stock_df['selection'] = merged_stock_df['ini_w_in_p_b'] * \\\n",
|
434 |
-
" (merged_stock_df['portfolio_return_p'] - merged_stock_df['portfolio_return_b'])\n",
|
435 |
-
"\n",
|
436 |
-
" # interaction\n",
|
437 |
-
" merged_stock_df['interaction'] = (merged_stock_df['ini_w_in_p_p'] - merged_stock_df['ini_w_in_p_b']) * \\\n",
|
438 |
-
" (merged_stock_df['portfolio_return_p'] - merged_stock_df['portfolio_return_b'])\n",
|
439 |
-
"\n",
|
440 |
-
" # excess\n",
|
441 |
-
" merged_stock_df['excess'] = merged_stock_df['portfolio_return_p'] - merged_stock_df['portfolio_return_b']\n",
|
442 |
-
"\n",
|
443 |
-
" # replace inf with nan\n",
|
444 |
-
" merged_stock_df.replace([np.inf, -np.inf], np.nan, inplace=True)\n",
|
445 |
-
" return merged_stock_df"
|
446 |
-
]
|
447 |
-
},
|
448 |
-
{
|
449 |
-
"cell_type": "code",
|
450 |
-
"execution_count": 53,
|
451 |
-
"metadata": {},
|
452 |
-
"outputs": [],
|
453 |
-
"source": [
|
454 |
-
"# test ing pipeline here "
|
455 |
-
]
|
456 |
-
},
|
457 |
-
{
|
458 |
-
"cell_type": "code",
|
459 |
-
"execution_count": 54,
|
460 |
-
"metadata": {},
|
461 |
-
"outputs": [],
|
462 |
-
"source": [
|
463 |
-
"portfolio_stock = get_processing_result_of_stocks_df(portfolio_df, profile_df)\n",
|
464 |
-
"benchmark_stock = get_processing_result_of_stocks_df(benchmark_df, b_profile)\n",
|
465 |
-
"\n",
|
466 |
-
"portfolio_eval_df = get_portfolio_evaluation(portfolio_stock, benchmark_stock, profile_df)\n",
|
467 |
-
"sector_eval_df = get_portfolio_sector_evaluation(portfolio_stock, benchmark_stock)\n",
|
468 |
-
"merged_df = merge_on_date(portfolio_stock, benchmark_stock)\n",
|
469 |
-
"bnb_sector_result = get_bhb_result(sector_eval_df)\n",
|
470 |
-
"bnb_stock_result = get_bhb_result(merged_df)\n"
|
471 |
-
]
|
472 |
-
},
|
473 |
-
{
|
474 |
-
"cell_type": "code",
|
475 |
-
"execution_count": null,
|
476 |
-
"metadata": {},
|
477 |
-
"outputs": [],
|
478 |
-
"source": [
|
479 |
-
"# save result \n",
|
480 |
-
"portfolio_eval_df.to_pickle('../data/portfolio_eval_df.pkl')\n",
|
481 |
-
"sector_eval_df.to_pickle('../data/sector_eval_df.pkl')\n",
|
482 |
-
"# merged_df.to_csv('merged_df.csv')\n",
|
483 |
-
"bnb_sector_result.to_pickle('../data/bnb_sector_result.pkl')\n",
|
484 |
-
"bnb_stock_result.to_pickle('../data/bnb_stock_result.pkl')\n",
|
485 |
-
"profile_df.to_pickle('../data/protfolio_profile.pkl')\n",
|
486 |
-
"b_profile.to_pickle('../data/benchmark_profile.pkl')"
|
487 |
-
]
|
488 |
-
},
|
489 |
-
{
|
490 |
-
"cell_type": "code",
|
491 |
-
"execution_count": null,
|
492 |
-
"metadata": {},
|
493 |
-
"outputs": [],
|
494 |
-
"source": [
|
495 |
-
"# bnb_sector_result[bnb_sector_result.date == datetime(2021, 10,13)].hvplot.bar(x='aggregate_sector', y=['allocation','selection','interaction'], stacked=True, rot=90, title='sector allocation')"
|
496 |
-
]
|
497 |
-
}
|
498 |
-
],
|
499 |
-
"metadata": {
|
500 |
-
"kernelspec": {
|
501 |
-
"display_name": "portfolio_risk_assesment",
|
502 |
-
"language": "python",
|
503 |
-
"name": "python3"
|
504 |
-
},
|
505 |
-
"language_info": {
|
506 |
-
"codemirror_mode": {
|
507 |
-
"name": "ipython",
|
508 |
-
"version": 3
|
509 |
-
},
|
510 |
-
"file_extension": ".py",
|
511 |
-
"mimetype": "text/x-python",
|
512 |
-
"name": "python",
|
513 |
-
"nbconvert_exporter": "python",
|
514 |
-
"pygments_lexer": "ipython3",
|
515 |
-
"version": "3.11.4"
|
516 |
-
},
|
517 |
-
"orig_nbformat": 4
|
518 |
-
},
|
519 |
-
"nbformat": 4,
|
520 |
-
"nbformat_minor": 2
|
521 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/portfolio_eval_df.pkl
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:b8b82727132680652cd1ca9c9a10d8014a22c77a7fa901983f97db99367ed0e6
|
3 |
-
size 25105
|
|
|
|
|
|
|
|
script/processing.ipynb
DELETED
@@ -1,501 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"data": {
|
10 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
11 |
-
"application/vnd.holoviews_load.v0+json": ""
|
12 |
-
},
|
13 |
-
"metadata": {},
|
14 |
-
"output_type": "display_data"
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"data": {
|
18 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
19 |
-
"application/vnd.holoviews_load.v0+json": ""
|
20 |
-
},
|
21 |
-
"metadata": {},
|
22 |
-
"output_type": "display_data"
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"data": {
|
26 |
-
"text/html": [
|
27 |
-
"<style>*[data-root-id],\n",
|
28 |
-
"*[data-root-id] > * {\n",
|
29 |
-
" box-sizing: border-box;\n",
|
30 |
-
" font-family: var(--jp-ui-font-family);\n",
|
31 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
32 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
33 |
-
"}\n",
|
34 |
-
"\n",
|
35 |
-
"/* Override VSCode background color */\n",
|
36 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
37 |
-
" > .lm-Widget\n",
|
38 |
-
" > *[data-root-id]),\n",
|
39 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
40 |
-
" background-color: transparent !important;\n",
|
41 |
-
"}\n",
|
42 |
-
"</style>"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
"metadata": {},
|
46 |
-
"output_type": "display_data"
|
47 |
-
}
|
48 |
-
],
|
49 |
-
"source": [
|
50 |
-
"import pandas as pd\n",
|
51 |
-
"import math\n",
|
52 |
-
"from datetime import datetime\n",
|
53 |
-
"import hvplot.pandas\n",
|
54 |
-
"# load data\n",
|
55 |
-
"profile_df = pd.read_pickle('../data/portfolio_portfile.pkl')\n",
|
56 |
-
"benchmark_df = pd.read_pickle('../data/benchmark_portfolio.pkl')\n",
|
57 |
-
"portfolio_df = pd.read_pickle('../data/portfolio_data.pkl')"
|
58 |
-
]
|
59 |
-
},
|
60 |
-
{
|
61 |
-
"cell_type": "code",
|
62 |
-
"execution_count": 2,
|
63 |
-
"metadata": {},
|
64 |
-
"outputs": [],
|
65 |
-
"source": [
|
66 |
-
"## calculate pct using closing price for each date\n",
|
67 |
-
"portfolio_df.sort_values(by=['date'], inplace=True)\n",
|
68 |
-
"portfolio_df['pct'] = portfolio_df.groupby(['ticker'])['close'].pct_change()\n",
|
69 |
-
"\n",
|
70 |
-
"benchmark_df.sort_values(by=['date'], inplace=True)\n",
|
71 |
-
"benchmark_df['pct'] = benchmark_df.groupby(['ticker'])['close'].pct_change()\n"
|
72 |
-
]
|
73 |
-
},
|
74 |
-
{
|
75 |
-
"cell_type": "code",
|
76 |
-
"execution_count": 3,
|
77 |
-
"metadata": {},
|
78 |
-
"outputs": [],
|
79 |
-
"source": [
|
80 |
-
"## return and weight\n",
|
81 |
-
"merge_df = portfolio_df.merge(profile_df[['ticker','weight','date']], on=['ticker','date'], how='left')\n",
|
82 |
-
"merge_df.sort_values(by=['date'], inplace=True)\n",
|
83 |
-
"benchmark_df.sort_values(by=['date'], inplace=True)\n",
|
84 |
-
"\n",
|
85 |
-
"# return for each stock\n",
|
86 |
-
"# portfolio_df['return'] = portfolio_df['close'] / portfolio_df.groupby(['ticker'])['close'].transform('first') - 1\n",
|
87 |
-
"# benchmark_df['return'] = benchmark_df['close'] / benchmark_df.groupby(['ticker'])['close'].transform('first') - 1\n",
|
88 |
-
"\n",
|
89 |
-
"# stock return in portfolio\n",
|
90 |
-
"first_close_per_ticker = merge_df.groupby('ticker')['close'].transform('first')\n",
|
91 |
-
"merge_df['return'] = merge_df['close'] / first_close_per_ticker - 1\n",
|
92 |
-
"\n",
|
93 |
-
"# stock return in benchmark\n",
|
94 |
-
"first_close_per_ticker = benchmark_df.groupby('ticker')['close'].transform('first')\n",
|
95 |
-
"benchmark_df['return'] = benchmark_df['close'] / first_close_per_ticker - 1\n",
|
96 |
-
"\n",
|
97 |
-
"# weight\n",
|
98 |
-
"initial_weight = merge_df.groupby('ticker')['weight'].transform('first') \n",
|
99 |
-
"merge_df['weight'] = initial_weight + (merge_df['return'] * initial_weight)\n",
|
100 |
-
"\n",
|
101 |
-
"# initial_weight\n",
|
102 |
-
"# merge_df[merge_df.ticker==\"002709.XSHE\"]\n",
|
103 |
-
"# merge_df\n",
|
104 |
-
"# benchmark_df"
|
105 |
-
]
|
106 |
-
},
|
107 |
-
{
|
108 |
-
"cell_type": "code",
|
109 |
-
"execution_count": 4,
|
110 |
-
"metadata": {},
|
111 |
-
"outputs": [],
|
112 |
-
"source": [
|
113 |
-
"portfolio_df = merge_df"
|
114 |
-
]
|
115 |
-
},
|
116 |
-
{
|
117 |
-
"cell_type": "code",
|
118 |
-
"execution_count": 5,
|
119 |
-
"metadata": {},
|
120 |
-
"outputs": [],
|
121 |
-
"source": [
|
122 |
-
"## normalize weight\n",
|
123 |
-
"benchmark_df['norm_weight'] = benchmark_df['weight'] / benchmark_df.groupby(['date'])['weight'].transform('sum')\n",
|
124 |
-
"portfolio_df['norm_weight'] = portfolio_df['weight'] / portfolio_df.groupby(['date'])['weight'].transform('sum')"
|
125 |
-
]
|
126 |
-
},
|
127 |
-
{
|
128 |
-
"cell_type": "code",
|
129 |
-
"execution_count": 6,
|
130 |
-
"metadata": {},
|
131 |
-
"outputs": [],
|
132 |
-
"source": [
|
133 |
-
"## calculate weighted return\n",
|
134 |
-
"portfolio_df['weighted_pct'] = portfolio_df['pct'] * portfolio_df['norm_weight']\n",
|
135 |
-
"benchmark_df['weighted_pct'] = benchmark_df['pct'] * benchmark_df['norm_weight']\n"
|
136 |
-
]
|
137 |
-
},
|
138 |
-
{
|
139 |
-
"cell_type": "code",
|
140 |
-
"execution_count": 7,
|
141 |
-
"metadata": {},
|
142 |
-
"outputs": [],
|
143 |
-
"source": [
|
144 |
-
"## Calculate portfolio pct of return by summing the 'weighted_return' for each date\n",
|
145 |
-
"\n",
|
146 |
-
"# reset index becaue its a new table\n",
|
147 |
-
"portfolio_pct = portfolio_df.groupby('date')['weighted_pct'].sum().reset_index()\n",
|
148 |
-
"portfolio_pct.columns = ['date', 'pct']\n",
|
149 |
-
"\n",
|
150 |
-
"# benchmark pct summing the 'weighted_return' for each date\n",
|
151 |
-
"#TODO chagne to use new weight in order to perform simulation\n",
|
152 |
-
"benchmark_pct = benchmark_df.groupby('date')['weighted_pct'].sum().reset_index()\n",
|
153 |
-
"benchmark_pct.columns = ['date', 'pct']\n",
|
154 |
-
"\n",
|
155 |
-
"# 'date', 'portfolio_return', and 'benchmark_return' columns\n",
|
156 |
-
"return_result = pd.merge(portfolio_pct, benchmark_pct, on='date', suffixes=('_portfolio', '_benchmark'))"
|
157 |
-
]
|
158 |
-
},
|
159 |
-
{
|
160 |
-
"cell_type": "code",
|
161 |
-
"execution_count": 8,
|
162 |
-
"metadata": {},
|
163 |
-
"outputs": [],
|
164 |
-
"source": [
|
165 |
-
"## add total return\n",
|
166 |
-
"portfolio_df['weighted_return'] = portfolio_df['return'] * portfolio_df['norm_weight']\n",
|
167 |
-
"portfolio_return = portfolio_df.groupby('date')['weighted_return'].sum().reset_index()\n",
|
168 |
-
"portfolio_return.columns = ['date', 'return']\n",
|
169 |
-
"return_result = return_result.merge(portfolio_return, on='date')"
|
170 |
-
]
|
171 |
-
},
|
172 |
-
{
|
173 |
-
"cell_type": "code",
|
174 |
-
"execution_count": 9,
|
175 |
-
"metadata": {},
|
176 |
-
"outputs": [],
|
177 |
-
"source": [
|
178 |
-
"# daily_active_return\n",
|
179 |
-
"return_result['daily_active_return'] = return_result['pct_portfolio'] - return_result['pct_benchmark']"
|
180 |
-
]
|
181 |
-
},
|
182 |
-
{
|
183 |
-
"cell_type": "code",
|
184 |
-
"execution_count": 10,
|
185 |
-
"metadata": {},
|
186 |
-
"outputs": [],
|
187 |
-
"source": [
|
188 |
-
"# daily pnl\n",
|
189 |
-
"return_result['mkt_cap'] = None\n",
|
190 |
-
"\n",
|
191 |
-
"# assign initial market cap\n",
|
192 |
-
"# sum weight because it is the money invested in the stock\n",
|
193 |
-
"# TODO chagne here to add simulation functionality\n",
|
194 |
-
"return_result.loc[return_result['date'] == profile_df['date'].values[0],'mkt_cap'] = profile_df['weight'].sum()\n",
|
195 |
-
"return_result.sort_values(by=['date'], inplace=True)\n",
|
196 |
-
"\n",
|
197 |
-
"# calculate daily mkt_cap\n",
|
198 |
-
"for i in range(1, len(return_result)):\n",
|
199 |
-
" return_result.loc[i, 'mkt_cap'] = return_result.loc[i-1, 'mkt_cap'] * (1 + return_result.loc[i, 'pct_portfolio'])\n",
|
200 |
-
"\n",
|
201 |
-
"# calculate daily pnl\n",
|
202 |
-
"return_result['daily_pnl'] = return_result['mkt_cap'].diff()\n",
|
203 |
-
"\n",
|
204 |
-
"\n"
|
205 |
-
]
|
206 |
-
},
|
207 |
-
{
|
208 |
-
"cell_type": "code",
|
209 |
-
"execution_count": 11,
|
210 |
-
"metadata": {},
|
211 |
-
"outputs": [],
|
212 |
-
"source": [
|
213 |
-
"## return volatilty mean return tracking erro cumulative pnl\n",
|
214 |
-
"# volatitly\n",
|
215 |
-
"return_result['pct_volitity_p'] = return_result['pct_portfolio'].expanding().std() * math.sqrt(252)\n",
|
216 |
-
"return_result['pct_volitity_b'] = return_result['pct_benchmark'].expanding().std() * math.sqrt(252)\n",
|
217 |
-
"# mean return\n",
|
218 |
-
"return_result['mean_return'] = return_result['return'].mean()\n",
|
219 |
-
"# tracking error \n",
|
220 |
-
"return_result['tracking_error'] = return_result['daily_active_return'].expanding().std() * math.sqrt(252)\n",
|
221 |
-
"# cumulative pnl\n",
|
222 |
-
"return_result['cum_pnl'] = return_result['daily_pnl'].cumsum()\n",
|
223 |
-
"# drawdown \n",
|
224 |
-
"return_result['drawdown'] = (return_result['cum_pnl'] - return_result['cum_pnl'].cummax()) / return_result['cum_pnl'].cummax()"
|
225 |
-
]
|
226 |
-
},
|
227 |
-
{
|
228 |
-
"cell_type": "code",
|
229 |
-
"execution_count": 12,
|
230 |
-
"metadata": {},
|
231 |
-
"outputs": [],
|
232 |
-
"source": [
|
233 |
-
"## save\n",
|
234 |
-
"return_result.to_pickle('../data/risk_return_result.pkl')"
|
235 |
-
]
|
236 |
-
},
|
237 |
-
{
|
238 |
-
"cell_type": "code",
|
239 |
-
"execution_count": 13,
|
240 |
-
"metadata": {},
|
241 |
-
"outputs": [],
|
242 |
-
"source": [
|
243 |
-
"# add sector info to portfolio_df\n",
|
244 |
-
"portfolio_df = pd.merge(portfolio_df, profile_df[['ticker','aggregate_sector']], on='ticker', how='left')"
|
245 |
-
]
|
246 |
-
},
|
247 |
-
{
|
248 |
-
"cell_type": "code",
|
249 |
-
"execution_count": 14,
|
250 |
-
"metadata": {},
|
251 |
-
"outputs": [
|
252 |
-
{
|
253 |
-
"name": "stderr",
|
254 |
-
"output_type": "stream",
|
255 |
-
"text": [
|
256 |
-
"/var/folders/v5/2108rh5964q9j741wg_s8r1w0000gn/T/ipykernel_1263/1040563745.py:2: SettingWithCopyWarning: \n",
|
257 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
258 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
259 |
-
"\n",
|
260 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
261 |
-
" benchmark_df[benchmark_df.aggregate_sector.isna()].aggregate_sector = '其他'\n"
|
262 |
-
]
|
263 |
-
}
|
264 |
-
],
|
265 |
-
"source": [
|
266 |
-
"# hanlde sector is nan\n",
|
267 |
-
"benchmark_df[benchmark_df.aggregate_sector.isna()].aggregate_sector = '其他'\n",
|
268 |
-
"portfolio_df[portfolio_df.aggregate_sector.isna()].aggregate_sector = '其他'"
|
269 |
-
]
|
270 |
-
},
|
271 |
-
{
|
272 |
-
"cell_type": "code",
|
273 |
-
"execution_count": 15,
|
274 |
-
"metadata": {},
|
275 |
-
"outputs": [
|
276 |
-
{
|
277 |
-
"data": {
|
278 |
-
"text/html": [
|
279 |
-
"<div>\n",
|
280 |
-
"<style scoped>\n",
|
281 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
282 |
-
" vertical-align: middle;\n",
|
283 |
-
" }\n",
|
284 |
-
"\n",
|
285 |
-
" .dataframe tbody tr th {\n",
|
286 |
-
" vertical-align: top;\n",
|
287 |
-
" }\n",
|
288 |
-
"\n",
|
289 |
-
" .dataframe thead th {\n",
|
290 |
-
" text-align: right;\n",
|
291 |
-
" }\n",
|
292 |
-
"</style>\n",
|
293 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
294 |
-
" <thead>\n",
|
295 |
-
" <tr style=\"text-align: right;\">\n",
|
296 |
-
" <th></th>\n",
|
297 |
-
" <th>date</th>\n",
|
298 |
-
" <th>weight</th>\n",
|
299 |
-
" <th>display_name_x</th>\n",
|
300 |
-
" <th>actual_data</th>\n",
|
301 |
-
" <th>ticker</th>\n",
|
302 |
-
" <th>open</th>\n",
|
303 |
-
" <th>close</th>\n",
|
304 |
-
" <th>high</th>\n",
|
305 |
-
" <th>low</th>\n",
|
306 |
-
" <th>volume</th>\n",
|
307 |
-
" <th>money</th>\n",
|
308 |
-
" <th>display_name_y</th>\n",
|
309 |
-
" <th>name</th>\n",
|
310 |
-
" <th>sector</th>\n",
|
311 |
-
" <th>aggregate_sector</th>\n",
|
312 |
-
" <th>pct</th>\n",
|
313 |
-
" <th>return</th>\n",
|
314 |
-
" <th>norm_weight</th>\n",
|
315 |
-
" <th>weighted_pct</th>\n",
|
316 |
-
" </tr>\n",
|
317 |
-
" </thead>\n",
|
318 |
-
" <tbody>\n",
|
319 |
-
" <tr>\n",
|
320 |
-
" <th>0</th>\n",
|
321 |
-
" <td>2021-01-05</td>\n",
|
322 |
-
" <td>0.088</td>\n",
|
323 |
-
" <td>神州高铁</td>\n",
|
324 |
-
" <td>2020-12-31</td>\n",
|
325 |
-
" <td>000008.XSHE</td>\n",
|
326 |
-
" <td>2.52</td>\n",
|
327 |
-
" <td>2.57</td>\n",
|
328 |
-
" <td>2.67</td>\n",
|
329 |
-
" <td>2.49</td>\n",
|
330 |
-
" <td>33215803.0</td>\n",
|
331 |
-
" <td>85358605.99</td>\n",
|
332 |
-
" <td>神州高铁</td>\n",
|
333 |
-
" <td>SZGT</td>\n",
|
334 |
-
" <td>机械设备I 运输设备II 铁路设备III 铁路、船舶、航空航天和其他运输设备制造业 城轨铁路 工业</td>\n",
|
335 |
-
" <td>工业</td>\n",
|
336 |
-
" <td>NaN</td>\n",
|
337 |
-
" <td>0.0</td>\n",
|
338 |
-
" <td>0.00088</td>\n",
|
339 |
-
" <td>NaN</td>\n",
|
340 |
-
" </tr>\n",
|
341 |
-
" </tbody>\n",
|
342 |
-
"</table>\n",
|
343 |
-
"</div>"
|
344 |
-
],
|
345 |
-
"text/plain": [
|
346 |
-
" date weight display_name_x actual_data ticker open close \\\n",
|
347 |
-
"0 2021-01-05 0.088 神州高铁 2020-12-31 000008.XSHE 2.52 2.57 \n",
|
348 |
-
"\n",
|
349 |
-
" high low volume money display_name_y name \\\n",
|
350 |
-
"0 2.67 2.49 33215803.0 85358605.99 神州高铁 SZGT \n",
|
351 |
-
"\n",
|
352 |
-
" sector aggregate_sector pct \\\n",
|
353 |
-
"0 机械设备I 运输设备II 铁路设备III 铁路、船舶、航空航天和其他运输设备制造业 城轨铁路 工业 工业 NaN \n",
|
354 |
-
"\n",
|
355 |
-
" return norm_weight weighted_pct \n",
|
356 |
-
"0 0.0 0.00088 NaN "
|
357 |
-
]
|
358 |
-
},
|
359 |
-
"execution_count": 15,
|
360 |
-
"metadata": {},
|
361 |
-
"output_type": "execute_result"
|
362 |
-
}
|
363 |
-
],
|
364 |
-
"source": [
|
365 |
-
"benchmark_df.head(1)"
|
366 |
-
]
|
367 |
-
},
|
368 |
-
{
|
369 |
-
"cell_type": "code",
|
370 |
-
"execution_count": 16,
|
371 |
-
"metadata": {},
|
372 |
-
"outputs": [],
|
373 |
-
"source": [
|
374 |
-
"## aggregate as sector \n",
|
375 |
-
"\n",
|
376 |
-
"# weighted return in a sector, weight in a sector\n",
|
377 |
-
"portfolio_df['weight_in_sector'] = portfolio_df['norm_weight']/ portfolio_df.groupby(['aggregate_sector','date'])['weight'].transform('sum')\n",
|
378 |
-
"portfolio_df['weighted_s_return'] = portfolio_df['return'] * portfolio_df['weight_in_sector']\n",
|
379 |
-
"\n",
|
380 |
-
"# return and weight by sector\n",
|
381 |
-
"return_by_sector = portfolio_df.groupby(['aggregate_sector','date'])['weighted_s_return'].sum().reset_index()\n",
|
382 |
-
"normed_sector_weight = portfolio_df.groupby(['aggregate_sector','date'])['norm_weight'].sum().reset_index()\n",
|
383 |
-
"p_sector_result = pd.merge(return_by_sector, normed_sector_weight, on=['aggregate_sector','date'], how='left')\n",
|
384 |
-
"p_sector_result.rename(columns={'weighted_s_return':'return'}, inplace=True)\n",
|
385 |
-
"\n",
|
386 |
-
"# same thing for benchmark\n",
|
387 |
-
"benchmark_df['weight_in_sector'] = benchmark_df['norm_weight']/ benchmark_df.groupby(['aggregate_sector','date'])['norm_weight'].transform('sum')\n",
|
388 |
-
"benchmark_df['weighted_s_return'] = benchmark_df['return'] * benchmark_df['weight_in_sector']\n",
|
389 |
-
"return_by_sector = benchmark_df.groupby(['aggregate_sector','date'])['weighted_s_return'].sum().reset_index()\n",
|
390 |
-
"normed_sector_weight = benchmark_df.groupby(['aggregate_sector','date'])['norm_weight'].sum().reset_index()\n",
|
391 |
-
"b_sector_result = pd.merge(return_by_sector, normed_sector_weight, on=['aggregate_sector','date'], how='left')\n",
|
392 |
-
"b_sector_result.rename(columns={'weighted_s_return':'return'}, inplace=True)\n"
|
393 |
-
]
|
394 |
-
},
|
395 |
-
{
|
396 |
-
"cell_type": "code",
|
397 |
-
"execution_count": 17,
|
398 |
-
"metadata": {},
|
399 |
-
"outputs": [],
|
400 |
-
"source": [
|
401 |
-
"## selection, allocation, interaction for sector\n",
|
402 |
-
"\n",
|
403 |
-
"\n",
|
404 |
-
"bnb_result_sector = pd.merge(\n",
|
405 |
-
" p_sector_result, b_sector_result,\n",
|
406 |
-
" on=['date','aggregate_sector',], how='outer', suffixes=('_p', '_b'))\n",
|
407 |
-
"\n",
|
408 |
-
"# replace nan norm_weight_b with 0\n",
|
409 |
-
"bnb_result_sector['norm_weight_b'] = bnb_result_sector['norm_weight_b'].fillna(0)\n",
|
410 |
-
"bnb_result_sector['norm_weight_p'] = bnb_result_sector['norm_weight_p'].fillna(0)\n",
|
411 |
-
"\n",
|
412 |
-
"# active weight\n",
|
413 |
-
"bnb_result_sector['active_weight'] = bnb_result_sector['norm_weight_p'] - bnb_result_sector['norm_weight_b']\n",
|
414 |
-
"\n",
|
415 |
-
"# allocation \n",
|
416 |
-
"bnb_result_sector['allocation'] = bnb_result_sector['active_weight'] * bnb_result_sector['return_b']\n",
|
417 |
-
"\n",
|
418 |
-
"#selection\n",
|
419 |
-
"bnb_result_sector['selection'] = bnb_result_sector['norm_weight_p'] * (bnb_result_sector['return_p'] - bnb_result_sector['return_b'])\n",
|
420 |
-
"\n",
|
421 |
-
"#inetration\n",
|
422 |
-
"bnb_result_sector['interaction'] = (bnb_result_sector['norm_weight_p'] - bnb_result_sector['norm_weight_b']) *\\\n",
|
423 |
-
" (bnb_result_sector['return_p'] - bnb_result_sector['return_b'])"
|
424 |
-
]
|
425 |
-
},
|
426 |
-
{
|
427 |
-
"cell_type": "code",
|
428 |
-
"execution_count": 18,
|
429 |
-
"metadata": {},
|
430 |
-
"outputs": [],
|
431 |
-
"source": [
|
432 |
-
"## save result \n",
|
433 |
-
"bnb_result_sector.to_pickle('../data/bnb_result_sector.pkl')"
|
434 |
-
]
|
435 |
-
},
|
436 |
-
{
|
437 |
-
"cell_type": "code",
|
438 |
-
"execution_count": 19,
|
439 |
-
"metadata": {},
|
440 |
-
"outputs": [],
|
441 |
-
"source": [
|
442 |
-
"## selection, allocation, interaction for stocks\n",
|
443 |
-
"\n",
|
444 |
-
"# I keep weight to exame the stock not in benchmark but in portfolio and vice versa\n",
|
445 |
-
"bnb_result = pd.merge(\n",
|
446 |
-
" portfolio_df[['date','ticker','norm_weight','weight','return','aggregate_sector']],\n",
|
447 |
-
" benchmark_df[['date','ticker','norm_weight','weight','return']], on=['date','ticker',], how='outer', suffixes=('_p', '_b'))\n",
|
448 |
-
"\n",
|
449 |
-
"# replace nan norm_weight_b with 0\n",
|
450 |
-
"bnb_result['norm_weight_b'] = bnb_result['norm_weight_b'].fillna(0)\n",
|
451 |
-
"bnb_result['norm_weight_p'] = bnb_result['norm_weight_p'].fillna(0)\n",
|
452 |
-
"\n",
|
453 |
-
"# active weight\n",
|
454 |
-
"bnb_result['active_weight'] = bnb_result['norm_weight_p'] - bnb_result['norm_weight_b']\n",
|
455 |
-
"\n",
|
456 |
-
"# allocation \n",
|
457 |
-
"bnb_result['allocation'] = bnb_result['active_weight'] * bnb_result['return_b']\n",
|
458 |
-
"\n",
|
459 |
-
"#selection\n",
|
460 |
-
"bnb_result['selection'] = bnb_result['norm_weight_p'] * (bnb_result['return_p'] - bnb_result['return_b'])\n",
|
461 |
-
"\n",
|
462 |
-
"#inetration\n",
|
463 |
-
"bnb_result['interaction'] = (bnb_result['norm_weight_p'] - bnb_result['norm_weight_b']) *\\\n",
|
464 |
-
" (bnb_result['return_p'] - bnb_result['return_b'])\n",
|
465 |
-
"\n"
|
466 |
-
]
|
467 |
-
},
|
468 |
-
{
|
469 |
-
"cell_type": "code",
|
470 |
-
"execution_count": 20,
|
471 |
-
"metadata": {},
|
472 |
-
"outputs": [],
|
473 |
-
"source": [
|
474 |
-
"## svae\n",
|
475 |
-
"bnb_result.to_pickle('../data/bnb_result.pkl')"
|
476 |
-
]
|
477 |
-
}
|
478 |
-
],
|
479 |
-
"metadata": {
|
480 |
-
"kernelspec": {
|
481 |
-
"display_name": "portfolio_risk_assesment",
|
482 |
-
"language": "python",
|
483 |
-
"name": "python3"
|
484 |
-
},
|
485 |
-
"language_info": {
|
486 |
-
"codemirror_mode": {
|
487 |
-
"name": "ipython",
|
488 |
-
"version": 3
|
489 |
-
},
|
490 |
-
"file_extension": ".py",
|
491 |
-
"mimetype": "text/x-python",
|
492 |
-
"name": "python",
|
493 |
-
"nbconvert_exporter": "python",
|
494 |
-
"pygments_lexer": "ipython3",
|
495 |
-
"version": "3.11.4"
|
496 |
-
},
|
497 |
-
"orig_nbformat": 4
|
498 |
-
},
|
499 |
-
"nbformat": 4,
|
500 |
-
"nbformat_minor": 2
|
501 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/processing2.ipynb
DELETED
@@ -1,1836 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 142,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import pandas as pd\n",
|
10 |
-
"import math\n",
|
11 |
-
"from datetime import datetime\n",
|
12 |
-
"import hvplot.pandas\n",
|
13 |
-
"import math\n",
|
14 |
-
"# load data\n",
|
15 |
-
"profile_df = pd.read_pickle('../data/portfolio_portfile.pkl')\n",
|
16 |
-
"benchmark_df = pd.read_pickle('../data/benchmark_portfolio.pkl')\n",
|
17 |
-
"portfolio_df = pd.read_pickle('../data/portfolio_data.pkl')"
|
18 |
-
]
|
19 |
-
},
|
20 |
-
{
|
21 |
-
"cell_type": "code",
|
22 |
-
"execution_count": 143,
|
23 |
-
"metadata": {},
|
24 |
-
"outputs": [],
|
25 |
-
"source": [
|
26 |
-
"# to acoomodate the current pipe line\n",
|
27 |
-
"min_dates = benchmark_df.groupby('ticker')['date'].min()\n",
|
28 |
-
"\n",
|
29 |
-
"for ticker, min_date in min_dates.items():\n",
|
30 |
-
" benchmark_df.loc[(benchmark_df['ticker'] == ticker) & (benchmark_df['date'] != min_date), 'weight'] = float('nan')\n",
|
31 |
-
"\n",
|
32 |
-
"benchmark_df['initial_weight'] = benchmark_df['weight']\n",
|
33 |
-
"# drop weight\n",
|
34 |
-
"benchmark_df = benchmark_df.drop(columns=['weight'])"
|
35 |
-
]
|
36 |
-
},
|
37 |
-
{
|
38 |
-
"cell_type": "code",
|
39 |
-
"execution_count": 144,
|
40 |
-
"metadata": {},
|
41 |
-
"outputs": [
|
42 |
-
{
|
43 |
-
"data": {
|
44 |
-
"text/plain": [
|
45 |
-
"Series([], Name: initial_weight, dtype: int64)"
|
46 |
-
]
|
47 |
-
},
|
48 |
-
"execution_count": 144,
|
49 |
-
"metadata": {},
|
50 |
-
"output_type": "execute_result"
|
51 |
-
}
|
52 |
-
],
|
53 |
-
"source": [
|
54 |
-
"# check if all unique ticker has an weight\n",
|
55 |
-
"count_list = benchmark_df.groupby('ticker')['initial_weight'].count().sort_values(ascending=False)\n",
|
56 |
-
"count_list[count_list != 1]\n"
|
57 |
-
]
|
58 |
-
},
|
59 |
-
{
|
60 |
-
"cell_type": "code",
|
61 |
-
"execution_count": 145,
|
62 |
-
"metadata": {},
|
63 |
-
"outputs": [],
|
64 |
-
"source": [
|
65 |
-
"update_profile_df = profile_df.copy()\n",
|
66 |
-
"update_profile_df['date'] = datetime(2021,1,10)\n",
|
67 |
-
"update_profile_df['weight'] = [50,100,200,300,400,500]\n",
|
68 |
-
"profile_df = pd.concat([profile_df, update_profile_df])\n"
|
69 |
-
]
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"cell_type": "code",
|
73 |
-
"execution_count": 146,
|
74 |
-
"metadata": {},
|
75 |
-
"outputs": [],
|
76 |
-
"source": [
|
77 |
-
"def calculate_pct(stock_df):\n",
|
78 |
-
" stock_df['pct'] = stock_df.groupby(['ticker'])['close'].pct_change()\n"
|
79 |
-
]
|
80 |
-
},
|
81 |
-
{
|
82 |
-
"cell_type": "code",
|
83 |
-
"execution_count": 147,
|
84 |
-
"metadata": {},
|
85 |
-
"outputs": [],
|
86 |
-
"source": [
|
87 |
-
"# step 1 pct\n",
|
88 |
-
"calculate_pct(portfolio_df)\n",
|
89 |
-
"calculate_pct(benchmark_df)"
|
90 |
-
]
|
91 |
-
},
|
92 |
-
{
|
93 |
-
"cell_type": "code",
|
94 |
-
"execution_count": 148,
|
95 |
-
"metadata": {},
|
96 |
-
"outputs": [],
|
97 |
-
"source": [
|
98 |
-
"def return_weighted_stock_df(stock_price_df, profile_df=None):\n",
|
99 |
-
" # TODO change later this a temporary solution\n",
|
100 |
-
" # initialize weight if profile_df is not none\n",
|
101 |
-
" merged_df = pd.DataFrame()\n",
|
102 |
-
" if profile_df is not None:\n",
|
103 |
-
" merged_df = stock_price_df.merge(profile_df[['weight', 'date', 'ticker']], on=['ticker', 'date'], how='outer')\n",
|
104 |
-
" merged_df.sort_values(by=['date'], inplace=True)\n",
|
105 |
-
" merged_df.rename(columns={'weight': 'initial_weight'}, inplace=True)\n",
|
106 |
-
" else:\n",
|
107 |
-
" merged_df = stock_price_df.copy()\n",
|
108 |
-
" merged_df['current_weight'] = float('nan')\n",
|
109 |
-
" merged_df['previous_weight'] = float('nan')\n",
|
110 |
-
" df_grouped = merged_df.groupby('ticker')\n",
|
111 |
-
" for _, group in df_grouped:\n",
|
112 |
-
" pre_w = float('nan')\n",
|
113 |
-
" ini_w = float('nan')\n",
|
114 |
-
" for index, row in group.iterrows():\n",
|
115 |
-
" cur_w = float('nan')\n",
|
116 |
-
" # if has initial weight, the following row all use this initial weight\n",
|
117 |
-
" if not pd.isna(row['initial_weight']):\n",
|
118 |
-
" ini_w = row['initial_weight']\n",
|
119 |
-
" cur_w = ini_w\n",
|
120 |
-
" # just calculate current weight based on previous weight\n",
|
121 |
-
" else:\n",
|
122 |
-
" cur_w = pre_w * (1 + row['pct'])\n",
|
123 |
-
"\n",
|
124 |
-
" merged_df.loc[index, 'current_weight'] = cur_w \n",
|
125 |
-
" merged_df.loc[index, 'previous_weight'] = pre_w\n",
|
126 |
-
" merged_df.loc[index, 'initial_weight'] = ini_w\n",
|
127 |
-
" pre_w = cur_w\n",
|
128 |
-
" \n",
|
129 |
-
" # drop row where closing price is none\n",
|
130 |
-
" merged_df = merged_df[~pd.isna(merged_df['close'])]\n",
|
131 |
-
" # drop index\n",
|
132 |
-
" return merged_df"
|
133 |
-
]
|
134 |
-
},
|
135 |
-
{
|
136 |
-
"cell_type": "code",
|
137 |
-
"execution_count": 149,
|
138 |
-
"metadata": {},
|
139 |
-
"outputs": [],
|
140 |
-
"source": [
|
141 |
-
"# TODO consider save the weight calculation\n",
|
142 |
-
"portfolio_df = return_weighted_stock_df(portfolio_df, profile_df)\n",
|
143 |
-
"benchmark_df = return_weighted_stock_df(benchmark_df)"
|
144 |
-
]
|
145 |
-
},
|
146 |
-
{
|
147 |
-
"cell_type": "code",
|
148 |
-
"execution_count": 150,
|
149 |
-
"metadata": {},
|
150 |
-
"outputs": [],
|
151 |
-
"source": [
|
152 |
-
"# benchmark_df[benchmark_df.ticker =='000008.XSHE']"
|
153 |
-
]
|
154 |
-
},
|
155 |
-
{
|
156 |
-
"cell_type": "code",
|
157 |
-
"execution_count": 151,
|
158 |
-
"metadata": {},
|
159 |
-
"outputs": [],
|
160 |
-
"source": [
|
161 |
-
"## normalize all weight\n",
|
162 |
-
"def normalize_weight(stock_df):\n",
|
163 |
-
" stock_df['current_weight'] = stock_df['current_weight'] / \\\n",
|
164 |
-
" stock_df.groupby('date')['current_weight'].transform('sum')\n",
|
165 |
-
"\n",
|
166 |
-
" stock_df['previous_weight'] = stock_df['previous_weight'] / \\\n",
|
167 |
-
" stock_df.groupby('date')['previous_weight'].transform('sum')\n",
|
168 |
-
"\n",
|
169 |
-
" stock_df['initial_weight'] = stock_df['initial_weight'] / \\\n",
|
170 |
-
" stock_df.groupby('date')['initial_weight'].transform('sum')\n"
|
171 |
-
]
|
172 |
-
},
|
173 |
-
{
|
174 |
-
"cell_type": "code",
|
175 |
-
"execution_count": 152,
|
176 |
-
"metadata": {},
|
177 |
-
"outputs": [],
|
178 |
-
"source": [
|
179 |
-
"normalize_weight(portfolio_df)\n",
|
180 |
-
"normalize_weight(benchmark_df)"
|
181 |
-
]
|
182 |
-
},
|
183 |
-
{
|
184 |
-
"cell_type": "code",
|
185 |
-
"execution_count": 153,
|
186 |
-
"metadata": {},
|
187 |
-
"outputs": [
|
188 |
-
{
|
189 |
-
"data": {
|
190 |
-
"text/plain": [
|
191 |
-
"260 0.032258\n",
|
192 |
-
"258 0.064516\n",
|
193 |
-
"262 0.129032\n",
|
194 |
-
"263 0.258065\n",
|
195 |
-
"259 0.322581\n",
|
196 |
-
"261 0.193548\n",
|
197 |
-
"Name: initial_weight, dtype: float64"
|
198 |
-
]
|
199 |
-
},
|
200 |
-
"execution_count": 153,
|
201 |
-
"metadata": {},
|
202 |
-
"output_type": "execute_result"
|
203 |
-
}
|
204 |
-
],
|
205 |
-
"source": [
|
206 |
-
"portfolio_df[portfolio_df.date == datetime(2021, 3, 12)]['initial_weight']"
|
207 |
-
]
|
208 |
-
},
|
209 |
-
{
|
210 |
-
"cell_type": "code",
|
211 |
-
"execution_count": 154,
|
212 |
-
"metadata": {},
|
213 |
-
"outputs": [
|
214 |
-
{
|
215 |
-
"name": "stdout",
|
216 |
-
"output_type": "stream",
|
217 |
-
"text": [
|
218 |
-
"1.0\n",
|
219 |
-
"1.0\n",
|
220 |
-
"1.0\n"
|
221 |
-
]
|
222 |
-
}
|
223 |
-
],
|
224 |
-
"source": [
|
225 |
-
"print(benchmark_df[benchmark_df.date == datetime(2021, 3, 12)]['initial_weight'].sum())\n",
|
226 |
-
"print(benchmark_df[benchmark_df.date == datetime(2021, 3, 12)]['current_weight'].sum())\n",
|
227 |
-
"print(benchmark_df[benchmark_df.date == datetime(2021, 3, 12)]['previous_weight'].sum())"
|
228 |
-
]
|
229 |
-
},
|
230 |
-
{
|
231 |
-
"cell_type": "code",
|
232 |
-
"execution_count": 155,
|
233 |
-
"metadata": {},
|
234 |
-
"outputs": [],
|
235 |
-
"source": [
|
236 |
-
"# step 3 sector wegiht\n",
|
237 |
-
"\n",
|
238 |
-
"# add sector information first\n",
|
239 |
-
"def create_sector_weight(stock_df, profile_df=None):\n",
|
240 |
-
" # if profile_df is none assume the aggregate_sector stock info already in stock_df\n",
|
241 |
-
" merged_df = None\n",
|
242 |
-
" if profile_df is not None:\n",
|
243 |
-
" merged_df = stock_df.merge(profile_df[['ticker', 'aggregate_sector']], on='ticker', how='left')\n",
|
244 |
-
" else:\n",
|
245 |
-
" merged_df = stock_df.copy()\n",
|
246 |
-
" # set null to others\n",
|
247 |
-
" merged_df['aggregate_sector'] = merged_df['aggregate_sector'].fillna('其他')\n",
|
248 |
-
" # calculate previous_sector_weight\n",
|
249 |
-
" merged_df['previous_sector_weight'] = merged_df['previous_weight'] / \\\n",
|
250 |
-
" merged_df.groupby(['date', 'aggregate_sector'])['previous_weight'].transform('sum')\n",
|
251 |
-
" # calculate initial sectore weight\n",
|
252 |
-
" merged_df['initial_sector_weight'] = merged_df['initial_weight'] / \\\n",
|
253 |
-
" merged_df.groupby(['date', 'aggregate_sector'])['initial_weight'].transform('sum')\n",
|
254 |
-
" \n",
|
255 |
-
" return merged_df"
|
256 |
-
]
|
257 |
-
},
|
258 |
-
{
|
259 |
-
"cell_type": "code",
|
260 |
-
"execution_count": 156,
|
261 |
-
"metadata": {},
|
262 |
-
"outputs": [],
|
263 |
-
"source": [
|
264 |
-
"portfolio_df = create_sector_weight(stock_df = portfolio_df, profile_df = profile_df)\n",
|
265 |
-
"benchmark_df = create_sector_weight(benchmark_df)\n"
|
266 |
-
]
|
267 |
-
},
|
268 |
-
{
|
269 |
-
"cell_type": "code",
|
270 |
-
"execution_count": 157,
|
271 |
-
"metadata": {},
|
272 |
-
"outputs": [
|
273 |
-
{
|
274 |
-
"name": "stdout",
|
275 |
-
"output_type": "stream",
|
276 |
-
"text": [
|
277 |
-
"aggregate_sector\n",
|
278 |
-
"信息与通信 1.0\n",
|
279 |
-
"公用事业 1.0\n",
|
280 |
-
"其他 1.0\n",
|
281 |
-
"医药卫生 1.0\n",
|
282 |
-
"原料与能源 1.0\n",
|
283 |
-
"工业 1.0\n",
|
284 |
-
"消费 1.0\n",
|
285 |
-
"金融与地产 1.0\n",
|
286 |
-
"Name: previous_sector_weight, dtype: float64\n",
|
287 |
-
"aggregate_sector\n",
|
288 |
-
"信息与通信 1.0\n",
|
289 |
-
"公用事业 1.0\n",
|
290 |
-
"其他 1.0\n",
|
291 |
-
"医药卫生 1.0\n",
|
292 |
-
"原料与能源 1.0\n",
|
293 |
-
"工业 1.0\n",
|
294 |
-
"消费 1.0\n",
|
295 |
-
"金融与地产 1.0\n",
|
296 |
-
"Name: initial_sector_weight, dtype: float64\n"
|
297 |
-
]
|
298 |
-
}
|
299 |
-
],
|
300 |
-
"source": [
|
301 |
-
"# check result \n",
|
302 |
-
"print(benchmark_df[benchmark_df.date == datetime(2021, 3, 12)].groupby('aggregate_sector')['previous_sector_weight'].sum())\n",
|
303 |
-
"print(benchmark_df[benchmark_df.date == datetime(2021, 3, 12)].groupby('aggregate_sector')['initial_sector_weight'].sum())\n"
|
304 |
-
]
|
305 |
-
},
|
306 |
-
{
|
307 |
-
"cell_type": "code",
|
308 |
-
"execution_count": 158,
|
309 |
-
"metadata": {},
|
310 |
-
"outputs": [
|
311 |
-
{
|
312 |
-
"name": "stdout",
|
313 |
-
"output_type": "stream",
|
314 |
-
"text": [
|
315 |
-
"aggregate_sector\n",
|
316 |
-
"信息与通信 1.0\n",
|
317 |
-
"医药卫生 1.0\n",
|
318 |
-
"原料与能源 1.0\n",
|
319 |
-
"工业 1.0\n",
|
320 |
-
"消费 1.0\n",
|
321 |
-
"Name: previous_sector_weight, dtype: float64\n",
|
322 |
-
"aggregate_sector\n",
|
323 |
-
"信息与通信 1.0\n",
|
324 |
-
"医药卫生 1.0\n",
|
325 |
-
"原料与能源 1.0\n",
|
326 |
-
"工业 1.0\n",
|
327 |
-
"消费 1.0\n",
|
328 |
-
"Name: initial_sector_weight, dtype: float64\n"
|
329 |
-
]
|
330 |
-
}
|
331 |
-
],
|
332 |
-
"source": [
|
333 |
-
"# check result \n",
|
334 |
-
"print(portfolio_df[portfolio_df.date == datetime(2021, 3, 12)].groupby('aggregate_sector')['previous_sector_weight'].sum())\n",
|
335 |
-
"print(portfolio_df[portfolio_df.date == datetime(2021, 3, 12)].groupby('aggregate_sector')['initial_sector_weight'].sum())\n"
|
336 |
-
]
|
337 |
-
},
|
338 |
-
{
|
339 |
-
"cell_type": "code",
|
340 |
-
"execution_count": 159,
|
341 |
-
"metadata": {},
|
342 |
-
"outputs": [],
|
343 |
-
"source": [
|
344 |
-
"## return define as the total return since the portfolio created\n",
|
345 |
-
"def calcualte_return(stock_df):\n",
|
346 |
-
" stock_df['return'] = stock_df['close'] / stock_df.groupby(['ticker'])['close'].transform('first') - 1"
|
347 |
-
]
|
348 |
-
},
|
349 |
-
{
|
350 |
-
"cell_type": "code",
|
351 |
-
"execution_count": 160,
|
352 |
-
"metadata": {},
|
353 |
-
"outputs": [],
|
354 |
-
"source": [
|
355 |
-
"calcualte_return(portfolio_df)\n",
|
356 |
-
"calcualte_return(benchmark_df)"
|
357 |
-
]
|
358 |
-
},
|
359 |
-
{
|
360 |
-
"cell_type": "code",
|
361 |
-
"execution_count": 161,
|
362 |
-
"metadata": {},
|
363 |
-
"outputs": [],
|
364 |
-
"source": [
|
365 |
-
"def calculate_weighted_sector_return(stock_df):\n",
|
366 |
-
" stock_df['weighted_sectore_return'] = stock_df['return'] * stock_df['initial_sector_weight']"
|
367 |
-
]
|
368 |
-
},
|
369 |
-
{
|
370 |
-
"cell_type": "code",
|
371 |
-
"execution_count": 162,
|
372 |
-
"metadata": {},
|
373 |
-
"outputs": [],
|
374 |
-
"source": [
|
375 |
-
"calculate_weighted_sector_return(portfolio_df)\n",
|
376 |
-
"calculate_weighted_sector_return(benchmark_df)"
|
377 |
-
]
|
378 |
-
},
|
379 |
-
{
|
380 |
-
"cell_type": "code",
|
381 |
-
"execution_count": 163,
|
382 |
-
"metadata": {},
|
383 |
-
"outputs": [],
|
384 |
-
"source": [
|
385 |
-
"## weighted return and sector weighred return \n",
|
386 |
-
"def calculate_weighted_return(stock_df):\n",
|
387 |
-
" stock_df['weighted_return'] = stock_df['return'] * stock_df['initial_weight']"
|
388 |
-
]
|
389 |
-
},
|
390 |
-
{
|
391 |
-
"cell_type": "code",
|
392 |
-
"execution_count": 164,
|
393 |
-
"metadata": {},
|
394 |
-
"outputs": [],
|
395 |
-
"source": [
|
396 |
-
"# step\n",
|
397 |
-
"calculate_weighted_return(portfolio_df)\n",
|
398 |
-
"calculate_weighted_return(benchmark_df)"
|
399 |
-
]
|
400 |
-
},
|
401 |
-
{
|
402 |
-
"cell_type": "code",
|
403 |
-
"execution_count": 165,
|
404 |
-
"metadata": {},
|
405 |
-
"outputs": [],
|
406 |
-
"source": [
|
407 |
-
"def calculate_weighted_sector_return(stock_df):\n",
|
408 |
-
" stock_df['weighted_sector_return'] = stock_df['return'] * stock_df['initial_sector_weight']"
|
409 |
-
]
|
410 |
-
},
|
411 |
-
{
|
412 |
-
"cell_type": "code",
|
413 |
-
"execution_count": 166,
|
414 |
-
"metadata": {},
|
415 |
-
"outputs": [],
|
416 |
-
"source": [
|
417 |
-
"calculate_weighted_sector_return(portfolio_df)\n",
|
418 |
-
"calculate_weighted_sector_return(benchmark_df)"
|
419 |
-
]
|
420 |
-
},
|
421 |
-
{
|
422 |
-
"cell_type": "code",
|
423 |
-
"execution_count": 167,
|
424 |
-
"metadata": {},
|
425 |
-
"outputs": [],
|
426 |
-
"source": [
|
427 |
-
"## calcualte weighted pc\n",
|
428 |
-
"def calculate_weighted_pct(stock_df):\n",
|
429 |
-
" stock_df['weighted_pct'] = stock_df['pct'] * stock_df['previous_weight']\n",
|
430 |
-
"\n"
|
431 |
-
]
|
432 |
-
},
|
433 |
-
{
|
434 |
-
"cell_type": "code",
|
435 |
-
"execution_count": 168,
|
436 |
-
"metadata": {},
|
437 |
-
"outputs": [],
|
438 |
-
"source": [
|
439 |
-
"def calculate_weighted_sector_pct(stock_df):\n",
|
440 |
-
" stock_df['weighted_sector_pct'] = stock_df['pct'] * stock_df['previous_sector_weight']\n",
|
441 |
-
" "
|
442 |
-
]
|
443 |
-
},
|
444 |
-
{
|
445 |
-
"cell_type": "code",
|
446 |
-
"execution_count": 169,
|
447 |
-
"metadata": {},
|
448 |
-
"outputs": [],
|
449 |
-
"source": [
|
450 |
-
"calculate_weighted_sector_pct(portfolio_df)\n",
|
451 |
-
"calculate_weighted_sector_pct(benchmark_df)"
|
452 |
-
]
|
453 |
-
},
|
454 |
-
{
|
455 |
-
"cell_type": "code",
|
456 |
-
"execution_count": 170,
|
457 |
-
"metadata": {},
|
458 |
-
"outputs": [],
|
459 |
-
"source": [
|
460 |
-
"calculate_weighted_pct(portfolio_df)\n",
|
461 |
-
"calculate_weighted_pct(benchmark_df)"
|
462 |
-
]
|
463 |
-
},
|
464 |
-
{
|
465 |
-
"cell_type": "code",
|
466 |
-
"execution_count": 171,
|
467 |
-
"metadata": {},
|
468 |
-
"outputs": [],
|
469 |
-
"source": [
|
470 |
-
"calculate_weighted_sector_return(portfolio_df)\n",
|
471 |
-
"calculate_weighted_sector_return(benchmark_df)"
|
472 |
-
]
|
473 |
-
},
|
474 |
-
{
|
475 |
-
"cell_type": "code",
|
476 |
-
"execution_count": 172,
|
477 |
-
"metadata": {},
|
478 |
-
"outputs": [],
|
479 |
-
"source": [
|
480 |
-
"## aggregate by date\n",
|
481 |
-
"\n",
|
482 |
-
"# pct and weighted_return\n",
|
483 |
-
"# def agg_by_date(stock_df)\n",
|
484 |
-
"def agg_by_date(stock_df):\n",
|
485 |
-
" agg_on_date_df = pd.DataFrame(stock_df.groupby('date')[['weighted_return','weighted_pct']].sum())\n",
|
486 |
-
" agg_on_date_df.rename(columns={'weighted_return': 'return', 'weighted_pct': 'pct'}, inplace=True)\n",
|
487 |
-
" return agg_on_date_df\n",
|
488 |
-
"\n",
|
489 |
-
"\n"
|
490 |
-
]
|
491 |
-
},
|
492 |
-
{
|
493 |
-
"cell_type": "code",
|
494 |
-
"execution_count": 173,
|
495 |
-
"metadata": {},
|
496 |
-
"outputs": [],
|
497 |
-
"source": [
|
498 |
-
"p_total_view = agg_by_date(portfolio_df)\n",
|
499 |
-
"b_total_view = agg_by_date(benchmark_df)"
|
500 |
-
]
|
501 |
-
},
|
502 |
-
{
|
503 |
-
"cell_type": "code",
|
504 |
-
"execution_count": 174,
|
505 |
-
"metadata": {},
|
506 |
-
"outputs": [],
|
507 |
-
"source": [
|
508 |
-
"## aggregate by sector\n",
|
509 |
-
"def agg_by_sector(stock_df):\n",
|
510 |
-
" agg_on_sector_df = pd.DataFrame(stock_df.groupby(['aggregate_sector','date'])[['weighted_sector_return','weighted_sector_pct']].sum())\n",
|
511 |
-
" agg_on_sector_df.rename(columns={'weighted_sector_return': 'return', 'weighted_sector_pct': 'pct'}, inplace=True)\n",
|
512 |
-
" return agg_on_sector_df"
|
513 |
-
]
|
514 |
-
},
|
515 |
-
{
|
516 |
-
"cell_type": "code",
|
517 |
-
"execution_count": 175,
|
518 |
-
"metadata": {},
|
519 |
-
"outputs": [],
|
520 |
-
"source": [
|
521 |
-
"p_sector_view = agg_by_sector(portfolio_df)\n",
|
522 |
-
"b_sector_view = agg_by_sector(benchmark_df)"
|
523 |
-
]
|
524 |
-
},
|
525 |
-
{
|
526 |
-
"cell_type": "code",
|
527 |
-
"execution_count": 200,
|
528 |
-
"metadata": {},
|
529 |
-
"outputs": [],
|
530 |
-
"source": [
|
531 |
-
"def create_risk_table(portfolio_summary, benchmark_summary):\n",
|
532 |
-
" # total risk tracking error \n",
|
533 |
-
" merged_df = pd.merge(portfolio_summary, benchmark_summary, on='date', how='outer', suffixes=('_p', '_b'))\n",
|
534 |
-
" merged_df['risk_p'] = merged_df['return_p'].expanding().std() * math.sqrt(252)\n",
|
535 |
-
" merged_df['risk_b'] = merged_df['return_b'].expanding().std() * math.sqrt(252)\n",
|
536 |
-
" merged_df['active_return'] = merged_df['return_p'] - merged_df['return_b']\n",
|
537 |
-
" merged_df['tracking_error'] = merged_df['active_return'].expanding().std() * math.sqrt(252)\n",
|
538 |
-
" merged_df['date'] = merged_df.index\n",
|
539 |
-
" # drop index\n",
|
540 |
-
" merged_df.reset_index(drop=True, inplace=True)\n",
|
541 |
-
" return merged_df"
|
542 |
-
]
|
543 |
-
},
|
544 |
-
{
|
545 |
-
"cell_type": "code",
|
546 |
-
"execution_count": 201,
|
547 |
-
"metadata": {},
|
548 |
-
"outputs": [],
|
549 |
-
"source": [
|
550 |
-
"portfolio_risk_by_date_df = create_risk_table(p_total_view, b_total_view)"
|
551 |
-
]
|
552 |
-
},
|
553 |
-
{
|
554 |
-
"cell_type": "code",
|
555 |
-
"execution_count": 202,
|
556 |
-
"metadata": {},
|
557 |
-
"outputs": [
|
558 |
-
{
|
559 |
-
"data": {
|
560 |
-
"text/html": [
|
561 |
-
"<div>\n",
|
562 |
-
"<style scoped>\n",
|
563 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
564 |
-
" vertical-align: middle;\n",
|
565 |
-
" }\n",
|
566 |
-
"\n",
|
567 |
-
" .dataframe tbody tr th {\n",
|
568 |
-
" vertical-align: top;\n",
|
569 |
-
" }\n",
|
570 |
-
"\n",
|
571 |
-
" .dataframe thead th {\n",
|
572 |
-
" text-align: right;\n",
|
573 |
-
" }\n",
|
574 |
-
"</style>\n",
|
575 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
576 |
-
" <thead>\n",
|
577 |
-
" <tr style=\"text-align: right;\">\n",
|
578 |
-
" <th></th>\n",
|
579 |
-
" <th>return_p</th>\n",
|
580 |
-
" <th>pct_p</th>\n",
|
581 |
-
" <th>return_b</th>\n",
|
582 |
-
" <th>pct_b</th>\n",
|
583 |
-
" <th>risk_p</th>\n",
|
584 |
-
" <th>risk_b</th>\n",
|
585 |
-
" <th>active_return</th>\n",
|
586 |
-
" <th>tracking_error</th>\n",
|
587 |
-
" <th>date</th>\n",
|
588 |
-
" </tr>\n",
|
589 |
-
" </thead>\n",
|
590 |
-
" <tbody>\n",
|
591 |
-
" <tr>\n",
|
592 |
-
" <th>0</th>\n",
|
593 |
-
" <td>0.000000</td>\n",
|
594 |
-
" <td>0.000000</td>\n",
|
595 |
-
" <td>0.000000</td>\n",
|
596 |
-
" <td>0.000000</td>\n",
|
597 |
-
" <td>NaN</td>\n",
|
598 |
-
" <td>NaN</td>\n",
|
599 |
-
" <td>0.000000</td>\n",
|
600 |
-
" <td>NaN</td>\n",
|
601 |
-
" <td>2021-01-05</td>\n",
|
602 |
-
" </tr>\n",
|
603 |
-
" <tr>\n",
|
604 |
-
" <th>1</th>\n",
|
605 |
-
" <td>0.012146</td>\n",
|
606 |
-
" <td>0.012146</td>\n",
|
607 |
-
" <td>-0.001934</td>\n",
|
608 |
-
" <td>-0.001934</td>\n",
|
609 |
-
" <td>0.136341</td>\n",
|
610 |
-
" <td>0.021705</td>\n",
|
611 |
-
" <td>0.014080</td>\n",
|
612 |
-
" <td>0.158046</td>\n",
|
613 |
-
" <td>2021-01-06</td>\n",
|
614 |
-
" </tr>\n",
|
615 |
-
" <tr>\n",
|
616 |
-
" <th>2</th>\n",
|
617 |
-
" <td>0.086830</td>\n",
|
618 |
-
" <td>0.074233</td>\n",
|
619 |
-
" <td>-0.000811</td>\n",
|
620 |
-
" <td>0.001125</td>\n",
|
621 |
-
" <td>0.746402</td>\n",
|
622 |
-
" <td>0.015414</td>\n",
|
623 |
-
" <td>0.087641</td>\n",
|
624 |
-
" <td>0.747127</td>\n",
|
625 |
-
" <td>2021-01-07</td>\n",
|
626 |
-
" </tr>\n",
|
627 |
-
" <tr>\n",
|
628 |
-
" <th>3</th>\n",
|
629 |
-
" <td>0.089435</td>\n",
|
630 |
-
" <td>0.002496</td>\n",
|
631 |
-
" <td>0.002535</td>\n",
|
632 |
-
" <td>0.003349</td>\n",
|
633 |
-
" <td>0.756382</td>\n",
|
634 |
-
" <td>0.030137</td>\n",
|
635 |
-
" <td>0.086900</td>\n",
|
636 |
-
" <td>0.740979</td>\n",
|
637 |
-
" <td>2021-01-08</td>\n",
|
638 |
-
" </tr>\n",
|
639 |
-
" <tr>\n",
|
640 |
-
" <th>4</th>\n",
|
641 |
-
" <td>0.148063</td>\n",
|
642 |
-
" <td>0.029363</td>\n",
|
643 |
-
" <td>-0.013015</td>\n",
|
644 |
-
" <td>-0.015511</td>\n",
|
645 |
-
" <td>0.970984</td>\n",
|
646 |
-
" <td>0.095654</td>\n",
|
647 |
-
" <td>0.161078</td>\n",
|
648 |
-
" <td>1.032423</td>\n",
|
649 |
-
" <td>2021-01-11</td>\n",
|
650 |
-
" </tr>\n",
|
651 |
-
" <tr>\n",
|
652 |
-
" <th>...</th>\n",
|
653 |
-
" <td>...</td>\n",
|
654 |
-
" <td>...</td>\n",
|
655 |
-
" <td>...</td>\n",
|
656 |
-
" <td>...</td>\n",
|
657 |
-
" <td>...</td>\n",
|
658 |
-
" <td>...</td>\n",
|
659 |
-
" <td>...</td>\n",
|
660 |
-
" <td>...</td>\n",
|
661 |
-
" <td>...</td>\n",
|
662 |
-
" </tr>\n",
|
663 |
-
" <tr>\n",
|
664 |
-
" <th>242</th>\n",
|
665 |
-
" <td>0.028005</td>\n",
|
666 |
-
" <td>-0.071081</td>\n",
|
667 |
-
" <td>0.086827</td>\n",
|
668 |
-
" <td>0.000156</td>\n",
|
669 |
-
" <td>2.097631</td>\n",
|
670 |
-
" <td>0.886298</td>\n",
|
671 |
-
" <td>-0.058822</td>\n",
|
672 |
-
" <td>1.856213</td>\n",
|
673 |
-
" <td>2022-01-04</td>\n",
|
674 |
-
" </tr>\n",
|
675 |
-
" <tr>\n",
|
676 |
-
" <th>243</th>\n",
|
677 |
-
" <td>-0.033053</td>\n",
|
678 |
-
" <td>-0.059582</td>\n",
|
679 |
-
" <td>0.067931</td>\n",
|
680 |
-
" <td>-0.017386</td>\n",
|
681 |
-
" <td>2.099052</td>\n",
|
682 |
-
" <td>0.884891</td>\n",
|
683 |
-
" <td>-0.100984</td>\n",
|
684 |
-
" <td>1.861347</td>\n",
|
685 |
-
" <td>2022-01-05</td>\n",
|
686 |
-
" </tr>\n",
|
687 |
-
" <tr>\n",
|
688 |
-
" <th>244</th>\n",
|
689 |
-
" <td>-0.042238</td>\n",
|
690 |
-
" <td>-0.008112</td>\n",
|
691 |
-
" <td>0.069522</td>\n",
|
692 |
-
" <td>0.001490</td>\n",
|
693 |
-
" <td>2.101118</td>\n",
|
694 |
-
" <td>0.883542</td>\n",
|
695 |
-
" <td>-0.111761</td>\n",
|
696 |
-
" <td>1.867445</td>\n",
|
697 |
-
" <td>2022-01-06</td>\n",
|
698 |
-
" </tr>\n",
|
699 |
-
" <tr>\n",
|
700 |
-
" <th>245</th>\n",
|
701 |
-
" <td>-0.073118</td>\n",
|
702 |
-
" <td>-0.031015</td>\n",
|
703 |
-
" <td>0.062056</td>\n",
|
704 |
-
" <td>-0.006981</td>\n",
|
705 |
-
" <td>2.105760</td>\n",
|
706 |
-
" <td>0.881986</td>\n",
|
707 |
-
" <td>-0.135174</td>\n",
|
708 |
-
" <td>1.875959</td>\n",
|
709 |
-
" <td>2022-01-07</td>\n",
|
710 |
-
" </tr>\n",
|
711 |
-
" <tr>\n",
|
712 |
-
" <th>246</th>\n",
|
713 |
-
" <td>-0.029944</td>\n",
|
714 |
-
" <td>0.044300</td>\n",
|
715 |
-
" <td>0.064588</td>\n",
|
716 |
-
" <td>0.002384</td>\n",
|
717 |
-
" <td>2.106749</td>\n",
|
718 |
-
" <td>0.880502</td>\n",
|
719 |
-
" <td>-0.094532</td>\n",
|
720 |
-
" <td>1.880060</td>\n",
|
721 |
-
" <td>2022-01-10</td>\n",
|
722 |
-
" </tr>\n",
|
723 |
-
" </tbody>\n",
|
724 |
-
"</table>\n",
|
725 |
-
"<p>247 rows × 9 columns</p>\n",
|
726 |
-
"</div>"
|
727 |
-
],
|
728 |
-
"text/plain": [
|
729 |
-
" return_p pct_p return_b pct_b risk_p risk_b \\\n",
|
730 |
-
"0 0.000000 0.000000 0.000000 0.000000 NaN NaN \n",
|
731 |
-
"1 0.012146 0.012146 -0.001934 -0.001934 0.136341 0.021705 \n",
|
732 |
-
"2 0.086830 0.074233 -0.000811 0.001125 0.746402 0.015414 \n",
|
733 |
-
"3 0.089435 0.002496 0.002535 0.003349 0.756382 0.030137 \n",
|
734 |
-
"4 0.148063 0.029363 -0.013015 -0.015511 0.970984 0.095654 \n",
|
735 |
-
".. ... ... ... ... ... ... \n",
|
736 |
-
"242 0.028005 -0.071081 0.086827 0.000156 2.097631 0.886298 \n",
|
737 |
-
"243 -0.033053 -0.059582 0.067931 -0.017386 2.099052 0.884891 \n",
|
738 |
-
"244 -0.042238 -0.008112 0.069522 0.001490 2.101118 0.883542 \n",
|
739 |
-
"245 -0.073118 -0.031015 0.062056 -0.006981 2.105760 0.881986 \n",
|
740 |
-
"246 -0.029944 0.044300 0.064588 0.002384 2.106749 0.880502 \n",
|
741 |
-
"\n",
|
742 |
-
" active_return tracking_error date \n",
|
743 |
-
"0 0.000000 NaN 2021-01-05 \n",
|
744 |
-
"1 0.014080 0.158046 2021-01-06 \n",
|
745 |
-
"2 0.087641 0.747127 2021-01-07 \n",
|
746 |
-
"3 0.086900 0.740979 2021-01-08 \n",
|
747 |
-
"4 0.161078 1.032423 2021-01-11 \n",
|
748 |
-
".. ... ... ... \n",
|
749 |
-
"242 -0.058822 1.856213 2022-01-04 \n",
|
750 |
-
"243 -0.100984 1.861347 2022-01-05 \n",
|
751 |
-
"244 -0.111761 1.867445 2022-01-06 \n",
|
752 |
-
"245 -0.135174 1.875959 2022-01-07 \n",
|
753 |
-
"246 -0.094532 1.880060 2022-01-10 \n",
|
754 |
-
"\n",
|
755 |
-
"[247 rows x 9 columns]"
|
756 |
-
]
|
757 |
-
},
|
758 |
-
"execution_count": 202,
|
759 |
-
"metadata": {},
|
760 |
-
"output_type": "execute_result"
|
761 |
-
}
|
762 |
-
],
|
763 |
-
"source": [
|
764 |
-
"# add mkt cap\n",
|
765 |
-
"portfolio_risk_by_date_df"
|
766 |
-
]
|
767 |
-
},
|
768 |
-
{
|
769 |
-
"cell_type": "code",
|
770 |
-
"execution_count": 217,
|
771 |
-
"metadata": {},
|
772 |
-
"outputs": [
|
773 |
-
{
|
774 |
-
"data": {
|
775 |
-
"text/plain": [
|
776 |
-
"date\n",
|
777 |
-
"2021-01-05 600\n",
|
778 |
-
"2021-01-10 1550\n",
|
779 |
-
"Name: weight, dtype: int64"
|
780 |
-
]
|
781 |
-
},
|
782 |
-
"execution_count": 217,
|
783 |
-
"metadata": {},
|
784 |
-
"output_type": "execute_result"
|
785 |
-
}
|
786 |
-
],
|
787 |
-
"source": [
|
788 |
-
"profile_df.groupby('date')['weight'].sum()\n",
|
789 |
-
"\n",
|
790 |
-
"# for i in range(1, len(portfolio_risk_by_date_df)):\n",
|
791 |
-
"# cur_mkt = portfolio_risk_by_date_df.loc[i, 'mkt_cap']\n",
|
792 |
-
"# if pd.isna(cur_mkt):\n",
|
793 |
-
"# portfolio_risk_by_date_df.loc[i, 'mkt_cap'] = portfolio_risk_by_date_df.loc[i-1, 'mkt_cap'] * (1 + portfolio_risk_by_date_df.loc[i, 'pct_p'])\n",
|
794 |
-
" "
|
795 |
-
]
|
796 |
-
},
|
797 |
-
{
|
798 |
-
"cell_type": "code",
|
799 |
-
"execution_count": 216,
|
800 |
-
"metadata": {},
|
801 |
-
"outputs": [
|
802 |
-
{
|
803 |
-
"data": {
|
804 |
-
"text/html": [
|
805 |
-
"<div>\n",
|
806 |
-
"<style scoped>\n",
|
807 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
808 |
-
" vertical-align: middle;\n",
|
809 |
-
" }\n",
|
810 |
-
"\n",
|
811 |
-
" .dataframe tbody tr th {\n",
|
812 |
-
" vertical-align: top;\n",
|
813 |
-
" }\n",
|
814 |
-
"\n",
|
815 |
-
" .dataframe thead th {\n",
|
816 |
-
" text-align: right;\n",
|
817 |
-
" }\n",
|
818 |
-
"</style>\n",
|
819 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
820 |
-
" <thead>\n",
|
821 |
-
" <tr style=\"text-align: right;\">\n",
|
822 |
-
" <th></th>\n",
|
823 |
-
" <th>return_p</th>\n",
|
824 |
-
" <th>pct_p</th>\n",
|
825 |
-
" <th>return_b</th>\n",
|
826 |
-
" <th>pct_b</th>\n",
|
827 |
-
" <th>risk_p</th>\n",
|
828 |
-
" <th>risk_b</th>\n",
|
829 |
-
" <th>active_return</th>\n",
|
830 |
-
" <th>tracking_error</th>\n",
|
831 |
-
" <th>date</th>\n",
|
832 |
-
" <th>mkt_cap</th>\n",
|
833 |
-
" </tr>\n",
|
834 |
-
" </thead>\n",
|
835 |
-
" <tbody>\n",
|
836 |
-
" <tr>\n",
|
837 |
-
" <th>0</th>\n",
|
838 |
-
" <td>0.0</td>\n",
|
839 |
-
" <td>0.0</td>\n",
|
840 |
-
" <td>0.0</td>\n",
|
841 |
-
" <td>0.0</td>\n",
|
842 |
-
" <td>NaN</td>\n",
|
843 |
-
" <td>NaN</td>\n",
|
844 |
-
" <td>0.0</td>\n",
|
845 |
-
" <td>NaN</td>\n",
|
846 |
-
" <td>2021-01-05</td>\n",
|
847 |
-
" <td>600.0</td>\n",
|
848 |
-
" </tr>\n",
|
849 |
-
" </tbody>\n",
|
850 |
-
"</table>\n",
|
851 |
-
"</div>"
|
852 |
-
],
|
853 |
-
"text/plain": [
|
854 |
-
" return_p pct_p return_b pct_b risk_p risk_b active_return \\\n",
|
855 |
-
"0 0.0 0.0 0.0 0.0 NaN NaN 0.0 \n",
|
856 |
-
"\n",
|
857 |
-
" tracking_error date mkt_cap \n",
|
858 |
-
"0 NaN 2021-01-05 600.0 "
|
859 |
-
]
|
860 |
-
},
|
861 |
-
"execution_count": 216,
|
862 |
-
"metadata": {},
|
863 |
-
"output_type": "execute_result"
|
864 |
-
}
|
865 |
-
],
|
866 |
-
"source": [
|
867 |
-
"# display row where mkt_cap is not nana\n",
|
868 |
-
"portfolio_risk_by_date_df[portfolio_risk_by_date_df['mkt_cap'].notna()]"
|
869 |
-
]
|
870 |
-
},
|
871 |
-
{
|
872 |
-
"cell_type": "code",
|
873 |
-
"execution_count": null,
|
874 |
-
"metadata": {},
|
875 |
-
"outputs": [
|
876 |
-
{
|
877 |
-
"name": "stderr",
|
878 |
-
"output_type": "stream",
|
879 |
-
"text": [
|
880 |
-
"/var/folders/v5/2108rh5964q9j741wg_s8r1w0000gn/T/ipykernel_23255/2871737262.py:10: SettingWithCopyWarning: \n",
|
881 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
882 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
883 |
-
"\n",
|
884 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
885 |
-
" pct['weighted_pct'] = pct['pct'] * pct['norm_weight']\n"
|
886 |
-
]
|
887 |
-
},
|
888 |
-
{
|
889 |
-
"data": {
|
890 |
-
"text/html": [
|
891 |
-
"<div>\n",
|
892 |
-
"<style scoped>\n",
|
893 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
894 |
-
" vertical-align: middle;\n",
|
895 |
-
" }\n",
|
896 |
-
"\n",
|
897 |
-
" .dataframe tbody tr th {\n",
|
898 |
-
" vertical-align: top;\n",
|
899 |
-
" }\n",
|
900 |
-
"\n",
|
901 |
-
" .dataframe thead th {\n",
|
902 |
-
" text-align: right;\n",
|
903 |
-
" }\n",
|
904 |
-
"</style>\n",
|
905 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
906 |
-
" <thead>\n",
|
907 |
-
" <tr style=\"text-align: right;\">\n",
|
908 |
-
" <th></th>\n",
|
909 |
-
" <th>date</th>\n",
|
910 |
-
" <th>return</th>\n",
|
911 |
-
" <th>pct</th>\n",
|
912 |
-
" </tr>\n",
|
913 |
-
" </thead>\n",
|
914 |
-
" <tbody>\n",
|
915 |
-
" <tr>\n",
|
916 |
-
" <th>0</th>\n",
|
917 |
-
" <td>2021-01-05</td>\n",
|
918 |
-
" <td>0.000000</td>\n",
|
919 |
-
" <td>0.000000</td>\n",
|
920 |
-
" </tr>\n",
|
921 |
-
" <tr>\n",
|
922 |
-
" <th>1</th>\n",
|
923 |
-
" <td>2021-01-06</td>\n",
|
924 |
-
" <td>0.007011</td>\n",
|
925 |
-
" <td>0.036439</td>\n",
|
926 |
-
" </tr>\n",
|
927 |
-
" <tr>\n",
|
928 |
-
" <th>2</th>\n",
|
929 |
-
" <td>2021-01-07</td>\n",
|
930 |
-
" <td>0.047531</td>\n",
|
931 |
-
" <td>0.218707</td>\n",
|
932 |
-
" </tr>\n",
|
933 |
-
" <tr>\n",
|
934 |
-
" <th>3</th>\n",
|
935 |
-
" <td>2021-01-08</td>\n",
|
936 |
-
" <td>0.047111</td>\n",
|
937 |
-
" <td>0.013639</td>\n",
|
938 |
-
" </tr>\n",
|
939 |
-
" <tr>\n",
|
940 |
-
" <th>4</th>\n",
|
941 |
-
" <td>2021-01-11</td>\n",
|
942 |
-
" <td>0.052768</td>\n",
|
943 |
-
" <td>0.014559</td>\n",
|
944 |
-
" </tr>\n",
|
945 |
-
" <tr>\n",
|
946 |
-
" <th>...</th>\n",
|
947 |
-
" <td>...</td>\n",
|
948 |
-
" <td>...</td>\n",
|
949 |
-
" <td>...</td>\n",
|
950 |
-
" </tr>\n",
|
951 |
-
" <tr>\n",
|
952 |
-
" <th>242</th>\n",
|
953 |
-
" <td>2022-01-04</td>\n",
|
954 |
-
" <td>0.363845</td>\n",
|
955 |
-
" <td>-0.199827</td>\n",
|
956 |
-
" </tr>\n",
|
957 |
-
" <tr>\n",
|
958 |
-
" <th>243</th>\n",
|
959 |
-
" <td>2022-01-05</td>\n",
|
960 |
-
" <td>0.306697</td>\n",
|
961 |
-
" <td>-0.193598</td>\n",
|
962 |
-
" </tr>\n",
|
963 |
-
" <tr>\n",
|
964 |
-
" <th>244</th>\n",
|
965 |
-
" <td>2022-01-06</td>\n",
|
966 |
-
" <td>0.331291</td>\n",
|
967 |
-
" <td>0.023418</td>\n",
|
968 |
-
" </tr>\n",
|
969 |
-
" <tr>\n",
|
970 |
-
" <th>245</th>\n",
|
971 |
-
" <td>2022-01-07</td>\n",
|
972 |
-
" <td>0.313726</td>\n",
|
973 |
-
" <td>-0.080728</td>\n",
|
974 |
-
" </tr>\n",
|
975 |
-
" <tr>\n",
|
976 |
-
" <th>246</th>\n",
|
977 |
-
" <td>2022-01-10</td>\n",
|
978 |
-
" <td>0.313262</td>\n",
|
979 |
-
" <td>0.110254</td>\n",
|
980 |
-
" </tr>\n",
|
981 |
-
" </tbody>\n",
|
982 |
-
"</table>\n",
|
983 |
-
"<p>247 rows × 3 columns</p>\n",
|
984 |
-
"</div>"
|
985 |
-
],
|
986 |
-
"text/plain": [
|
987 |
-
" date return pct\n",
|
988 |
-
"0 2021-01-05 0.000000 0.000000\n",
|
989 |
-
"1 2021-01-06 0.007011 0.036439\n",
|
990 |
-
"2 2021-01-07 0.047531 0.218707\n",
|
991 |
-
"3 2021-01-08 0.047111 0.013639\n",
|
992 |
-
"4 2021-01-11 0.052768 0.014559\n",
|
993 |
-
".. ... ... ...\n",
|
994 |
-
"242 2022-01-04 0.363845 -0.199827\n",
|
995 |
-
"243 2022-01-05 0.306697 -0.193598\n",
|
996 |
-
"244 2022-01-06 0.331291 0.023418\n",
|
997 |
-
"245 2022-01-07 0.313726 -0.080728\n",
|
998 |
-
"246 2022-01-10 0.313262 0.110254\n",
|
999 |
-
"\n",
|
1000 |
-
"[247 rows x 3 columns]"
|
1001 |
-
]
|
1002 |
-
},
|
1003 |
-
"execution_count": 191,
|
1004 |
-
"metadata": {},
|
1005 |
-
"output_type": "execute_result"
|
1006 |
-
}
|
1007 |
-
],
|
1008 |
-
"source": [
|
1009 |
-
"## aggregate by date\n",
|
1010 |
-
"# step 7 aggregate (get portfolio return and pct(change of daily return))by date\n",
|
1011 |
-
"def create_agg_by_date(stock_df):\n",
|
1012 |
-
" # sum up weighted return to get return \n",
|
1013 |
-
" agg_return = stock_df.groupby(['date'])['weighted_return'].sum().reset_index()\n",
|
1014 |
-
" agg_return.rename(columns={'weighted_return':'return'}, inplace=True)\n",
|
1015 |
-
"\n",
|
1016 |
-
" # sum up weighted pct to get pct\n",
|
1017 |
-
" pct = stock_df[['date','pct','norm_weight','ticker']]\n",
|
1018 |
-
" pct['weighted_pct'] = pct['pct'] * pct['norm_weight']\n",
|
1019 |
-
" agg_pct = pct.groupby(['date'])['pct'].sum().reset_index()\n",
|
1020 |
-
"\n",
|
1021 |
-
" agg_df = pd.merge(agg_return, agg_pct, on='date', how='outer')\n",
|
1022 |
-
" return agg_df\n",
|
1023 |
-
"\n",
|
1024 |
-
"\n",
|
1025 |
-
"\n",
|
1026 |
-
"p_perform_result = create_agg_by_date(p_stock_df)\n",
|
1027 |
-
"p_perform_result"
|
1028 |
-
]
|
1029 |
-
},
|
1030 |
-
{
|
1031 |
-
"cell_type": "code",
|
1032 |
-
"execution_count": null,
|
1033 |
-
"metadata": {},
|
1034 |
-
"outputs": [
|
1035 |
-
{
|
1036 |
-
"data": {
|
1037 |
-
"text/html": [
|
1038 |
-
"<div>\n",
|
1039 |
-
"<style scoped>\n",
|
1040 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
1041 |
-
" vertical-align: middle;\n",
|
1042 |
-
" }\n",
|
1043 |
-
"\n",
|
1044 |
-
" .dataframe tbody tr th {\n",
|
1045 |
-
" vertical-align: top;\n",
|
1046 |
-
" }\n",
|
1047 |
-
"\n",
|
1048 |
-
" .dataframe thead th {\n",
|
1049 |
-
" text-align: right;\n",
|
1050 |
-
" }\n",
|
1051 |
-
"</style>\n",
|
1052 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
1053 |
-
" <thead>\n",
|
1054 |
-
" <tr style=\"text-align: right;\">\n",
|
1055 |
-
" <th></th>\n",
|
1056 |
-
" <th>ticker</th>\n",
|
1057 |
-
" <th>date</th>\n",
|
1058 |
-
" <th>open</th>\n",
|
1059 |
-
" <th>close</th>\n",
|
1060 |
-
" <th>high</th>\n",
|
1061 |
-
" <th>low</th>\n",
|
1062 |
-
" <th>volume</th>\n",
|
1063 |
-
" <th>money</th>\n",
|
1064 |
-
" <th>pct</th>\n",
|
1065 |
-
" <th>weight</th>\n",
|
1066 |
-
" <th>return</th>\n",
|
1067 |
-
" <th>norm_weight</th>\n",
|
1068 |
-
" <th>weighted_return</th>\n",
|
1069 |
-
" <th>aggregate_sector</th>\n",
|
1070 |
-
" <th>display_name</th>\n",
|
1071 |
-
" </tr>\n",
|
1072 |
-
" </thead>\n",
|
1073 |
-
" <tbody>\n",
|
1074 |
-
" <tr>\n",
|
1075 |
-
" <th>1452</th>\n",
|
1076 |
-
" <td>603882.XSHG</td>\n",
|
1077 |
-
" <td>2022-01-04</td>\n",
|
1078 |
-
" <td>106.89</td>\n",
|
1079 |
-
" <td>98.84</td>\n",
|
1080 |
-
" <td>106.89</td>\n",
|
1081 |
-
" <td>98.67</td>\n",
|
1082 |
-
" <td>5140406.0</td>\n",
|
1083 |
-
" <td>5.181929e+08</td>\n",
|
1084 |
-
" <td>-0.076262</td>\n",
|
1085 |
-
" <td>79.300385</td>\n",
|
1086 |
-
" <td>-0.206996</td>\n",
|
1087 |
-
" <td>0.107586</td>\n",
|
1088 |
-
" <td>-0.022270</td>\n",
|
1089 |
-
" <td>医药卫生</td>\n",
|
1090 |
-
" <td>金域医学</td>\n",
|
1091 |
-
" </tr>\n",
|
1092 |
-
" <tr>\n",
|
1093 |
-
" <th>1453</th>\n",
|
1094 |
-
" <td>002709.XSHE</td>\n",
|
1095 |
-
" <td>2022-01-04</td>\n",
|
1096 |
-
" <td>57.64</td>\n",
|
1097 |
-
" <td>54.64</td>\n",
|
1098 |
-
" <td>57.87</td>\n",
|
1099 |
-
" <td>54.29</td>\n",
|
1100 |
-
" <td>42150916.0</td>\n",
|
1101 |
-
" <td>2.333429e+09</td>\n",
|
1102 |
-
" <td>-0.028277</td>\n",
|
1103 |
-
" <td>161.227501</td>\n",
|
1104 |
-
" <td>0.612275</td>\n",
|
1105 |
-
" <td>0.218735</td>\n",
|
1106 |
-
" <td>0.133926</td>\n",
|
1107 |
-
" <td>工业</td>\n",
|
1108 |
-
" <td>天赐材料</td>\n",
|
1109 |
-
" </tr>\n",
|
1110 |
-
" <tr>\n",
|
1111 |
-
" <th>1454</th>\n",
|
1112 |
-
" <td>600409.XSHG</td>\n",
|
1113 |
-
" <td>2022-01-04</td>\n",
|
1114 |
-
" <td>8.16</td>\n",
|
1115 |
-
" <td>8.21</td>\n",
|
1116 |
-
" <td>8.25</td>\n",
|
1117 |
-
" <td>8.15</td>\n",
|
1118 |
-
" <td>27288613.0</td>\n",
|
1119 |
-
" <td>2.237925e+08</td>\n",
|
1120 |
-
" <td>0.007362</td>\n",
|
1121 |
-
" <td>85.788924</td>\n",
|
1122 |
-
" <td>-0.142111</td>\n",
|
1123 |
-
" <td>0.116389</td>\n",
|
1124 |
-
" <td>-0.016540</td>\n",
|
1125 |
-
" <td>原料与能源</td>\n",
|
1126 |
-
" <td>三友化工</td>\n",
|
1127 |
-
" </tr>\n",
|
1128 |
-
" <tr>\n",
|
1129 |
-
" <th>1455</th>\n",
|
1130 |
-
" <td>002920.XSHE</td>\n",
|
1131 |
-
" <td>2022-01-04</td>\n",
|
1132 |
-
" <td>139.71</td>\n",
|
1133 |
-
" <td>131.69</td>\n",
|
1134 |
-
" <td>140.91</td>\n",
|
1135 |
-
" <td>131.45</td>\n",
|
1136 |
-
" <td>5410083.0</td>\n",
|
1137 |
-
" <td>7.233361e+08</td>\n",
|
1138 |
-
" <td>-0.060833</td>\n",
|
1139 |
-
" <td>150.934097</td>\n",
|
1140 |
-
" <td>0.509341</td>\n",
|
1141 |
-
" <td>0.204770</td>\n",
|
1142 |
-
" <td>0.104298</td>\n",
|
1143 |
-
" <td>信息与通信</td>\n",
|
1144 |
-
" <td>德赛西威</td>\n",
|
1145 |
-
" </tr>\n",
|
1146 |
-
" <tr>\n",
|
1147 |
-
" <th>1456</th>\n",
|
1148 |
-
" <td>300274.XSHE</td>\n",
|
1149 |
-
" <td>2022-01-04</td>\n",
|
1150 |
-
" <td>146.52</td>\n",
|
1151 |
-
" <td>134.96</td>\n",
|
1152 |
-
" <td>148.46</td>\n",
|
1153 |
-
" <td>134.61</td>\n",
|
1154 |
-
" <td>24205007.0</td>\n",
|
1155 |
-
" <td>3.333125e+09</td>\n",
|
1156 |
-
" <td>-0.071291</td>\n",
|
1157 |
-
" <td>176.533682</td>\n",
|
1158 |
-
" <td>0.765337</td>\n",
|
1159 |
-
" <td>0.239501</td>\n",
|
1160 |
-
" <td>0.183299</td>\n",
|
1161 |
-
" <td>工业</td>\n",
|
1162 |
-
" <td>阳光电源</td>\n",
|
1163 |
-
" </tr>\n",
|
1164 |
-
" <tr>\n",
|
1165 |
-
" <th>1457</th>\n",
|
1166 |
-
" <td>600415.XSHG</td>\n",
|
1167 |
-
" <td>2022-01-04</td>\n",
|
1168 |
-
" <td>4.80</td>\n",
|
1169 |
-
" <td>4.89</td>\n",
|
1170 |
-
" <td>4.90</td>\n",
|
1171 |
-
" <td>4.78</td>\n",
|
1172 |
-
" <td>58291943.0</td>\n",
|
1173 |
-
" <td>2.832956e+08</td>\n",
|
1174 |
-
" <td>0.029474</td>\n",
|
1175 |
-
" <td>83.304940</td>\n",
|
1176 |
-
" <td>-0.166951</td>\n",
|
1177 |
-
" <td>0.113019</td>\n",
|
1178 |
-
" <td>-0.018869</td>\n",
|
1179 |
-
" <td>消费</td>\n",
|
1180 |
-
" <td>小商品城</td>\n",
|
1181 |
-
" </tr>\n",
|
1182 |
-
" </tbody>\n",
|
1183 |
-
"</table>\n",
|
1184 |
-
"</div>"
|
1185 |
-
],
|
1186 |
-
"text/plain": [
|
1187 |
-
" ticker date open close high low volume \\\n",
|
1188 |
-
"1452 603882.XSHG 2022-01-04 106.89 98.84 106.89 98.67 5140406.0 \n",
|
1189 |
-
"1453 002709.XSHE 2022-01-04 57.64 54.64 57.87 54.29 42150916.0 \n",
|
1190 |
-
"1454 600409.XSHG 2022-01-04 8.16 8.21 8.25 8.15 27288613.0 \n",
|
1191 |
-
"1455 002920.XSHE 2022-01-04 139.71 131.69 140.91 131.45 5410083.0 \n",
|
1192 |
-
"1456 300274.XSHE 2022-01-04 146.52 134.96 148.46 134.61 24205007.0 \n",
|
1193 |
-
"1457 600415.XSHG 2022-01-04 4.80 4.89 4.90 4.78 58291943.0 \n",
|
1194 |
-
"\n",
|
1195 |
-
" money pct weight return norm_weight \\\n",
|
1196 |
-
"1452 5.181929e+08 -0.076262 79.300385 -0.206996 0.107586 \n",
|
1197 |
-
"1453 2.333429e+09 -0.028277 161.227501 0.612275 0.218735 \n",
|
1198 |
-
"1454 2.237925e+08 0.007362 85.788924 -0.142111 0.116389 \n",
|
1199 |
-
"1455 7.233361e+08 -0.060833 150.934097 0.509341 0.204770 \n",
|
1200 |
-
"1456 3.333125e+09 -0.071291 176.533682 0.765337 0.239501 \n",
|
1201 |
-
"1457 2.832956e+08 0.029474 83.304940 -0.166951 0.113019 \n",
|
1202 |
-
"\n",
|
1203 |
-
" weighted_return aggregate_sector display_name \n",
|
1204 |
-
"1452 -0.022270 医药卫生 金域医学 \n",
|
1205 |
-
"1453 0.133926 工业 天赐材料 \n",
|
1206 |
-
"1454 -0.016540 原料与能源 三友化工 \n",
|
1207 |
-
"1455 0.104298 信息与通信 德赛西威 \n",
|
1208 |
-
"1456 0.183299 工业 阳光电源 \n",
|
1209 |
-
"1457 -0.018869 消费 小商品城 "
|
1210 |
-
]
|
1211 |
-
},
|
1212 |
-
"execution_count": 194,
|
1213 |
-
"metadata": {},
|
1214 |
-
"output_type": "execute_result"
|
1215 |
-
}
|
1216 |
-
],
|
1217 |
-
"source": [
|
1218 |
-
"p_stock_df[p_stock_df.date==datetime(2022,1,4)]"
|
1219 |
-
]
|
1220 |
-
},
|
1221 |
-
{
|
1222 |
-
"cell_type": "code",
|
1223 |
-
"execution_count": null,
|
1224 |
-
"metadata": {},
|
1225 |
-
"outputs": [
|
1226 |
-
{
|
1227 |
-
"data": {
|
1228 |
-
"text/html": [
|
1229 |
-
"<div>\n",
|
1230 |
-
"<style scoped>\n",
|
1231 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
1232 |
-
" vertical-align: middle;\n",
|
1233 |
-
" }\n",
|
1234 |
-
"\n",
|
1235 |
-
" .dataframe tbody tr th {\n",
|
1236 |
-
" vertical-align: top;\n",
|
1237 |
-
" }\n",
|
1238 |
-
"\n",
|
1239 |
-
" .dataframe thead th {\n",
|
1240 |
-
" text-align: right;\n",
|
1241 |
-
" }\n",
|
1242 |
-
"</style>\n",
|
1243 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
1244 |
-
" <thead>\n",
|
1245 |
-
" <tr style=\"text-align: right;\">\n",
|
1246 |
-
" <th></th>\n",
|
1247 |
-
" <th>date</th>\n",
|
1248 |
-
" <th>mkt_cap</th>\n",
|
1249 |
-
" </tr>\n",
|
1250 |
-
" </thead>\n",
|
1251 |
-
" <tbody>\n",
|
1252 |
-
" <tr>\n",
|
1253 |
-
" <th>0</th>\n",
|
1254 |
-
" <td>2021-01-05</td>\n",
|
1255 |
-
" <td>600</td>\n",
|
1256 |
-
" </tr>\n",
|
1257 |
-
" <tr>\n",
|
1258 |
-
" <th>1</th>\n",
|
1259 |
-
" <td>2021-01-10</td>\n",
|
1260 |
-
" <td>1550</td>\n",
|
1261 |
-
" </tr>\n",
|
1262 |
-
" </tbody>\n",
|
1263 |
-
"</table>\n",
|
1264 |
-
"</div>"
|
1265 |
-
],
|
1266 |
-
"text/plain": [
|
1267 |
-
" date mkt_cap\n",
|
1268 |
-
"0 2021-01-05 600\n",
|
1269 |
-
"1 2021-01-10 1550"
|
1270 |
-
]
|
1271 |
-
},
|
1272 |
-
"execution_count": 102,
|
1273 |
-
"metadata": {},
|
1274 |
-
"output_type": "execute_result"
|
1275 |
-
}
|
1276 |
-
],
|
1277 |
-
"source": [
|
1278 |
-
"mkt_cap_df = pd.DataFrame(profile_df.groupby(['date'])['weight'].sum()).reset_index()\n",
|
1279 |
-
"mkt_cap_df.rename(columns={'weight':'mkt_cap'}, inplace=True)\n",
|
1280 |
-
"mkt_cap_df"
|
1281 |
-
]
|
1282 |
-
},
|
1283 |
-
{
|
1284 |
-
"cell_type": "code",
|
1285 |
-
"execution_count": null,
|
1286 |
-
"metadata": {},
|
1287 |
-
"outputs": [
|
1288 |
-
{
|
1289 |
-
"data": {
|
1290 |
-
"text/html": [
|
1291 |
-
"<div>\n",
|
1292 |
-
"<style scoped>\n",
|
1293 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
1294 |
-
" vertical-align: middle;\n",
|
1295 |
-
" }\n",
|
1296 |
-
"\n",
|
1297 |
-
" .dataframe tbody tr th {\n",
|
1298 |
-
" vertical-align: top;\n",
|
1299 |
-
" }\n",
|
1300 |
-
"\n",
|
1301 |
-
" .dataframe thead th {\n",
|
1302 |
-
" text-align: right;\n",
|
1303 |
-
" }\n",
|
1304 |
-
"</style>\n",
|
1305 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
1306 |
-
" <thead>\n",
|
1307 |
-
" <tr style=\"text-align: right;\">\n",
|
1308 |
-
" <th></th>\n",
|
1309 |
-
" <th>date</th>\n",
|
1310 |
-
" <th>return</th>\n",
|
1311 |
-
" <th>pct</th>\n",
|
1312 |
-
" <th>mkt_cap</th>\n",
|
1313 |
-
" </tr>\n",
|
1314 |
-
" </thead>\n",
|
1315 |
-
" <tbody>\n",
|
1316 |
-
" <tr>\n",
|
1317 |
-
" <th>0</th>\n",
|
1318 |
-
" <td>2021-01-05</td>\n",
|
1319 |
-
" <td>0.000000</td>\n",
|
1320 |
-
" <td>0.000000</td>\n",
|
1321 |
-
" <td>600.000000</td>\n",
|
1322 |
-
" </tr>\n",
|
1323 |
-
" <tr>\n",
|
1324 |
-
" <th>1</th>\n",
|
1325 |
-
" <td>2021-01-06</td>\n",
|
1326 |
-
" <td>0.007011</td>\n",
|
1327 |
-
" <td>0.036439</td>\n",
|
1328 |
-
" <td>621.863161</td>\n",
|
1329 |
-
" </tr>\n",
|
1330 |
-
" <tr>\n",
|
1331 |
-
" <th>2</th>\n",
|
1332 |
-
" <td>2021-01-07</td>\n",
|
1333 |
-
" <td>0.047531</td>\n",
|
1334 |
-
" <td>0.218707</td>\n",
|
1335 |
-
" <td>757.869005</td>\n",
|
1336 |
-
" </tr>\n",
|
1337 |
-
" <tr>\n",
|
1338 |
-
" <th>3</th>\n",
|
1339 |
-
" <td>2021-01-08</td>\n",
|
1340 |
-
" <td>0.047111</td>\n",
|
1341 |
-
" <td>0.013639</td>\n",
|
1342 |
-
" <td>768.205269</td>\n",
|
1343 |
-
" </tr>\n",
|
1344 |
-
" </tbody>\n",
|
1345 |
-
"</table>\n",
|
1346 |
-
"</div>"
|
1347 |
-
],
|
1348 |
-
"text/plain": [
|
1349 |
-
" date return pct mkt_cap\n",
|
1350 |
-
"0 2021-01-05 0.000000 0.000000 600.000000\n",
|
1351 |
-
"1 2021-01-06 0.007011 0.036439 621.863161\n",
|
1352 |
-
"2 2021-01-07 0.047531 0.218707 757.869005\n",
|
1353 |
-
"3 2021-01-08 0.047111 0.013639 768.205269"
|
1354 |
-
]
|
1355 |
-
},
|
1356 |
-
"execution_count": 103,
|
1357 |
-
"metadata": {},
|
1358 |
-
"output_type": "execute_result"
|
1359 |
-
}
|
1360 |
-
],
|
1361 |
-
"source": [
|
1362 |
-
"# get mkt adjustment (weight is the fund in a stock)\n",
|
1363 |
-
"mkt_adjustment = pd.DataFrame(profile_df.groupby(['date'])['weight'].sum()).reset_index()\n",
|
1364 |
-
"mkt_adjustment.rename(columns={'weight':'mkt_cap'}, inplace=True)\n",
|
1365 |
-
"merge_df = p_perform_result.merge(mkt_adjustment, on='date', how='outer')\n",
|
1366 |
-
"\n",
|
1367 |
-
"\n",
|
1368 |
-
"for i in range(1, len(merge_df)):\n",
|
1369 |
-
" merge_df.loc[i, 'mkt_cap'] = merge_df.loc[i-1, 'mkt_cap'] * (1 + merge_df.loc[i, 'pct'])\n",
|
1370 |
-
"\n",
|
1371 |
-
"# # calculate daily mkt_cap\n",
|
1372 |
-
"# # initial_mkt_cap = merge_df.loc[0, 'mkt_cap']\n",
|
1373 |
-
"# for i in range(1, len(merge_df)):\n",
|
1374 |
-
"# row = merge_df.loc[i]\n",
|
1375 |
-
"# if pd.isna(row['mkt_cap']):\n",
|
1376 |
-
"# merge_df.loc[i, 'mkt_cap'] = merge_df.loc[i-1, 'mkt_cap'] * (1 + merge_df.loc[i, 'pct_portfolio'])\n",
|
1377 |
-
" \n",
|
1378 |
-
"# # step 8 calculate daily mkt cap\n",
|
1379 |
-
"\n",
|
1380 |
-
"merge_df[merge_df.date < datetime(2021,1,10)]"
|
1381 |
-
]
|
1382 |
-
},
|
1383 |
-
{
|
1384 |
-
"cell_type": "code",
|
1385 |
-
"execution_count": null,
|
1386 |
-
"metadata": {},
|
1387 |
-
"outputs": [
|
1388 |
-
{
|
1389 |
-
"data": {
|
1390 |
-
"text/html": [
|
1391 |
-
"<div>\n",
|
1392 |
-
"<style scoped>\n",
|
1393 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
1394 |
-
" vertical-align: middle;\n",
|
1395 |
-
" }\n",
|
1396 |
-
"\n",
|
1397 |
-
" .dataframe tbody tr th {\n",
|
1398 |
-
" vertical-align: top;\n",
|
1399 |
-
" }\n",
|
1400 |
-
"\n",
|
1401 |
-
" .dataframe thead th {\n",
|
1402 |
-
" text-align: right;\n",
|
1403 |
-
" }\n",
|
1404 |
-
"</style>\n",
|
1405 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
1406 |
-
" <thead>\n",
|
1407 |
-
" <tr style=\"text-align: right;\">\n",
|
1408 |
-
" <th></th>\n",
|
1409 |
-
" <th>ticker</th>\n",
|
1410 |
-
" <th>date</th>\n",
|
1411 |
-
" <th>open</th>\n",
|
1412 |
-
" <th>close</th>\n",
|
1413 |
-
" <th>high</th>\n",
|
1414 |
-
" <th>low</th>\n",
|
1415 |
-
" <th>volume</th>\n",
|
1416 |
-
" <th>money</th>\n",
|
1417 |
-
" <th>pct</th>\n",
|
1418 |
-
" <th>weight</th>\n",
|
1419 |
-
" <th>return</th>\n",
|
1420 |
-
" <th>norm_weight</th>\n",
|
1421 |
-
" <th>weighted_return</th>\n",
|
1422 |
-
" <th>aggregate_sector</th>\n",
|
1423 |
-
" <th>display_name</th>\n",
|
1424 |
-
" </tr>\n",
|
1425 |
-
" </thead>\n",
|
1426 |
-
" <tbody>\n",
|
1427 |
-
" <tr>\n",
|
1428 |
-
" <th>0</th>\n",
|
1429 |
-
" <td>002709.XSHE</td>\n",
|
1430 |
-
" <td>2021-01-05</td>\n",
|
1431 |
-
" <td>32.54</td>\n",
|
1432 |
-
" <td>33.89</td>\n",
|
1433 |
-
" <td>34.22</td>\n",
|
1434 |
-
" <td>31.39</td>\n",
|
1435 |
-
" <td>59152352.0</td>\n",
|
1436 |
-
" <td>1.942406e+09</td>\n",
|
1437 |
-
" <td>NaN</td>\n",
|
1438 |
-
" <td>100.000000</td>\n",
|
1439 |
-
" <td>0.000000</td>\n",
|
1440 |
-
" <td>0.166667</td>\n",
|
1441 |
-
" <td>0.000000</td>\n",
|
1442 |
-
" <td>工业</td>\n",
|
1443 |
-
" <td>天赐材料</td>\n",
|
1444 |
-
" </tr>\n",
|
1445 |
-
" <tr>\n",
|
1446 |
-
" <th>1</th>\n",
|
1447 |
-
" <td>600415.XSHG</td>\n",
|
1448 |
-
" <td>2021-01-05</td>\n",
|
1449 |
-
" <td>5.33</td>\n",
|
1450 |
-
" <td>5.87</td>\n",
|
1451 |
-
" <td>5.87</td>\n",
|
1452 |
-
" <td>5.22</td>\n",
|
1453 |
-
" <td>180936477.0</td>\n",
|
1454 |
-
" <td>1.010225e+09</td>\n",
|
1455 |
-
" <td>NaN</td>\n",
|
1456 |
-
" <td>100.000000</td>\n",
|
1457 |
-
" <td>0.000000</td>\n",
|
1458 |
-
" <td>0.166667</td>\n",
|
1459 |
-
" <td>0.000000</td>\n",
|
1460 |
-
" <td>消费</td>\n",
|
1461 |
-
" <td>小商品城</td>\n",
|
1462 |
-
" </tr>\n",
|
1463 |
-
" <tr>\n",
|
1464 |
-
" <th>2</th>\n",
|
1465 |
-
" <td>600409.XSHG</td>\n",
|
1466 |
-
" <td>2021-01-05</td>\n",
|
1467 |
-
" <td>9.23</td>\n",
|
1468 |
-
" <td>9.57</td>\n",
|
1469 |
-
" <td>9.66</td>\n",
|
1470 |
-
" <td>9.08</td>\n",
|
1471 |
-
" <td>82669289.0</td>\n",
|
1472 |
-
" <td>7.803391e+08</td>\n",
|
1473 |
-
" <td>NaN</td>\n",
|
1474 |
-
" <td>100.000000</td>\n",
|
1475 |
-
" <td>0.000000</td>\n",
|
1476 |
-
" <td>0.166667</td>\n",
|
1477 |
-
" <td>0.000000</td>\n",
|
1478 |
-
" <td>原料与能源</td>\n",
|
1479 |
-
" <td>三友化工</td>\n",
|
1480 |
-
" </tr>\n",
|
1481 |
-
" <tr>\n",
|
1482 |
-
" <th>3</th>\n",
|
1483 |
-
" <td>300274.XSHE</td>\n",
|
1484 |
-
" <td>2021-01-05</td>\n",
|
1485 |
-
" <td>76.03</td>\n",
|
1486 |
-
" <td>76.45</td>\n",
|
1487 |
-
" <td>80.20</td>\n",
|
1488 |
-
" <td>75.27</td>\n",
|
1489 |
-
" <td>51384827.0</td>\n",
|
1490 |
-
" <td>3.961995e+09</td>\n",
|
1491 |
-
" <td>NaN</td>\n",
|
1492 |
-
" <td>100.000000</td>\n",
|
1493 |
-
" <td>0.000000</td>\n",
|
1494 |
-
" <td>0.166667</td>\n",
|
1495 |
-
" <td>0.000000</td>\n",
|
1496 |
-
" <td>工业</td>\n",
|
1497 |
-
" <td>阳光电源</td>\n",
|
1498 |
-
" </tr>\n",
|
1499 |
-
" <tr>\n",
|
1500 |
-
" <th>4</th>\n",
|
1501 |
-
" <td>002920.XSHE</td>\n",
|
1502 |
-
" <td>2021-01-05</td>\n",
|
1503 |
-
" <td>85.44</td>\n",
|
1504 |
-
" <td>87.25</td>\n",
|
1505 |
-
" <td>87.95</td>\n",
|
1506 |
-
" <td>84.07</td>\n",
|
1507 |
-
" <td>3852674.0</td>\n",
|
1508 |
-
" <td>3.322598e+08</td>\n",
|
1509 |
-
" <td>NaN</td>\n",
|
1510 |
-
" <td>100.000000</td>\n",
|
1511 |
-
" <td>0.000000</td>\n",
|
1512 |
-
" <td>0.166667</td>\n",
|
1513 |
-
" <td>0.000000</td>\n",
|
1514 |
-
" <td>信息与通信</td>\n",
|
1515 |
-
" <td>德赛西威</td>\n",
|
1516 |
-
" </tr>\n",
|
1517 |
-
" <tr>\n",
|
1518 |
-
" <th>...</th>\n",
|
1519 |
-
" <td>...</td>\n",
|
1520 |
-
" <td>...</td>\n",
|
1521 |
-
" <td>...</td>\n",
|
1522 |
-
" <td>...</td>\n",
|
1523 |
-
" <td>...</td>\n",
|
1524 |
-
" <td>...</td>\n",
|
1525 |
-
" <td>...</td>\n",
|
1526 |
-
" <td>...</td>\n",
|
1527 |
-
" <td>...</td>\n",
|
1528 |
-
" <td>...</td>\n",
|
1529 |
-
" <td>...</td>\n",
|
1530 |
-
" <td>...</td>\n",
|
1531 |
-
" <td>...</td>\n",
|
1532 |
-
" <td>...</td>\n",
|
1533 |
-
" <td>...</td>\n",
|
1534 |
-
" </tr>\n",
|
1535 |
-
" <tr>\n",
|
1536 |
-
" <th>1477</th>\n",
|
1537 |
-
" <td>600409.XSHG</td>\n",
|
1538 |
-
" <td>2022-01-10</td>\n",
|
1539 |
-
" <td>8.24</td>\n",
|
1540 |
-
" <td>8.35</td>\n",
|
1541 |
-
" <td>8.39</td>\n",
|
1542 |
-
" <td>8.21</td>\n",
|
1543 |
-
" <td>32516017.0</td>\n",
|
1544 |
-
" <td>2.699300e+08</td>\n",
|
1545 |
-
" <td>0.015815</td>\n",
|
1546 |
-
" <td>87.251829</td>\n",
|
1547 |
-
" <td>-0.127482</td>\n",
|
1548 |
-
" <td>0.121949</td>\n",
|
1549 |
-
" <td>-0.015546</td>\n",
|
1550 |
-
" <td>原料与能源</td>\n",
|
1551 |
-
" <td>三友化工</td>\n",
|
1552 |
-
" </tr>\n",
|
1553 |
-
" <tr>\n",
|
1554 |
-
" <th>1478</th>\n",
|
1555 |
-
" <td>002920.XSHE</td>\n",
|
1556 |
-
" <td>2022-01-10</td>\n",
|
1557 |
-
" <td>130.36</td>\n",
|
1558 |
-
" <td>138.43</td>\n",
|
1559 |
-
" <td>141.96</td>\n",
|
1560 |
-
" <td>130.11</td>\n",
|
1561 |
-
" <td>5005400.0</td>\n",
|
1562 |
-
" <td>6.901614e+08</td>\n",
|
1563 |
-
" <td>0.046888</td>\n",
|
1564 |
-
" <td>158.659026</td>\n",
|
1565 |
-
" <td>0.586590</td>\n",
|
1566 |
-
" <td>0.221752</td>\n",
|
1567 |
-
" <td>0.130077</td>\n",
|
1568 |
-
" <td>信息与通信</td>\n",
|
1569 |
-
" <td>德赛西威</td>\n",
|
1570 |
-
" </tr>\n",
|
1571 |
-
" <tr>\n",
|
1572 |
-
" <th>1479</th>\n",
|
1573 |
-
" <td>002709.XSHE</td>\n",
|
1574 |
-
" <td>2022-01-10</td>\n",
|
1575 |
-
" <td>51.63</td>\n",
|
1576 |
-
" <td>50.73</td>\n",
|
1577 |
-
" <td>51.93</td>\n",
|
1578 |
-
" <td>50.03</td>\n",
|
1579 |
-
" <td>29821246.0</td>\n",
|
1580 |
-
" <td>1.518902e+09</td>\n",
|
1581 |
-
" <td>-0.019142</td>\n",
|
1582 |
-
" <td>149.690174</td>\n",
|
1583 |
-
" <td>0.496902</td>\n",
|
1584 |
-
" <td>0.209216</td>\n",
|
1585 |
-
" <td>0.103960</td>\n",
|
1586 |
-
" <td>工业</td>\n",
|
1587 |
-
" <td>天赐材料</td>\n",
|
1588 |
-
" </tr>\n",
|
1589 |
-
" <tr>\n",
|
1590 |
-
" <th>1480</th>\n",
|
1591 |
-
" <td>600415.XSHG</td>\n",
|
1592 |
-
" <td>2022-01-10</td>\n",
|
1593 |
-
" <td>4.70</td>\n",
|
1594 |
-
" <td>4.75</td>\n",
|
1595 |
-
" <td>4.85</td>\n",
|
1596 |
-
" <td>4.67</td>\n",
|
1597 |
-
" <td>39278041.0</td>\n",
|
1598 |
-
" <td>1.859827e+08</td>\n",
|
1599 |
-
" <td>0.010638</td>\n",
|
1600 |
-
" <td>80.919932</td>\n",
|
1601 |
-
" <td>-0.190801</td>\n",
|
1602 |
-
" <td>0.113099</td>\n",
|
1603 |
-
" <td>-0.021579</td>\n",
|
1604 |
-
" <td>消费</td>\n",
|
1605 |
-
" <td>小商品城</td>\n",
|
1606 |
-
" </tr>\n",
|
1607 |
-
" <tr>\n",
|
1608 |
-
" <th>1481</th>\n",
|
1609 |
-
" <td>603882.XSHG</td>\n",
|
1610 |
-
" <td>2022-01-10</td>\n",
|
1611 |
-
" <td>88.45</td>\n",
|
1612 |
-
" <td>95.53</td>\n",
|
1613 |
-
" <td>95.59</td>\n",
|
1614 |
-
" <td>88.39</td>\n",
|
1615 |
-
" <td>6991445.0</td>\n",
|
1616 |
-
" <td>6.468392e+08</td>\n",
|
1617 |
-
" <td>0.085692</td>\n",
|
1618 |
-
" <td>76.644737</td>\n",
|
1619 |
-
" <td>-0.233553</td>\n",
|
1620 |
-
" <td>0.107123</td>\n",
|
1621 |
-
" <td>-0.025019</td>\n",
|
1622 |
-
" <td>医药卫生</td>\n",
|
1623 |
-
" <td>金域医学</td>\n",
|
1624 |
-
" </tr>\n",
|
1625 |
-
" </tbody>\n",
|
1626 |
-
"</table>\n",
|
1627 |
-
"<p>1482 rows × 15 columns</p>\n",
|
1628 |
-
"</div>"
|
1629 |
-
],
|
1630 |
-
"text/plain": [
|
1631 |
-
" ticker date open close high low volume \\\n",
|
1632 |
-
"0 002709.XSHE 2021-01-05 32.54 33.89 34.22 31.39 59152352.0 \n",
|
1633 |
-
"1 600415.XSHG 2021-01-05 5.33 5.87 5.87 5.22 180936477.0 \n",
|
1634 |
-
"2 600409.XSHG 2021-01-05 9.23 9.57 9.66 9.08 82669289.0 \n",
|
1635 |
-
"3 300274.XSHE 2021-01-05 76.03 76.45 80.20 75.27 51384827.0 \n",
|
1636 |
-
"4 002920.XSHE 2021-01-05 85.44 87.25 87.95 84.07 3852674.0 \n",
|
1637 |
-
"... ... ... ... ... ... ... ... \n",
|
1638 |
-
"1477 600409.XSHG 2022-01-10 8.24 8.35 8.39 8.21 32516017.0 \n",
|
1639 |
-
"1478 002920.XSHE 2022-01-10 130.36 138.43 141.96 130.11 5005400.0 \n",
|
1640 |
-
"1479 002709.XSHE 2022-01-10 51.63 50.73 51.93 50.03 29821246.0 \n",
|
1641 |
-
"1480 600415.XSHG 2022-01-10 4.70 4.75 4.85 4.67 39278041.0 \n",
|
1642 |
-
"1481 603882.XSHG 2022-01-10 88.45 95.53 95.59 88.39 6991445.0 \n",
|
1643 |
-
"\n",
|
1644 |
-
" money pct weight return norm_weight \\\n",
|
1645 |
-
"0 1.942406e+09 NaN 100.000000 0.000000 0.166667 \n",
|
1646 |
-
"1 1.010225e+09 NaN 100.000000 0.000000 0.166667 \n",
|
1647 |
-
"2 7.803391e+08 NaN 100.000000 0.000000 0.166667 \n",
|
1648 |
-
"3 3.961995e+09 NaN 100.000000 0.000000 0.166667 \n",
|
1649 |
-
"4 3.322598e+08 NaN 100.000000 0.000000 0.166667 \n",
|
1650 |
-
"... ... ... ... ... ... \n",
|
1651 |
-
"1477 2.699300e+08 0.015815 87.251829 -0.127482 0.121949 \n",
|
1652 |
-
"1478 6.901614e+08 0.046888 158.659026 0.586590 0.221752 \n",
|
1653 |
-
"1479 1.518902e+09 -0.019142 149.690174 0.496902 0.209216 \n",
|
1654 |
-
"1480 1.859827e+08 0.010638 80.919932 -0.190801 0.113099 \n",
|
1655 |
-
"1481 6.468392e+08 0.085692 76.644737 -0.233553 0.107123 \n",
|
1656 |
-
"\n",
|
1657 |
-
" weighted_return aggregate_sector display_name \n",
|
1658 |
-
"0 0.000000 工业 天赐材料 \n",
|
1659 |
-
"1 0.000000 消费 小商品城 \n",
|
1660 |
-
"2 0.000000 原料与能源 三友化工 \n",
|
1661 |
-
"3 0.000000 工业 阳光电源 \n",
|
1662 |
-
"4 0.000000 信息与通信 德赛西威 \n",
|
1663 |
-
"... ... ... ... \n",
|
1664 |
-
"1477 -0.015546 原料与能源 三友化工 \n",
|
1665 |
-
"1478 0.130077 信息与通信 德赛西威 \n",
|
1666 |
-
"1479 0.103960 工业 天赐材料 \n",
|
1667 |
-
"1480 -0.021579 消费 小商品城 \n",
|
1668 |
-
"1481 -0.025019 医药卫生 金域医学 \n",
|
1669 |
-
"\n",
|
1670 |
-
"[1482 rows x 15 columns]"
|
1671 |
-
]
|
1672 |
-
},
|
1673 |
-
"execution_count": 127,
|
1674 |
-
"metadata": {},
|
1675 |
-
"output_type": "execute_result"
|
1676 |
-
}
|
1677 |
-
],
|
1678 |
-
"source": [
|
1679 |
-
"## agg by sector and day\n",
|
1680 |
-
"p_stock_df['weight_in_sector'] = p_stock_df.groupby"
|
1681 |
-
]
|
1682 |
-
},
|
1683 |
-
{
|
1684 |
-
"cell_type": "code",
|
1685 |
-
"execution_count": null,
|
1686 |
-
"metadata": {},
|
1687 |
-
"outputs": [],
|
1688 |
-
"source": [
|
1689 |
-
"def creaet_portfolio_return(stock_df):\n",
|
1690 |
-
" portfolio_df = stock_df.groupby(['date'])['weighted_return'].sum().reset_index()\n",
|
1691 |
-
" portfolio_df.rename(columns={'weighted_return':'portfolio_return'}, inplace=True)\n",
|
1692 |
-
" return portfolio_df"
|
1693 |
-
]
|
1694 |
-
},
|
1695 |
-
{
|
1696 |
-
"cell_type": "code",
|
1697 |
-
"execution_count": null,
|
1698 |
-
"metadata": {},
|
1699 |
-
"outputs": [
|
1700 |
-
{
|
1701 |
-
"data": {
|
1702 |
-
"text/html": [
|
1703 |
-
"<div>\n",
|
1704 |
-
"<style scoped>\n",
|
1705 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
1706 |
-
" vertical-align: middle;\n",
|
1707 |
-
" }\n",
|
1708 |
-
"\n",
|
1709 |
-
" .dataframe tbody tr th {\n",
|
1710 |
-
" vertical-align: top;\n",
|
1711 |
-
" }\n",
|
1712 |
-
"\n",
|
1713 |
-
" .dataframe thead th {\n",
|
1714 |
-
" text-align: right;\n",
|
1715 |
-
" }\n",
|
1716 |
-
"</style>\n",
|
1717 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
1718 |
-
" <thead>\n",
|
1719 |
-
" <tr style=\"text-align: right;\">\n",
|
1720 |
-
" <th></th>\n",
|
1721 |
-
" <th>date</th>\n",
|
1722 |
-
" <th>portfolio_return</th>\n",
|
1723 |
-
" </tr>\n",
|
1724 |
-
" </thead>\n",
|
1725 |
-
" <tbody>\n",
|
1726 |
-
" <tr>\n",
|
1727 |
-
" <th>0</th>\n",
|
1728 |
-
" <td>2021-01-05</td>\n",
|
1729 |
-
" <td>0.000000</td>\n",
|
1730 |
-
" </tr>\n",
|
1731 |
-
" <tr>\n",
|
1732 |
-
" <th>1</th>\n",
|
1733 |
-
" <td>2021-01-06</td>\n",
|
1734 |
-
" <td>0.007011</td>\n",
|
1735 |
-
" </tr>\n",
|
1736 |
-
" <tr>\n",
|
1737 |
-
" <th>2</th>\n",
|
1738 |
-
" <td>2021-01-07</td>\n",
|
1739 |
-
" <td>0.047531</td>\n",
|
1740 |
-
" </tr>\n",
|
1741 |
-
" <tr>\n",
|
1742 |
-
" <th>3</th>\n",
|
1743 |
-
" <td>2021-01-08</td>\n",
|
1744 |
-
" <td>0.047111</td>\n",
|
1745 |
-
" </tr>\n",
|
1746 |
-
" <tr>\n",
|
1747 |
-
" <th>4</th>\n",
|
1748 |
-
" <td>2021-01-11</td>\n",
|
1749 |
-
" <td>0.052768</td>\n",
|
1750 |
-
" </tr>\n",
|
1751 |
-
" <tr>\n",
|
1752 |
-
" <th>...</th>\n",
|
1753 |
-
" <td>...</td>\n",
|
1754 |
-
" <td>...</td>\n",
|
1755 |
-
" </tr>\n",
|
1756 |
-
" <tr>\n",
|
1757 |
-
" <th>242</th>\n",
|
1758 |
-
" <td>2022-01-04</td>\n",
|
1759 |
-
" <td>0.363845</td>\n",
|
1760 |
-
" </tr>\n",
|
1761 |
-
" <tr>\n",
|
1762 |
-
" <th>243</th>\n",
|
1763 |
-
" <td>2022-01-05</td>\n",
|
1764 |
-
" <td>0.306697</td>\n",
|
1765 |
-
" </tr>\n",
|
1766 |
-
" <tr>\n",
|
1767 |
-
" <th>244</th>\n",
|
1768 |
-
" <td>2022-01-06</td>\n",
|
1769 |
-
" <td>0.331291</td>\n",
|
1770 |
-
" </tr>\n",
|
1771 |
-
" <tr>\n",
|
1772 |
-
" <th>245</th>\n",
|
1773 |
-
" <td>2022-01-07</td>\n",
|
1774 |
-
" <td>0.313726</td>\n",
|
1775 |
-
" </tr>\n",
|
1776 |
-
" <tr>\n",
|
1777 |
-
" <th>246</th>\n",
|
1778 |
-
" <td>2022-01-10</td>\n",
|
1779 |
-
" <td>0.313262</td>\n",
|
1780 |
-
" </tr>\n",
|
1781 |
-
" </tbody>\n",
|
1782 |
-
"</table>\n",
|
1783 |
-
"<p>247 rows × 2 columns</p>\n",
|
1784 |
-
"</div>"
|
1785 |
-
],
|
1786 |
-
"text/plain": [
|
1787 |
-
" date portfolio_return\n",
|
1788 |
-
"0 2021-01-05 0.000000\n",
|
1789 |
-
"1 2021-01-06 0.007011\n",
|
1790 |
-
"2 2021-01-07 0.047531\n",
|
1791 |
-
"3 2021-01-08 0.047111\n",
|
1792 |
-
"4 2021-01-11 0.052768\n",
|
1793 |
-
".. ... ...\n",
|
1794 |
-
"242 2022-01-04 0.363845\n",
|
1795 |
-
"243 2022-01-05 0.306697\n",
|
1796 |
-
"244 2022-01-06 0.331291\n",
|
1797 |
-
"245 2022-01-07 0.313726\n",
|
1798 |
-
"246 2022-01-10 0.313262\n",
|
1799 |
-
"\n",
|
1800 |
-
"[247 rows x 2 columns]"
|
1801 |
-
]
|
1802 |
-
},
|
1803 |
-
"execution_count": 58,
|
1804 |
-
"metadata": {},
|
1805 |
-
"output_type": "execute_result"
|
1806 |
-
}
|
1807 |
-
],
|
1808 |
-
"source": [
|
1809 |
-
"portfolio_df = creaet_portfolio_return(p_stock_df)\n",
|
1810 |
-
"portfolio_df"
|
1811 |
-
]
|
1812 |
-
}
|
1813 |
-
],
|
1814 |
-
"metadata": {
|
1815 |
-
"kernelspec": {
|
1816 |
-
"display_name": "portfolio_risk_assesment",
|
1817 |
-
"language": "python",
|
1818 |
-
"name": "python3"
|
1819 |
-
},
|
1820 |
-
"language_info": {
|
1821 |
-
"codemirror_mode": {
|
1822 |
-
"name": "ipython",
|
1823 |
-
"version": 3
|
1824 |
-
},
|
1825 |
-
"file_extension": ".py",
|
1826 |
-
"mimetype": "text/x-python",
|
1827 |
-
"name": "python",
|
1828 |
-
"nbconvert_exporter": "python",
|
1829 |
-
"pygments_lexer": "ipython3",
|
1830 |
-
"version": "3.11.4"
|
1831 |
-
},
|
1832 |
-
"orig_nbformat": 4
|
1833 |
-
},
|
1834 |
-
"nbformat": 4,
|
1835 |
-
"nbformat_minor": 2
|
1836 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/sector_eval_df.pkl
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:dc104daae7afcd56a05f8aff9fa4d80d139a7db33d271fd69fbacb29db22283a
|
3 |
-
size 152021
|
|
|
|
|
|
|
|
script/stream_pricessing.ipynb
DELETED
@@ -1,617 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 2,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"data": {
|
10 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
11 |
-
"application/vnd.holoviews_load.v0+json": ""
|
12 |
-
},
|
13 |
-
"metadata": {},
|
14 |
-
"output_type": "display_data"
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"data": {
|
18 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
19 |
-
"application/vnd.holoviews_load.v0+json": ""
|
20 |
-
},
|
21 |
-
"metadata": {},
|
22 |
-
"output_type": "display_data"
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"data": {
|
26 |
-
"text/html": [
|
27 |
-
"<style>*[data-root-id],\n",
|
28 |
-
"*[data-root-id] > * {\n",
|
29 |
-
" box-sizing: border-box;\n",
|
30 |
-
" font-family: var(--jp-ui-font-family);\n",
|
31 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
32 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
33 |
-
"}\n",
|
34 |
-
"\n",
|
35 |
-
"/* Override VSCode background color */\n",
|
36 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
37 |
-
" > .lm-Widget\n",
|
38 |
-
" > *[data-root-id]),\n",
|
39 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
40 |
-
" background-color: transparent !important;\n",
|
41 |
-
"}\n",
|
42 |
-
"</style>"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
"metadata": {},
|
46 |
-
"output_type": "display_data"
|
47 |
-
}
|
48 |
-
],
|
49 |
-
"source": [
|
50 |
-
"import pandas as pd\n",
|
51 |
-
"import math\n",
|
52 |
-
"from datetime import datetime\n",
|
53 |
-
"import hvplot.pandas\n",
|
54 |
-
"import math\n",
|
55 |
-
"import numpy as np\n",
|
56 |
-
"from streamz import Stream"
|
57 |
-
]
|
58 |
-
},
|
59 |
-
{
|
60 |
-
"cell_type": "code",
|
61 |
-
"execution_count": 3,
|
62 |
-
"metadata": {},
|
63 |
-
"outputs": [],
|
64 |
-
"source": [
|
65 |
-
"b_stocks = pd.read_pickle('../data/b_stocks.pkl')\n",
|
66 |
-
"p_stocks = pd.read_pickle('../data/p_stocks.pkl')\n",
|
67 |
-
"p_profile = pd.read_pickle('../data/p_profile.pkl')\n",
|
68 |
-
"b_profile = pd.read_pickle('../data/b_profile.pkl')"
|
69 |
-
]
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"cell_type": "code",
|
73 |
-
"execution_count": 20,
|
74 |
-
"metadata": {},
|
75 |
-
"outputs": [
|
76 |
-
{
|
77 |
-
"data": {
|
78 |
-
"text/html": [
|
79 |
-
"<div>\n",
|
80 |
-
"<style scoped>\n",
|
81 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
82 |
-
" vertical-align: middle;\n",
|
83 |
-
" }\n",
|
84 |
-
"\n",
|
85 |
-
" .dataframe tbody tr th {\n",
|
86 |
-
" vertical-align: top;\n",
|
87 |
-
" }\n",
|
88 |
-
"\n",
|
89 |
-
" .dataframe thead th {\n",
|
90 |
-
" text-align: right;\n",
|
91 |
-
" }\n",
|
92 |
-
"</style>\n",
|
93 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
94 |
-
" <thead>\n",
|
95 |
-
" <tr style=\"text-align: right;\">\n",
|
96 |
-
" <th></th>\n",
|
97 |
-
" <th>date</th>\n",
|
98 |
-
" <th>ticker</th>\n",
|
99 |
-
" <th>open</th>\n",
|
100 |
-
" <th>close</th>\n",
|
101 |
-
" <th>high</th>\n",
|
102 |
-
" <th>low</th>\n",
|
103 |
-
" <th>volume</th>\n",
|
104 |
-
" <th>money</th>\n",
|
105 |
-
" </tr>\n",
|
106 |
-
" </thead>\n",
|
107 |
-
" <tbody>\n",
|
108 |
-
" <tr>\n",
|
109 |
-
" <th>1</th>\n",
|
110 |
-
" <td>2021-01-04</td>\n",
|
111 |
-
" <td>002233.XSHE</td>\n",
|
112 |
-
" <td>11.27</td>\n",
|
113 |
-
" <td>11.28</td>\n",
|
114 |
-
" <td>11.34</td>\n",
|
115 |
-
" <td>11.17</td>\n",
|
116 |
-
" <td>16262377.0</td>\n",
|
117 |
-
" <td>1.829668e+08</td>\n",
|
118 |
-
" </tr>\n",
|
119 |
-
" <tr>\n",
|
120 |
-
" <th>247</th>\n",
|
121 |
-
" <td>2021-01-04</td>\n",
|
122 |
-
" <td>601778.XSHG</td>\n",
|
123 |
-
" <td>7.27</td>\n",
|
124 |
-
" <td>7.65</td>\n",
|
125 |
-
" <td>7.77</td>\n",
|
126 |
-
" <td>7.25</td>\n",
|
127 |
-
" <td>59723781.0</td>\n",
|
128 |
-
" <td>4.523540e+08</td>\n",
|
129 |
-
" </tr>\n",
|
130 |
-
" <tr>\n",
|
131 |
-
" <th>493</th>\n",
|
132 |
-
" <td>2021-01-04</td>\n",
|
133 |
-
" <td>002368.XSHE</td>\n",
|
134 |
-
" <td>25.41</td>\n",
|
135 |
-
" <td>28.18</td>\n",
|
136 |
-
" <td>28.18</td>\n",
|
137 |
-
" <td>25.27</td>\n",
|
138 |
-
" <td>17448308.0</td>\n",
|
139 |
-
" <td>4.729692e+08</td>\n",
|
140 |
-
" </tr>\n",
|
141 |
-
" <tr>\n",
|
142 |
-
" <th>739</th>\n",
|
143 |
-
" <td>2021-01-04</td>\n",
|
144 |
-
" <td>001914.XSHE</td>\n",
|
145 |
-
" <td>21.21</td>\n",
|
146 |
-
" <td>20.39</td>\n",
|
147 |
-
" <td>21.33</td>\n",
|
148 |
-
" <td>20.26</td>\n",
|
149 |
-
" <td>6619778.0</td>\n",
|
150 |
-
" <td>1.366024e+08</td>\n",
|
151 |
-
" </tr>\n",
|
152 |
-
" <tr>\n",
|
153 |
-
" <th>985</th>\n",
|
154 |
-
" <td>2021-01-04</td>\n",
|
155 |
-
" <td>002384.XSHE</td>\n",
|
156 |
-
" <td>25.66</td>\n",
|
157 |
-
" <td>25.98</td>\n",
|
158 |
-
" <td>26.00</td>\n",
|
159 |
-
" <td>25.17</td>\n",
|
160 |
-
" <td>50695885.0</td>\n",
|
161 |
-
" <td>1.296706e+09</td>\n",
|
162 |
-
" </tr>\n",
|
163 |
-
" <tr>\n",
|
164 |
-
" <th>...</th>\n",
|
165 |
-
" <td>...</td>\n",
|
166 |
-
" <td>...</td>\n",
|
167 |
-
" <td>...</td>\n",
|
168 |
-
" <td>...</td>\n",
|
169 |
-
" <td>...</td>\n",
|
170 |
-
" <td>...</td>\n",
|
171 |
-
" <td>...</td>\n",
|
172 |
-
" <td>...</td>\n",
|
173 |
-
" </tr>\n",
|
174 |
-
" <tr>\n",
|
175 |
-
" <th>147355</th>\n",
|
176 |
-
" <td>2021-01-04</td>\n",
|
177 |
-
" <td>600511.XSHG</td>\n",
|
178 |
-
" <td>46.39</td>\n",
|
179 |
-
" <td>45.10</td>\n",
|
180 |
-
" <td>46.55</td>\n",
|
181 |
-
" <td>44.32</td>\n",
|
182 |
-
" <td>45375375.0</td>\n",
|
183 |
-
" <td>2.043297e+09</td>\n",
|
184 |
-
" </tr>\n",
|
185 |
-
" <tr>\n",
|
186 |
-
" <th>147601</th>\n",
|
187 |
-
" <td>2021-01-04</td>\n",
|
188 |
-
" <td>600236.XSHG</td>\n",
|
189 |
-
" <td>4.05</td>\n",
|
190 |
-
" <td>4.05</td>\n",
|
191 |
-
" <td>4.05</td>\n",
|
192 |
-
" <td>4.02</td>\n",
|
193 |
-
" <td>5788783.0</td>\n",
|
194 |
-
" <td>2.339606e+07</td>\n",
|
195 |
-
" </tr>\n",
|
196 |
-
" <tr>\n",
|
197 |
-
" <th>147847</th>\n",
|
198 |
-
" <td>2021-01-04</td>\n",
|
199 |
-
" <td>000807.XSHE</td>\n",
|
200 |
-
" <td>7.32</td>\n",
|
201 |
-
" <td>7.58</td>\n",
|
202 |
-
" <td>7.71</td>\n",
|
203 |
-
" <td>7.13</td>\n",
|
204 |
-
" <td>136647514.0</td>\n",
|
205 |
-
" <td>1.027073e+09</td>\n",
|
206 |
-
" </tr>\n",
|
207 |
-
" <tr>\n",
|
208 |
-
" <th>148093</th>\n",
|
209 |
-
" <td>2021-01-04</td>\n",
|
210 |
-
" <td>002815.XSHE</td>\n",
|
211 |
-
" <td>13.41</td>\n",
|
212 |
-
" <td>13.55</td>\n",
|
213 |
-
" <td>13.67</td>\n",
|
214 |
-
" <td>13.29</td>\n",
|
215 |
-
" <td>5410989.0</td>\n",
|
216 |
-
" <td>7.290842e+07</td>\n",
|
217 |
-
" </tr>\n",
|
218 |
-
" <tr>\n",
|
219 |
-
" <th>148339</th>\n",
|
220 |
-
" <td>2021-01-04</td>\n",
|
221 |
-
" <td>002690.XSHE</td>\n",
|
222 |
-
" <td>31.68</td>\n",
|
223 |
-
" <td>31.68</td>\n",
|
224 |
-
" <td>32.12</td>\n",
|
225 |
-
" <td>31.26</td>\n",
|
226 |
-
" <td>3641409.0</td>\n",
|
227 |
-
" <td>1.153387e+08</td>\n",
|
228 |
-
" </tr>\n",
|
229 |
-
" </tbody>\n",
|
230 |
-
"</table>\n",
|
231 |
-
"<p>604 rows × 8 columns</p>\n",
|
232 |
-
"</div>"
|
233 |
-
],
|
234 |
-
"text/plain": [
|
235 |
-
" date ticker open close high low volume \\\n",
|
236 |
-
"1 2021-01-04 002233.XSHE 11.27 11.28 11.34 11.17 16262377.0 \n",
|
237 |
-
"247 2021-01-04 601778.XSHG 7.27 7.65 7.77 7.25 59723781.0 \n",
|
238 |
-
"493 2021-01-04 002368.XSHE 25.41 28.18 28.18 25.27 17448308.0 \n",
|
239 |
-
"739 2021-01-04 001914.XSHE 21.21 20.39 21.33 20.26 6619778.0 \n",
|
240 |
-
"985 2021-01-04 002384.XSHE 25.66 25.98 26.00 25.17 50695885.0 \n",
|
241 |
-
"... ... ... ... ... ... ... ... \n",
|
242 |
-
"147355 2021-01-04 600511.XSHG 46.39 45.10 46.55 44.32 45375375.0 \n",
|
243 |
-
"147601 2021-01-04 600236.XSHG 4.05 4.05 4.05 4.02 5788783.0 \n",
|
244 |
-
"147847 2021-01-04 000807.XSHE 7.32 7.58 7.71 7.13 136647514.0 \n",
|
245 |
-
"148093 2021-01-04 002815.XSHE 13.41 13.55 13.67 13.29 5410989.0 \n",
|
246 |
-
"148339 2021-01-04 002690.XSHE 31.68 31.68 32.12 31.26 3641409.0 \n",
|
247 |
-
"\n",
|
248 |
-
" money \n",
|
249 |
-
"1 1.829668e+08 \n",
|
250 |
-
"247 4.523540e+08 \n",
|
251 |
-
"493 4.729692e+08 \n",
|
252 |
-
"739 1.366024e+08 \n",
|
253 |
-
"985 1.296706e+09 \n",
|
254 |
-
"... ... \n",
|
255 |
-
"147355 2.043297e+09 \n",
|
256 |
-
"147601 2.339606e+07 \n",
|
257 |
-
"147847 1.027073e+09 \n",
|
258 |
-
"148093 7.290842e+07 \n",
|
259 |
-
"148339 1.153387e+08 \n",
|
260 |
-
"\n",
|
261 |
-
"[604 rows x 8 columns]"
|
262 |
-
]
|
263 |
-
},
|
264 |
-
"execution_count": 20,
|
265 |
-
"metadata": {},
|
266 |
-
"output_type": "execute_result"
|
267 |
-
}
|
268 |
-
],
|
269 |
-
"source": [
|
270 |
-
"# start stream here\n",
|
271 |
-
"dates = b_stocks.date.unique()\n",
|
272 |
-
"b_stocks[b_stocks.date == dates[1]]"
|
273 |
-
]
|
274 |
-
},
|
275 |
-
{
|
276 |
-
"cell_type": "code",
|
277 |
-
"execution_count": 32,
|
278 |
-
"metadata": {},
|
279 |
-
"outputs": [],
|
280 |
-
"source": [
|
281 |
-
"data1 = b_stocks[b_stocks.date == dates[0]]\n",
|
282 |
-
"data2 = b_stocks[b_stocks.date == dates[1]]\n",
|
283 |
-
"data3 = b_stocks[b_stocks.date == dates[2]]"
|
284 |
-
]
|
285 |
-
},
|
286 |
-
{
|
287 |
-
"cell_type": "code",
|
288 |
-
"execution_count": 34,
|
289 |
-
"metadata": {},
|
290 |
-
"outputs": [
|
291 |
-
{
|
292 |
-
"data": {
|
293 |
-
"text/html": [
|
294 |
-
"<div>\n",
|
295 |
-
"<style scoped>\n",
|
296 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
297 |
-
" vertical-align: middle;\n",
|
298 |
-
" }\n",
|
299 |
-
"\n",
|
300 |
-
" .dataframe tbody tr th {\n",
|
301 |
-
" vertical-align: top;\n",
|
302 |
-
" }\n",
|
303 |
-
"\n",
|
304 |
-
" .dataframe thead th {\n",
|
305 |
-
" text-align: right;\n",
|
306 |
-
" }\n",
|
307 |
-
"</style>\n",
|
308 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
309 |
-
" <thead>\n",
|
310 |
-
" <tr style=\"text-align: right;\">\n",
|
311 |
-
" <th></th>\n",
|
312 |
-
" <th>date</th>\n",
|
313 |
-
" <th>ticker</th>\n",
|
314 |
-
" <th>open</th>\n",
|
315 |
-
" <th>close</th>\n",
|
316 |
-
" <th>high</th>\n",
|
317 |
-
" <th>low</th>\n",
|
318 |
-
" <th>volume</th>\n",
|
319 |
-
" <th>money</th>\n",
|
320 |
-
" </tr>\n",
|
321 |
-
" </thead>\n",
|
322 |
-
" <tbody>\n",
|
323 |
-
" <tr>\n",
|
324 |
-
" <th>0</th>\n",
|
325 |
-
" <td>2020-12-31</td>\n",
|
326 |
-
" <td>002233.XSHE</td>\n",
|
327 |
-
" <td>11.23</td>\n",
|
328 |
-
" <td>11.30</td>\n",
|
329 |
-
" <td>11.38</td>\n",
|
330 |
-
" <td>11.19</td>\n",
|
331 |
-
" <td>9712496.0</td>\n",
|
332 |
-
" <td>1.096390e+08</td>\n",
|
333 |
-
" </tr>\n",
|
334 |
-
" <tr>\n",
|
335 |
-
" <th>246</th>\n",
|
336 |
-
" <td>2020-12-31</td>\n",
|
337 |
-
" <td>601778.XSHG</td>\n",
|
338 |
-
" <td>7.28</td>\n",
|
339 |
-
" <td>7.23</td>\n",
|
340 |
-
" <td>7.39</td>\n",
|
341 |
-
" <td>7.20</td>\n",
|
342 |
-
" <td>29971398.0</td>\n",
|
343 |
-
" <td>2.181267e+08</td>\n",
|
344 |
-
" </tr>\n",
|
345 |
-
" <tr>\n",
|
346 |
-
" <th>492</th>\n",
|
347 |
-
" <td>2020-12-31</td>\n",
|
348 |
-
" <td>002368.XSHE</td>\n",
|
349 |
-
" <td>24.96</td>\n",
|
350 |
-
" <td>25.62</td>\n",
|
351 |
-
" <td>25.92</td>\n",
|
352 |
-
" <td>24.96</td>\n",
|
353 |
-
" <td>7090839.0</td>\n",
|
354 |
-
" <td>1.811902e+08</td>\n",
|
355 |
-
" </tr>\n",
|
356 |
-
" <tr>\n",
|
357 |
-
" <th>738</th>\n",
|
358 |
-
" <td>2020-12-31</td>\n",
|
359 |
-
" <td>001914.XSHE</td>\n",
|
360 |
-
" <td>20.52</td>\n",
|
361 |
-
" <td>21.26</td>\n",
|
362 |
-
" <td>21.36</td>\n",
|
363 |
-
" <td>20.52</td>\n",
|
364 |
-
" <td>5598757.0</td>\n",
|
365 |
-
" <td>1.171876e+08</td>\n",
|
366 |
-
" </tr>\n",
|
367 |
-
" <tr>\n",
|
368 |
-
" <th>984</th>\n",
|
369 |
-
" <td>2020-12-31</td>\n",
|
370 |
-
" <td>002384.XSHE</td>\n",
|
371 |
-
" <td>25.67</td>\n",
|
372 |
-
" <td>25.65</td>\n",
|
373 |
-
" <td>25.90</td>\n",
|
374 |
-
" <td>25.15</td>\n",
|
375 |
-
" <td>49307624.0</td>\n",
|
376 |
-
" <td>1.256593e+09</td>\n",
|
377 |
-
" </tr>\n",
|
378 |
-
" <tr>\n",
|
379 |
-
" <th>...</th>\n",
|
380 |
-
" <td>...</td>\n",
|
381 |
-
" <td>...</td>\n",
|
382 |
-
" <td>...</td>\n",
|
383 |
-
" <td>...</td>\n",
|
384 |
-
" <td>...</td>\n",
|
385 |
-
" <td>...</td>\n",
|
386 |
-
" <td>...</td>\n",
|
387 |
-
" <td>...</td>\n",
|
388 |
-
" </tr>\n",
|
389 |
-
" <tr>\n",
|
390 |
-
" <th>147355</th>\n",
|
391 |
-
" <td>2021-01-04</td>\n",
|
392 |
-
" <td>600511.XSHG</td>\n",
|
393 |
-
" <td>46.39</td>\n",
|
394 |
-
" <td>45.10</td>\n",
|
395 |
-
" <td>46.55</td>\n",
|
396 |
-
" <td>44.32</td>\n",
|
397 |
-
" <td>45375375.0</td>\n",
|
398 |
-
" <td>2.043297e+09</td>\n",
|
399 |
-
" </tr>\n",
|
400 |
-
" <tr>\n",
|
401 |
-
" <th>147601</th>\n",
|
402 |
-
" <td>2021-01-04</td>\n",
|
403 |
-
" <td>600236.XSHG</td>\n",
|
404 |
-
" <td>4.05</td>\n",
|
405 |
-
" <td>4.05</td>\n",
|
406 |
-
" <td>4.05</td>\n",
|
407 |
-
" <td>4.02</td>\n",
|
408 |
-
" <td>5788783.0</td>\n",
|
409 |
-
" <td>2.339606e+07</td>\n",
|
410 |
-
" </tr>\n",
|
411 |
-
" <tr>\n",
|
412 |
-
" <th>147847</th>\n",
|
413 |
-
" <td>2021-01-04</td>\n",
|
414 |
-
" <td>000807.XSHE</td>\n",
|
415 |
-
" <td>7.32</td>\n",
|
416 |
-
" <td>7.58</td>\n",
|
417 |
-
" <td>7.71</td>\n",
|
418 |
-
" <td>7.13</td>\n",
|
419 |
-
" <td>136647514.0</td>\n",
|
420 |
-
" <td>1.027073e+09</td>\n",
|
421 |
-
" </tr>\n",
|
422 |
-
" <tr>\n",
|
423 |
-
" <th>148093</th>\n",
|
424 |
-
" <td>2021-01-04</td>\n",
|
425 |
-
" <td>002815.XSHE</td>\n",
|
426 |
-
" <td>13.41</td>\n",
|
427 |
-
" <td>13.55</td>\n",
|
428 |
-
" <td>13.67</td>\n",
|
429 |
-
" <td>13.29</td>\n",
|
430 |
-
" <td>5410989.0</td>\n",
|
431 |
-
" <td>7.290842e+07</td>\n",
|
432 |
-
" </tr>\n",
|
433 |
-
" <tr>\n",
|
434 |
-
" <th>148339</th>\n",
|
435 |
-
" <td>2021-01-04</td>\n",
|
436 |
-
" <td>002690.XSHE</td>\n",
|
437 |
-
" <td>31.68</td>\n",
|
438 |
-
" <td>31.68</td>\n",
|
439 |
-
" <td>32.12</td>\n",
|
440 |
-
" <td>31.26</td>\n",
|
441 |
-
" <td>3641409.0</td>\n",
|
442 |
-
" <td>1.153387e+08</td>\n",
|
443 |
-
" </tr>\n",
|
444 |
-
" </tbody>\n",
|
445 |
-
"</table>\n",
|
446 |
-
"<p>1208 rows × 8 columns</p>\n",
|
447 |
-
"</div>"
|
448 |
-
],
|
449 |
-
"text/plain": [
|
450 |
-
" date ticker open close high low volume \\\n",
|
451 |
-
"0 2020-12-31 002233.XSHE 11.23 11.30 11.38 11.19 9712496.0 \n",
|
452 |
-
"246 2020-12-31 601778.XSHG 7.28 7.23 7.39 7.20 29971398.0 \n",
|
453 |
-
"492 2020-12-31 002368.XSHE 24.96 25.62 25.92 24.96 7090839.0 \n",
|
454 |
-
"738 2020-12-31 001914.XSHE 20.52 21.26 21.36 20.52 5598757.0 \n",
|
455 |
-
"984 2020-12-31 002384.XSHE 25.67 25.65 25.90 25.15 49307624.0 \n",
|
456 |
-
"... ... ... ... ... ... ... ... \n",
|
457 |
-
"147355 2021-01-04 600511.XSHG 46.39 45.10 46.55 44.32 45375375.0 \n",
|
458 |
-
"147601 2021-01-04 600236.XSHG 4.05 4.05 4.05 4.02 5788783.0 \n",
|
459 |
-
"147847 2021-01-04 000807.XSHE 7.32 7.58 7.71 7.13 136647514.0 \n",
|
460 |
-
"148093 2021-01-04 002815.XSHE 13.41 13.55 13.67 13.29 5410989.0 \n",
|
461 |
-
"148339 2021-01-04 002690.XSHE 31.68 31.68 32.12 31.26 3641409.0 \n",
|
462 |
-
"\n",
|
463 |
-
" money \n",
|
464 |
-
"0 1.096390e+08 \n",
|
465 |
-
"246 2.181267e+08 \n",
|
466 |
-
"492 1.811902e+08 \n",
|
467 |
-
"738 1.171876e+08 \n",
|
468 |
-
"984 1.256593e+09 \n",
|
469 |
-
"... ... \n",
|
470 |
-
"147355 2.043297e+09 \n",
|
471 |
-
"147601 2.339606e+07 \n",
|
472 |
-
"147847 1.027073e+09 \n",
|
473 |
-
"148093 7.290842e+07 \n",
|
474 |
-
"148339 1.153387e+08 \n",
|
475 |
-
"\n",
|
476 |
-
"[1208 rows x 8 columns]"
|
477 |
-
]
|
478 |
-
},
|
479 |
-
"execution_count": 34,
|
480 |
-
"metadata": {},
|
481 |
-
"output_type": "execute_result"
|
482 |
-
}
|
483 |
-
],
|
484 |
-
"source": [
|
485 |
-
"merged_df = pd.concat([data1, data2])\n",
|
486 |
-
"merged_df"
|
487 |
-
]
|
488 |
-
},
|
489 |
-
{
|
490 |
-
"cell_type": "code",
|
491 |
-
"execution_count": 31,
|
492 |
-
"metadata": {},
|
493 |
-
"outputs": [
|
494 |
-
{
|
495 |
-
"name": "stdout",
|
496 |
-
"output_type": "stream",
|
497 |
-
"text": [
|
498 |
-
" date ticker open close high low volume \\\n",
|
499 |
-
"0 2020-12-31 002233.XSHE 11.23 11.30 11.38 11.19 9712496.0 \n",
|
500 |
-
"246 2020-12-31 601778.XSHG 7.28 7.23 7.39 7.20 29971398.0 \n",
|
501 |
-
"492 2020-12-31 002368.XSHE 24.96 25.62 25.92 24.96 7090839.0 \n",
|
502 |
-
"738 2020-12-31 001914.XSHE 20.52 21.26 21.36 20.52 5598757.0 \n",
|
503 |
-
"984 2020-12-31 002384.XSHE 25.67 25.65 25.90 25.15 49307624.0 \n",
|
504 |
-
"... ... ... ... ... ... ... ... \n",
|
505 |
-
"147354 2020-12-31 600511.XSHG 44.43 46.33 48.45 44.16 69779041.0 \n",
|
506 |
-
"147600 2020-12-31 600236.XSHG 4.07 4.05 4.10 4.02 6542015.0 \n",
|
507 |
-
"147846 2020-12-31 000807.XSHE 7.34 7.35 7.48 7.20 72260375.0 \n",
|
508 |
-
"148092 2020-12-31 002815.XSHE 13.22 13.41 13.51 13.19 4198958.0 \n",
|
509 |
-
"148338 2020-12-31 002690.XSHE 31.14 31.48 31.60 30.79 4010199.0 \n",
|
510 |
-
"\n",
|
511 |
-
" money \n",
|
512 |
-
"0 1.096390e+08 \n",
|
513 |
-
"246 2.181267e+08 \n",
|
514 |
-
"492 1.811902e+08 \n",
|
515 |
-
"738 1.171876e+08 \n",
|
516 |
-
"984 1.256593e+09 \n",
|
517 |
-
"... ... \n",
|
518 |
-
"147354 3.258608e+09 \n",
|
519 |
-
"147600 2.649244e+07 \n",
|
520 |
-
"147846 5.305392e+08 \n",
|
521 |
-
"148092 5.621386e+07 \n",
|
522 |
-
"148338 1.257796e+08 \n",
|
523 |
-
"\n",
|
524 |
-
"[604 rows x 8 columns]\n",
|
525 |
-
" date ticker open close high low volume \\\n",
|
526 |
-
"0 2020-12-31 002233.XSHE 11.23 11.30 11.38 11.19 9712496.0 \n",
|
527 |
-
"246 2020-12-31 601778.XSHG 7.28 7.23 7.39 7.20 29971398.0 \n",
|
528 |
-
"492 2020-12-31 002368.XSHE 24.96 25.62 25.92 24.96 7090839.0 \n",
|
529 |
-
"738 2020-12-31 001914.XSHE 20.52 21.26 21.36 20.52 5598757.0 \n",
|
530 |
-
"984 2020-12-31 002384.XSHE 25.67 25.65 25.90 25.15 49307624.0 \n",
|
531 |
-
"... ... ... ... ... ... ... ... \n",
|
532 |
-
"147355 2021-01-04 600511.XSHG 46.39 45.10 46.55 44.32 45375375.0 \n",
|
533 |
-
"147601 2021-01-04 600236.XSHG 4.05 4.05 4.05 4.02 5788783.0 \n",
|
534 |
-
"147847 2021-01-04 000807.XSHE 7.32 7.58 7.71 7.13 136647514.0 \n",
|
535 |
-
"148093 2021-01-04 002815.XSHE 13.41 13.55 13.67 13.29 5410989.0 \n",
|
536 |
-
"148339 2021-01-04 002690.XSHE 31.68 31.68 32.12 31.26 3641409.0 \n",
|
537 |
-
"\n",
|
538 |
-
" money \n",
|
539 |
-
"0 1.096390e+08 \n",
|
540 |
-
"246 2.181267e+08 \n",
|
541 |
-
"492 1.811902e+08 \n",
|
542 |
-
"738 1.171876e+08 \n",
|
543 |
-
"984 1.256593e+09 \n",
|
544 |
-
"... ... \n",
|
545 |
-
"147355 2.043297e+09 \n",
|
546 |
-
"147601 2.339606e+07 \n",
|
547 |
-
"147847 1.027073e+09 \n",
|
548 |
-
"148093 7.290842e+07 \n",
|
549 |
-
"148339 1.153387e+08 \n",
|
550 |
-
"\n",
|
551 |
-
"[1208 rows x 8 columns]\n",
|
552 |
-
" date ticker open close high low volume \\\n",
|
553 |
-
"0 2020-12-31 002233.XSHE 11.23 11.30 11.38 11.19 9712496.0 \n",
|
554 |
-
"246 2020-12-31 601778.XSHG 7.28 7.23 7.39 7.20 29971398.0 \n",
|
555 |
-
"492 2020-12-31 002368.XSHE 24.96 25.62 25.92 24.96 7090839.0 \n",
|
556 |
-
"738 2020-12-31 001914.XSHE 20.52 21.26 21.36 20.52 5598757.0 \n",
|
557 |
-
"984 2020-12-31 002384.XSHE 25.67 25.65 25.90 25.15 49307624.0 \n",
|
558 |
-
"... ... ... ... ... ... ... ... \n",
|
559 |
-
"147356 2021-01-05 600511.XSHG 45.00 45.58 46.79 43.58 45296155.0 \n",
|
560 |
-
"147602 2021-01-05 600236.XSHG 4.04 4.01 4.05 4.00 4302703.0 \n",
|
561 |
-
"147848 2021-01-05 000807.XSHE 7.61 7.99 8.21 7.48 177268867.0 \n",
|
562 |
-
"148094 2021-01-05 002815.XSHE 13.52 13.63 13.65 13.44 5800866.0 \n",
|
563 |
-
"148340 2021-01-05 002690.XSHE 31.68 31.85 32.14 31.42 5082815.0 \n",
|
564 |
-
"\n",
|
565 |
-
" money \n",
|
566 |
-
"0 1.096390e+08 \n",
|
567 |
-
"246 2.181267e+08 \n",
|
568 |
-
"492 1.811902e+08 \n",
|
569 |
-
"738 1.171876e+08 \n",
|
570 |
-
"984 1.256593e+09 \n",
|
571 |
-
"... ... \n",
|
572 |
-
"147356 2.035299e+09 \n",
|
573 |
-
"147602 1.726972e+07 \n",
|
574 |
-
"147848 1.383377e+09 \n",
|
575 |
-
"148094 7.856429e+07 \n",
|
576 |
-
"148340 1.612986e+08 \n",
|
577 |
-
"\n",
|
578 |
-
"[1812 rows x 8 columns]\n"
|
579 |
-
]
|
580 |
-
}
|
581 |
-
],
|
582 |
-
"source": [
|
583 |
-
"def add(prev_df, new_df):\n",
|
584 |
-
" merged_df = pd.concat([prev_df, new_df])\n",
|
585 |
-
" return merged_df\n",
|
586 |
-
"\n",
|
587 |
-
"source = Stream()\n",
|
588 |
-
"source.accumulate(add).sink(print)\n",
|
589 |
-
"source.emit(b_stocks[b_stocks.date == dates[0]])\n",
|
590 |
-
"source.emit(b_stocks[b_stocks.date == dates[1]])\n",
|
591 |
-
"source.emit(b_stocks[b_stocks.date == dates[2]])\n"
|
592 |
-
]
|
593 |
-
}
|
594 |
-
],
|
595 |
-
"metadata": {
|
596 |
-
"kernelspec": {
|
597 |
-
"display_name": "portfolio_risk_assesment",
|
598 |
-
"language": "python",
|
599 |
-
"name": "python3"
|
600 |
-
},
|
601 |
-
"language_info": {
|
602 |
-
"codemirror_mode": {
|
603 |
-
"name": "ipython",
|
604 |
-
"version": 3
|
605 |
-
},
|
606 |
-
"file_extension": ".py",
|
607 |
-
"mimetype": "text/x-python",
|
608 |
-
"name": "python",
|
609 |
-
"nbconvert_exporter": "python",
|
610 |
-
"pygments_lexer": "ipython3",
|
611 |
-
"version": "3.11.4"
|
612 |
-
},
|
613 |
-
"orig_nbformat": 4
|
614 |
-
},
|
615 |
-
"nbformat": 4,
|
616 |
-
"nbformat_minor": 2
|
617 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/stream_processing.py
DELETED
@@ -1,32 +0,0 @@
|
|
1 |
-
import pandas as pd
|
2 |
-
import math
|
3 |
-
from datetime import datetime
|
4 |
-
import hvplot.pandas
|
5 |
-
import math
|
6 |
-
import numpy as np
|
7 |
-
import time
|
8 |
-
from streamz import Stream
|
9 |
-
|
10 |
-
b_stocks = pd.read_pickle('../data/b_stocks.pkl')
|
11 |
-
p_stocks = pd.read_pickle('../data/p_stocks.pkl')
|
12 |
-
p_profile = pd.read_pickle('../data/p_profile.pkl')
|
13 |
-
b_profile = pd.read_pickle('../data/b_profile.pkl')
|
14 |
-
|
15 |
-
# start stream here
|
16 |
-
dates = b_stocks.date.unique()
|
17 |
-
b_stocks[b_stocks.date == dates[1]]
|
18 |
-
|
19 |
-
def add(prev_df, new_df):
|
20 |
-
merged_df = pd.concat([prev_df, new_df])
|
21 |
-
merged_df.sort_values(by=['date'], inplace=True)
|
22 |
-
merged_df['pct'] = merged_df.groupby('ticker')['close'].pct_change()
|
23 |
-
|
24 |
-
# remove prev_df
|
25 |
-
merged_df = merged_df[~merged_df.isin(prev_df)].dropna()
|
26 |
-
return merged_df
|
27 |
-
|
28 |
-
source = Stream()
|
29 |
-
source.accumulate(add).sink(print)
|
30 |
-
source.emit(b_stocks[b_stocks.date == dates[0]])
|
31 |
-
source.emit(b_stocks[b_stocks.date == dates[1]])
|
32 |
-
source.emit(b_stocks[b_stocks.date == dates[2]])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
script/styling.py
DELETED
@@ -1,15 +0,0 @@
|
|
1 |
-
plot_layout = dict(
|
2 |
-
legend=dict(
|
3 |
-
orientation="h",
|
4 |
-
),
|
5 |
-
yaxis_title=None,
|
6 |
-
xaxis_title=None,
|
7 |
-
margin=dict(l=0, r=0, t=30, b=0),
|
8 |
-
uniformtext_mode='hide',
|
9 |
-
|
10 |
-
)
|
11 |
-
|
12 |
-
barplot_trace = dict(
|
13 |
-
marker_line_width=0,
|
14 |
-
selector=dict(type="bar"),
|
15 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test.ipynb
DELETED
@@ -1,47 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": null,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import numpy as np\n",
|
10 |
-
"import pandas as pd\n",
|
11 |
-
"import panel as pn\n",
|
12 |
-
"\n",
|
13 |
-
"pn.extension('perspective', template='fast', sizing_mode='stretch_width')\n",
|
14 |
-
"df = pd.DataFrame(np.random.randn(10, 4), columns=list('ABCD')).cumsum()\n",
|
15 |
-
"\n",
|
16 |
-
"rollover = pn.widgets.IntInput(name='Rollover', value=15)\n",
|
17 |
-
"\n",
|
18 |
-
"perspective = pn.pane.Perspective(df, height=400)\n",
|
19 |
-
"\n",
|
20 |
-
"def stream():\n",
|
21 |
-
" data = df.iloc[-1] + np.random.randn(4)\n",
|
22 |
-
" perspective.stream(data, rollover=rollover.value)\n",
|
23 |
-
"\\\n",
|
24 |
-
"cb = pn.state.add_periodic_callback(stream, 50)\n",
|
25 |
-
"\n",
|
26 |
-
"pn.Column(\n",
|
27 |
-
" pn.Row(cb.param.period, rollover, perspective.param.theme),\n",
|
28 |
-
" perspective\n",
|
29 |
-
").servable()"
|
30 |
-
]
|
31 |
-
}
|
32 |
-
],
|
33 |
-
"metadata": {
|
34 |
-
"kernelspec": {
|
35 |
-
"display_name": "portfolio_risk_assesment",
|
36 |
-
"language": "python",
|
37 |
-
"name": "python3"
|
38 |
-
},
|
39 |
-
"language_info": {
|
40 |
-
"name": "python",
|
41 |
-
"version": "3.11.4"
|
42 |
-
},
|
43 |
-
"orig_nbformat": 4
|
44 |
-
},
|
45 |
-
"nbformat": 4,
|
46 |
-
"nbformat_minor": 2
|
47 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_background_task.py
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
import pipeline
|
2 |
-
import settings
|
3 |
-
|
4 |
-
def test_need_to_update():
|
5 |
-
table_list = settings.TABLE_NAME_AND_FREQ
|
6 |
-
for table, freq in table_list:
|
7 |
-
result = pipeline.need_to_update(table, freq)
|
8 |
-
print(result)
|
9 |
-
|
10 |
-
# test_need_to_update()
|
11 |
-
|
12 |
-
def test_fetch_stock_price():
|
13 |
-
df = pipeline.fetch_stock_price()
|
14 |
-
return df
|
15 |
-
|
16 |
-
def test_need_to_update_stocks_price():
|
17 |
-
print(pipeline.need_to_update_stocks_price())
|
18 |
-
|
19 |
-
|
20 |
-
def test_add_details_to_stock_df():
|
21 |
-
stock_df = pipeline.update_stocks_price()
|
22 |
-
stock_df = pipeline.add_details_to_stock_df(stock_df)
|
23 |
-
|
24 |
-
return stock_df
|
25 |
-
|
26 |
-
print(test_add_details_to_stock_df())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_responsive.py
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
import random
|
2 |
-
import panel.widgets as pnw
|
3 |
-
import panel as pn
|
4 |
-
pn.extension()
|
5 |
-
|
6 |
-
|
7 |
-
def rcolor(): return "#%06x" % random.randint(0, 0xFFFFFF)
|
8 |
-
|
9 |
-
|
10 |
-
box = pn.FlexBox(*[pn.pane.HTML(str(i), styles=dict(background=rcolor()),
|
11 |
-
width=370, height=100, sizing_mode='fixed') for i in range(24)],
|
12 |
-
align_conten='start', styles={'background': 'black'}
|
13 |
-
)
|
14 |
-
box.servable()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testing_pipeline.ipynb
DELETED
@@ -1,561 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"data": {
|
10 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
11 |
-
"application/vnd.holoviews_load.v0+json": ""
|
12 |
-
},
|
13 |
-
"metadata": {},
|
14 |
-
"output_type": "display_data"
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"data": {
|
18 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
19 |
-
"application/vnd.holoviews_load.v0+json": ""
|
20 |
-
},
|
21 |
-
"metadata": {},
|
22 |
-
"output_type": "display_data"
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"data": {
|
26 |
-
"text/html": [
|
27 |
-
"<style>*[data-root-id],\n",
|
28 |
-
"*[data-root-id] > * {\n",
|
29 |
-
" box-sizing: border-box;\n",
|
30 |
-
" font-family: var(--jp-ui-font-family);\n",
|
31 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
32 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
33 |
-
"}\n",
|
34 |
-
"\n",
|
35 |
-
"/* Override VSCode background color */\n",
|
36 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
37 |
-
" > .lm-Widget\n",
|
38 |
-
" > *[data-root-id]),\n",
|
39 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
40 |
-
" background-color: transparent !important;\n",
|
41 |
-
"}\n",
|
42 |
-
"</style>"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
"metadata": {},
|
46 |
-
"output_type": "display_data"
|
47 |
-
}
|
48 |
-
],
|
49 |
-
"source": [
|
50 |
-
"import pipeline\n",
|
51 |
-
"import settings\n",
|
52 |
-
"from sqlalchemy import create_engine\n",
|
53 |
-
"import pandas as pd\n",
|
54 |
-
"import processing\n",
|
55 |
-
"import datetime as dt\n",
|
56 |
-
"import api\n",
|
57 |
-
"import table_schema as ts\n",
|
58 |
-
"import db_operation as db\n",
|
59 |
-
"import numpy as np\n",
|
60 |
-
"import utils\n",
|
61 |
-
"import hvplot.pandas # noqa\n",
|
62 |
-
"pd.options.plotting.backend = 'holoviews'\n",
|
63 |
-
"db_url = 'sqlite:///instance/local.db'"
|
64 |
-
]
|
65 |
-
},
|
66 |
-
{
|
67 |
-
"cell_type": "code",
|
68 |
-
"execution_count": 2,
|
69 |
-
"metadata": {},
|
70 |
-
"outputs": [],
|
71 |
-
"source": [
|
72 |
-
"%load_ext autoreload\n",
|
73 |
-
"%autoreload 2"
|
74 |
-
]
|
75 |
-
},
|
76 |
-
{
|
77 |
-
"cell_type": "code",
|
78 |
-
"execution_count": 3,
|
79 |
-
"metadata": {},
|
80 |
-
"outputs": [],
|
81 |
-
"source": [
|
82 |
-
"# unique ticker list\n",
|
83 |
-
"def get_stocks_in_profile(profile_df):\n",
|
84 |
-
" ticker_list = profile_df['ticker'].unique().tolist()\n",
|
85 |
-
" stocks_df = db.get_stocks_price(ticker_list)\n",
|
86 |
-
" return stocks_df\n",
|
87 |
-
"portfolio_p = db.get_all_portfolio_profile()\n",
|
88 |
-
"benchmark_p = db.get_all_benchmark_profile()\n",
|
89 |
-
"p_stocks_df = get_stocks_in_profile(portfolio_p)\n",
|
90 |
-
"b_stocks_df = get_stocks_in_profile(benchmark_p)\n",
|
91 |
-
"\n",
|
92 |
-
"## temperaraly handle rename date to time\n",
|
93 |
-
"portfolio_p.rename(columns={'date': 'time','weight':'ini_w'}, inplace=True)\n",
|
94 |
-
"benchmark_p.rename(columns={'date': 'time'}, inplace=True)\n",
|
95 |
-
"# normalize weight in benchmark\n",
|
96 |
-
"grouped = benchmark_p.groupby('time')\n",
|
97 |
-
"benchmark_p['ini_w'] = grouped['weight'].transform(lambda x: x / x.sum())"
|
98 |
-
]
|
99 |
-
},
|
100 |
-
{
|
101 |
-
"cell_type": "code",
|
102 |
-
"execution_count": 4,
|
103 |
-
"metadata": {},
|
104 |
-
"outputs": [],
|
105 |
-
"source": [
|
106 |
-
"analytic_b = processing.create_analytic_df(b_stocks_df, benchmark_p)\n",
|
107 |
-
"analytic_p = processing.create_analytic_df(p_stocks_df, portfolio_p)"
|
108 |
-
]
|
109 |
-
},
|
110 |
-
{
|
111 |
-
"cell_type": "code",
|
112 |
-
"execution_count": 5,
|
113 |
-
"metadata": {},
|
114 |
-
"outputs": [],
|
115 |
-
"source": [
|
116 |
-
"# p stock weight\n",
|
117 |
-
"processing.calculate_cash(analytic_p)\n",
|
118 |
-
"processing.calculate_weight_using_cash(analytic_p)\n",
|
119 |
-
"processing.calculate_pct(analytic_p)\n",
|
120 |
-
"# b stock weight\n",
|
121 |
-
"analytic_b.sort_values(by=['time'], inplace=True)\n",
|
122 |
-
"grouped = analytic_b.groupby('ticker')\n",
|
123 |
-
"analytic_b['pct'] = grouped['close'].pct_change()\n",
|
124 |
-
"processing.calculate_weight_using_pct(analytic_b)\n",
|
125 |
-
"\n",
|
126 |
-
"# analytic_df.hvplot.line(x='time', y='cur_w', by='ticker', width=500, height=400)\n",
|
127 |
-
"# analytic_d"
|
128 |
-
]
|
129 |
-
},
|
130 |
-
{
|
131 |
-
"cell_type": "code",
|
132 |
-
"execution_count": 6,
|
133 |
-
"metadata": {},
|
134 |
-
"outputs": [],
|
135 |
-
"source": [
|
136 |
-
"# crop before processing\n",
|
137 |
-
"analytic_b = analytic_b[analytic_b.time >= analytic_p.time.min()].copy()\n",
|
138 |
-
"processing.calculate_log_return(analytic_p)\n",
|
139 |
-
"processing.calculate_log_return(analytic_b)\n"
|
140 |
-
]
|
141 |
-
},
|
142 |
-
{
|
143 |
-
"cell_type": "code",
|
144 |
-
"execution_count": 7,
|
145 |
-
"metadata": {},
|
146 |
-
"outputs": [
|
147 |
-
{
|
148 |
-
"data": {
|
149 |
-
"text/plain": [
|
150 |
-
"Index(['time', 'ticker', 'open', 'close', 'high', 'low', 'volume', 'money',\n",
|
151 |
-
" 'shares', 'sector', 'aggregate_sector', 'display_name', 'name', 'cash',\n",
|
152 |
-
" 'ini_w', 'ave_price', 'weight', 'pct', 'log_return',\n",
|
153 |
-
" 'weighted_log_return'],\n",
|
154 |
-
" dtype='object')"
|
155 |
-
]
|
156 |
-
},
|
157 |
-
"execution_count": 7,
|
158 |
-
"metadata": {},
|
159 |
-
"output_type": "execute_result"
|
160 |
-
}
|
161 |
-
],
|
162 |
-
"source": [
|
163 |
-
"analytic_p.columns"
|
164 |
-
]
|
165 |
-
},
|
166 |
-
{
|
167 |
-
"cell_type": "code",
|
168 |
-
"execution_count": 20,
|
169 |
-
"metadata": {},
|
170 |
-
"outputs": [
|
171 |
-
{
|
172 |
-
"data": {},
|
173 |
-
"metadata": {},
|
174 |
-
"output_type": "display_data"
|
175 |
-
},
|
176 |
-
{
|
177 |
-
"data": {
|
178 |
-
"application/vnd.holoviews_exec.v0+json": "",
|
179 |
-
"text/html": [
|
180 |
-
"<div id='p1149'>\n",
|
181 |
-
" <div id=\"ad7e920f-cf41-4c46-8ae3-2357eee49c67\" data-root-id=\"p1149\" style=\"display: contents;\"></div>\n",
|
182 |
-
"</div>\n",
|
183 |
-
"<script type=\"application/javascript\">(function(root) {\n",
|
184 |
-
" var docs_json = {\"9024d76f-8d10-4a0a-8327-1e46e4bcf29d\":{\"version\":\"3.1.1\",\"title\":\"Bokeh Application\",\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"mode\",\"kind\":\"Any\",\"default\":\"warn\"},{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationAreaBase1\",\"properties\":[{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]}],\"roots\":[{\"type\":\"object\",\"name\":\"Row\",\"id\":\"p1149\",\"attributes\":{\"name\":\"Row01028\",\"tags\":[\"embedded\"],\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n}\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"p1152\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.1.1/dist/css/loading.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"p1241\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.1.1/dist/css/listpanel.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"p1150\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.1.1/dist/bundled/theme/default.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"p1151\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.1.1/dist/bundled/theme/native.css\"}}],\"min_width\":700,\"margin\":0,\"sizing_mode\":\"stretch_width\",\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"Spacer\",\"id\":\"p1153\",\"attributes\":{\"name\":\"HSpacer01039\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"p1152\"},{\"id\":\"p1150\"},{\"id\":\"p1151\"}],\"margin\":0,\"sizing_mode\":\"stretch_width\",\"align\":\"start\"}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1157\",\"attributes\":{\"width\":700,\"height\":300,\"margin\":[5,10],\"sizing_mode\":\"fixed\",\"align\":\"start\",\"x_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"p1154\",\"attributes\":{\"tags\":[[[\"period\",\"period\",null],[\"Variable\",\"Variable\",null]]],\"factors\":[[\"2023-08-14\",\"notional_active_return\"],[\"2023-08-14\",\"selection\"],[\"2023-08-14\",\"interaction\"],[\"2023-08-14\",\"allocation\"],[\"2023-08-14\",\"active_return\"],[\"2023-08-15\",\"notional_active_return\"],[\"2023-08-15\",\"selection\"],[\"2023-08-15\",\"interaction\"],[\"2023-08-15\",\"allocation\"],[\"2023-08-15\",\"active_return\"],[\"2023-08-16\",\"notional_active_return\"],[\"2023-08-16\",\"selection\"],[\"2023-08-16\",\"interaction\"],[\"2023-08-16\",\"allocation\"],[\"2023-08-16\",\"active_return\"],[\"2023-08-17\",\"notional_active_return\"],[\"2023-08-17\",\"selection\"],[\"2023-08-17\",\"interaction\"],[\"2023-08-17\",\"allocation\"],[\"2023-08-17\",\"active_return\"],[\"2023-08-18\",\"notional_active_return\"],[\"2023-08-18\",\"selection\"],[\"2023-08-18\",\"interaction\"],[\"2023-08-18\",\"allocation\"],[\"2023-08-18\",\"active_return\"],[\"2023-08-21\",\"notional_active_return\"],[\"2023-08-21\",\"selection\"],[\"2023-08-21\",\"interaction\"],[\"2023-08-21\",\"allocation\"],[\"2023-08-21\",\"active_return\"],[\"2023-08-22\",\"notional_active_return\"],[\"2023-08-22\",\"selection\"],[\"2023-08-22\",\"interaction\"],[\"2023-08-22\",\"allocation\"],[\"2023-08-22\",\"active_return\"],[\"2023-08-23\",\"notional_active_return\"],[\"2023-08-23\",\"selection\"],[\"2023-08-23\",\"interaction\"],[\"2023-08-23\",\"allocation\"],[\"2023-08-23\",\"active_return\"],[\"2023-08-24\",\"notional_active_return\"],[\"2023-08-24\",\"selection\"],[\"2023-08-24\",\"interaction\"],[\"2023-08-24\",\"allocation\"],[\"2023-08-24\",\"active_return\"],[\"2023-08-25\",\"notional_active_return\"],[\"2023-08-25\",\"selection\"],[\"2023-08-25\",\"interaction\"],[\"2023-08-25\",\"allocation\"],[\"2023-08-25\",\"active_return\"],[\"2023-08-28\",\"notional_active_return\"],[\"2023-08-28\",\"selection\"],[\"2023-08-28\",\"interaction\"],[\"2023-08-28\",\"allocation\"],[\"2023-08-28\",\"active_return\"],[\"2023-08-29\",\"notional_active_return\"],[\"2023-08-29\",\"selection\"],[\"2023-08-29\",\"interaction\"],[\"2023-08-29\",\"allocation\"],[\"2023-08-29\",\"active_return\"]]}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p1155\",\"attributes\":{\"tags\":[[[\"value\",\"value\",null]]],\"start\":-0.038496781602345674,\"end\":0.03280656468119388,\"reset_start\":-0.038496781602345674,\"reset_end\":0.03280656468119388}},\"x_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"p1169\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1171\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1160\",\"attributes\":{\"text_color\":\"black\",\"text_font_size\":\"12pt\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1211\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1201\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1202\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1203\"},\"data\":{\"type\":\"map\",\"entries\":[[\"xoffsets\",[[\"2023-08-14\",\"active_return\"],[\"2023-08-15\",\"active_return\"],[\"2023-08-16\",\"active_return\"],[\"2023-08-17\",\"active_return\"],[\"2023-08-18\",\"active_return\"],[\"2023-08-21\",\"active_return\"],[\"2023-08-22\",\"active_return\"],[\"2023-08-23\",\"active_return\"],[\"2023-08-24\",\"active_return\"],[\"2023-08-25\",\"active_return\"],[\"2023-08-28\",\"active_return\"],[\"2023-08-29\",\"active_return\"],[\"2023-08-14\",\"allocation\"],[\"2023-08-15\",\"allocation\"],[\"2023-08-16\",\"allocation\"],[\"2023-08-17\",\"allocation\"],[\"2023-08-18\",\"allocation\"],[\"2023-08-21\",\"allocation\"],[\"2023-08-22\",\"allocation\"],[\"2023-08-23\",\"allocation\"],[\"2023-08-24\",\"allocation\"],[\"2023-08-25\",\"allocation\"],[\"2023-08-28\",\"allocation\"],[\"2023-08-29\",\"allocation\"],[\"2023-08-14\",\"interaction\"],[\"2023-08-15\",\"interaction\"],[\"2023-08-16\",\"interaction\"],[\"2023-08-17\",\"interaction\"],[\"2023-08-18\",\"interaction\"],[\"2023-08-21\",\"interaction\"],[\"2023-08-22\",\"interaction\"],[\"2023-08-23\",\"interaction\"],[\"2023-08-24\",\"interaction\"],[\"2023-08-25\",\"interaction\"],[\"2023-08-28\",\"interaction\"],[\"2023-08-29\",\"interaction\"],[\"2023-08-14\",\"selection\"],[\"2023-08-15\",\"selection\"],[\"2023-08-16\",\"selection\"],[\"2023-08-17\",\"selection\"],[\"2023-08-18\",\"selection\"],[\"2023-08-21\",\"selection\"],[\"2023-08-22\",\"selection\"],[\"2023-08-23\",\"selection\"],[\"2023-08-24\",\"selection\"],[\"2023-08-25\",\"selection\"],[\"2023-08-28\",\"selection\"],[\"2023-08-29\",\"selection\"],[\"2023-08-14\",\"notional_active_return\"],[\"2023-08-15\",\"notional_active_return\"],[\"2023-08-16\",\"notional_active_return\"],[\"2023-08-17\",\"notional_active_return\"],[\"2023-08-18\",\"notional_active_return\"],[\"2023-08-21\",\"notional_active_return\"],[\"2023-08-22\",\"notional_active_return\"],[\"2023-08-23\",\"notional_active_return\"],[\"2023-08-24\",\"notional_active_return\"],[\"2023-08-25\",\"notional_active_return\"],[\"2023-08-28\",\"notional_active_return\"],[\"2023-08-29\",\"notional_active_return\"]]],[\"value\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAACSdCUE2bmFP3iNNqu+pYE/OSn4FAn+gD/MxAlqBS5VP/EgqTPbb30/0vNefbyUbj+31cHIge+RP9S99ozbYn0/G5BXlT34fj8Vjs8HzTGSvyo0QxpwQJK/AAAAAAAAAABza22o1z+IP6dNJlePK4A/4UGVEQRyar81d4M+I+SRP0CLg/lztoE/HHfxBthpcT+oziSlOt2TPywP6a3443C/DWZJd1aniT+qHEItiBqHv+qiiBZr4Za/AAAAAAAAAACoKW1MOLt+v6obLAbAYn2/v/3qxyjtkj9lyJEIB6ugv0owVeBZk4q/AmEDeK10cj+Yx4eB88qVvxZuZHRmlY8/B4LzEUfpkb9VOsqV7KJzP6oRzhJmgps/AAAAAAAAAADkO90DO695P6dNJlePK4A/nAPx7I5/fL/itUApy8SQP4M1poDTlIc/NV5FQCeUdL+oziSlOt2TPywP6a3443C/DWZJd1aniT+qHEItiBqHv+qiiBZr4Za/AAAAAAAAAACSdCUE2bmFP3iNNqu+pYE/OSn4FAn+gD/MxAlqBS5VP/EgqTPbb30/0vNefbyUbj+31cHIge+RP9S99ozbYn0/G5BXlT34fj8Vjs8HzTGSvyo0QxpwQJK/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"period\",[\"2023-08-14\",\"2023-08-15\",\"2023-08-16\",\"2023-08-17\",\"2023-08-18\",\"2023-08-21\",\"2023-08-22\",\"2023-08-23\",\"2023-08-24\",\"2023-08-25\",\"2023-08-28\",\"2023-08-29\",\"2023-08-14\",\"2023-08-15\",\"2023-08-16\",\"2023-08-17\",\"2023-08-18\",\"2023-08-21\",\"2023-08-22\",\"2023-08-23\",\"2023-08-24\",\"2023-08-25\",\"2023-08-28\",\"2023-08-29\",\"2023-08-14\",\"2023-08-15\",\"2023-08-16\",\"2023-08-17\",\"2023-08-18\",\"2023-08-21\",\"2023-08-22\",\"2023-08-23\",\"2023-08-24\",\"2023-08-25\",\"2023-08-28\",\"2023-08-29\",\"2023-08-14\",\"2023-08-15\",\"2023-08-16\",\"2023-08-17\",\"2023-08-18\",\"2023-08-21\",\"2023-08-22\",\"2023-08-23\",\"2023-08-24\",\"2023-08-25\",\"2023-08-28\",\"2023-08-29\",\"2023-08-14\",\"2023-08-15\",\"2023-08-16\",\"2023-08-17\",\"2023-08-18\",\"2023-08-21\",\"2023-08-22\",\"2023-08-23\",\"2023-08-24\",\"2023-08-25\",\"2023-08-28\",\"2023-08-29\"]],[\"Variable\",[\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"active_return\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"allocation\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"interaction\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"selection\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\",\"notional_active_return\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1212\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1213\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p1208\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"xoffsets\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"value\"},\"fill_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"type\":\"object\",\"name\":\"CategoricalColorMapper\",\"id\":\"p1200\",\"attributes\":{\"palette\":[\"#30a2da\",\"#fc4f30\",\"#e5ae38\",\"#6d904f\",\"#8b8b8b\"],\"factors\":[\"active_return\",\"allocation\",\"interaction\",\"selection\",\"notional_active_return\"]}}},\"hatch_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p1214\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"xoffsets\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"value\"},\"line_color\":{\"type\":\"value\",\"value\":\"black\"},\"line_alpha\":{\"type\":\"value\",\"value\":1.0},\"line_width\":{\"type\":\"value\",\"value\":1},\"line_join\":{\"type\":\"value\",\"value\":\"bevel\"},\"line_cap\":{\"type\":\"value\",\"value\":\"butt\"},\"line_dash\":{\"type\":\"value\",\"value\":[]},\"line_dash_offset\":{\"type\":\"value\",\"value\":0},\"fill_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"fill_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"hatch_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_scale\":{\"type\":\"value\",\"value\":12.0},\"hatch_pattern\":{\"type\":\"value\",\"value\":null},\"hatch_weight\":{\"type\":\"value\",\"value\":1.0}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p1209\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"xoffsets\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"value\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p1210\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"xoffsets\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"value\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"field\",\"field\":\"Variable\",\"transform\":{\"id\":\"p1200\"}},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1162\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"HoverTool\",\"id\":\"p1156\",\"attributes\":{\"tags\":[\"hv_created\"],\"renderers\":[{\"id\":\"p1211\"}],\"tooltips\":[[\"period\",\"@{period}\"],[\"Variable\",\"@{Variable}\"],[\"value\",\"@{value}\"]]}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1186\"},{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1187\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1188\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1189\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1190\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1191\"}],\"active_drag\":{\"id\":\"p1187\"},\"active_scroll\":{\"id\":\"p1188\"}}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1179\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1182\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1181\"},\"axis_label\":\"\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1180\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"p1173\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"p1176\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"p1175\"},\"axis_label\":\"period, Variable\",\"major_label_orientation\":0.7853981633974483,\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1174\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1178\",\"attributes\":{\"axis\":{\"id\":\"p1173\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1185\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1179\"},\"grid_line_color\":null}}],\"min_border_top\":10,\"min_border_bottom\":10,\"min_border_left\":10,\"min_border_right\":10,\"output_backend\":\"webgl\"}},{\"type\":\"object\",\"name\":\"Spacer\",\"id\":\"p1239\",\"attributes\":{\"name\":\"HSpacer01042\",\"stylesheets\":[\"\\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\\n background-image: url(\\\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\\\");\\n background-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"p1152\"},{\"id\":\"p1150\"},{\"id\":\"p1151\"}],\"margin\":0,\"sizing_mode\":\"stretch_width\",\"align\":\"start\"}}]}}],\"callbacks\":{\"type\":\"map\"}}};\n",
|
185 |
-
" var render_items = [{\"docid\":\"9024d76f-8d10-4a0a-8327-1e46e4bcf29d\",\"roots\":{\"p1149\":\"ad7e920f-cf41-4c46-8ae3-2357eee49c67\"},\"root_ids\":[\"p1149\"]}];\n",
|
186 |
-
" var docs = Object.values(docs_json)\n",
|
187 |
-
" if (!docs) {\n",
|
188 |
-
" return\n",
|
189 |
-
" }\n",
|
190 |
-
" const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
|
191 |
-
" const is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1\n",
|
192 |
-
" function embed_document(root) {\n",
|
193 |
-
" var Bokeh = get_bokeh(root)\n",
|
194 |
-
" Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
|
195 |
-
" for (const render_item of render_items) {\n",
|
196 |
-
" for (const root_id of render_item.root_ids) {\n",
|
197 |
-
"\tconst id_el = document.getElementById(root_id)\n",
|
198 |
-
"\tif (id_el.children.length && (id_el.children[0].className === 'bk-root')) {\n",
|
199 |
-
"\t const root_el = id_el.children[0]\n",
|
200 |
-
"\t root_el.id = root_el.id + '-rendered'\n",
|
201 |
-
"\t}\n",
|
202 |
-
" }\n",
|
203 |
-
" }\n",
|
204 |
-
" }\n",
|
205 |
-
" function get_bokeh(root) {\n",
|
206 |
-
" if (root.Bokeh === undefined) {\n",
|
207 |
-
" return null\n",
|
208 |
-
" } else if (root.Bokeh.version !== py_version && !is_dev) {\n",
|
209 |
-
" if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
|
210 |
-
"\treturn null\n",
|
211 |
-
" }\n",
|
212 |
-
" return root.Bokeh.versions.get(py_version);\n",
|
213 |
-
" } else if (root.Bokeh.version === py_version) {\n",
|
214 |
-
" return root.Bokeh\n",
|
215 |
-
" }\n",
|
216 |
-
" return null\n",
|
217 |
-
" }\n",
|
218 |
-
" function is_loaded(root) {\n",
|
219 |
-
" var Bokeh = get_bokeh(root)\n",
|
220 |
-
" return (Bokeh != null && Bokeh.Panel !== undefined)\n",
|
221 |
-
" }\n",
|
222 |
-
" if (is_loaded(root)) {\n",
|
223 |
-
" embed_document(root);\n",
|
224 |
-
" } else {\n",
|
225 |
-
" var attempts = 0;\n",
|
226 |
-
" var timer = setInterval(function(root) {\n",
|
227 |
-
" if (is_loaded(root)) {\n",
|
228 |
-
" clearInterval(timer);\n",
|
229 |
-
" embed_document(root);\n",
|
230 |
-
" } else if (document.readyState == \"complete\") {\n",
|
231 |
-
" attempts++;\n",
|
232 |
-
" if (attempts > 200) {\n",
|
233 |
-
" clearInterval(timer);\n",
|
234 |
-
"\t var Bokeh = get_bokeh(root)\n",
|
235 |
-
"\t if (Bokeh == null || Bokeh.Panel == null) {\n",
|
236 |
-
" console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
|
237 |
-
"\t } else {\n",
|
238 |
-
"\t console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
|
239 |
-
"\t embed_document(root)\n",
|
240 |
-
"\t }\n",
|
241 |
-
" }\n",
|
242 |
-
" }\n",
|
243 |
-
" }, 25, root)\n",
|
244 |
-
" }\n",
|
245 |
-
"})(window);</script>"
|
246 |
-
],
|
247 |
-
"text/plain": [
|
248 |
-
":Bars [period,Variable] (value)"
|
249 |
-
]
|
250 |
-
},
|
251 |
-
"execution_count": 20,
|
252 |
-
"metadata": {
|
253 |
-
"application/vnd.holoviews_exec.v0+json": {
|
254 |
-
"id": "p1149"
|
255 |
-
}
|
256 |
-
},
|
257 |
-
"output_type": "execute_result"
|
258 |
-
}
|
259 |
-
],
|
260 |
-
"source": [
|
261 |
-
"agg_b = processing.aggregate_analytic_df_by_period(analytic_b, 'D')\n",
|
262 |
-
"agg_p = processing.aggregate_analytic_df_by_period(analytic_p, 'D')\n",
|
263 |
-
"bhb_result = processing.calculate_periodic_BHB(agg_b, agg_p)\n",
|
264 |
-
"agg_bhb_result = processing.aggregate_bhb_df(bhb_result)\n",
|
265 |
-
"agg_bhb_result.hvplot.bar(\n",
|
266 |
-
" y=['active_return','allocation',\n",
|
267 |
-
" 'interaction','selection',\n",
|
268 |
-
" 'notional_active_return'],rot=45,legend='top')"
|
269 |
-
]
|
270 |
-
},
|
271 |
-
{
|
272 |
-
"cell_type": "code",
|
273 |
-
"execution_count": 131,
|
274 |
-
"metadata": {},
|
275 |
-
"outputs": [],
|
276 |
-
"source": [
|
277 |
-
"agg_bhb_result['period_str'] = agg_bhb_result.index.map(lambda x: str(x))"
|
278 |
-
]
|
279 |
-
},
|
280 |
-
{
|
281 |
-
"cell_type": "code",
|
282 |
-
"execution_count": 132,
|
283 |
-
"metadata": {},
|
284 |
-
"outputs": [
|
285 |
-
{
|
286 |
-
"data": {
|
287 |
-
"text/html": [
|
288 |
-
"<div>\n",
|
289 |
-
"<style scoped>\n",
|
290 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
291 |
-
" vertical-align: middle;\n",
|
292 |
-
" }\n",
|
293 |
-
"\n",
|
294 |
-
" .dataframe tbody tr th {\n",
|
295 |
-
" vertical-align: top;\n",
|
296 |
-
" }\n",
|
297 |
-
"\n",
|
298 |
-
" .dataframe thead th {\n",
|
299 |
-
" text-align: right;\n",
|
300 |
-
" }\n",
|
301 |
-
"</style>\n",
|
302 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
303 |
-
" <thead>\n",
|
304 |
-
" <tr style=\"text-align: right;\">\n",
|
305 |
-
" <th></th>\n",
|
306 |
-
" <th>active_return</th>\n",
|
307 |
-
" <th>allocation</th>\n",
|
308 |
-
" <th>interaction</th>\n",
|
309 |
-
" <th>selection</th>\n",
|
310 |
-
" <th>notional_active_return</th>\n",
|
311 |
-
" <th>period_str</th>\n",
|
312 |
-
" </tr>\n",
|
313 |
-
" <tr>\n",
|
314 |
-
" <th>period</th>\n",
|
315 |
-
" <th></th>\n",
|
316 |
-
" <th></th>\n",
|
317 |
-
" <th></th>\n",
|
318 |
-
" <th></th>\n",
|
319 |
-
" <th></th>\n",
|
320 |
-
" <th></th>\n",
|
321 |
-
" </tr>\n",
|
322 |
-
" </thead>\n",
|
323 |
-
" <tbody>\n",
|
324 |
-
" <tr>\n",
|
325 |
-
" <th>2023-08-08/2023-08-14</th>\n",
|
326 |
-
" <td>0.000000</td>\n",
|
327 |
-
" <td>0.000000</td>\n",
|
328 |
-
" <td>0.000000</td>\n",
|
329 |
-
" <td>0.00000</td>\n",
|
330 |
-
" <td>0.000000</td>\n",
|
331 |
-
" <td>2023-08-08/2023-08-14</td>\n",
|
332 |
-
" </tr>\n",
|
333 |
-
" <tr>\n",
|
334 |
-
" <th>2023-08-15/2023-08-21</th>\n",
|
335 |
-
" <td>0.043550</td>\n",
|
336 |
-
" <td>0.043253</td>\n",
|
337 |
-
" <td>-0.028373</td>\n",
|
338 |
-
" <td>0.02867</td>\n",
|
339 |
-
" <td>0.043550</td>\n",
|
340 |
-
" <td>2023-08-15/2023-08-21</td>\n",
|
341 |
-
" </tr>\n",
|
342 |
-
" <tr>\n",
|
343 |
-
" <th>2023-08-22/2023-08-28</th>\n",
|
344 |
-
" <td>0.014808</td>\n",
|
345 |
-
" <td>0.015379</td>\n",
|
346 |
-
" <td>-0.017291</td>\n",
|
347 |
-
" <td>0.01672</td>\n",
|
348 |
-
" <td>0.014808</td>\n",
|
349 |
-
" <td>2023-08-22/2023-08-28</td>\n",
|
350 |
-
" </tr>\n",
|
351 |
-
" <tr>\n",
|
352 |
-
" <th>2023-08-29/2023-09-04</th>\n",
|
353 |
-
" <td>0.000000</td>\n",
|
354 |
-
" <td>0.000000</td>\n",
|
355 |
-
" <td>0.000000</td>\n",
|
356 |
-
" <td>0.00000</td>\n",
|
357 |
-
" <td>0.000000</td>\n",
|
358 |
-
" <td>2023-08-29/2023-09-04</td>\n",
|
359 |
-
" </tr>\n",
|
360 |
-
" </tbody>\n",
|
361 |
-
"</table>\n",
|
362 |
-
"</div>"
|
363 |
-
],
|
364 |
-
"text/plain": [
|
365 |
-
" active_return allocation interaction selection \\\n",
|
366 |
-
"period \n",
|
367 |
-
"2023-08-08/2023-08-14 0.000000 0.000000 0.000000 0.00000 \n",
|
368 |
-
"2023-08-15/2023-08-21 0.043550 0.043253 -0.028373 0.02867 \n",
|
369 |
-
"2023-08-22/2023-08-28 0.014808 0.015379 -0.017291 0.01672 \n",
|
370 |
-
"2023-08-29/2023-09-04 0.000000 0.000000 0.000000 0.00000 \n",
|
371 |
-
"\n",
|
372 |
-
" notional_active_return period_str \n",
|
373 |
-
"period \n",
|
374 |
-
"2023-08-08/2023-08-14 0.000000 2023-08-08/2023-08-14 \n",
|
375 |
-
"2023-08-15/2023-08-21 0.043550 2023-08-15/2023-08-21 \n",
|
376 |
-
"2023-08-22/2023-08-28 0.014808 2023-08-22/2023-08-28 \n",
|
377 |
-
"2023-08-29/2023-09-04 0.000000 2023-08-29/2023-09-04 "
|
378 |
-
]
|
379 |
-
},
|
380 |
-
"execution_count": 132,
|
381 |
-
"metadata": {},
|
382 |
-
"output_type": "execute_result"
|
383 |
-
}
|
384 |
-
],
|
385 |
-
"source": [
|
386 |
-
"agg_bhb_result"
|
387 |
-
]
|
388 |
-
},
|
389 |
-
{
|
390 |
-
"cell_type": "code",
|
391 |
-
"execution_count": 133,
|
392 |
-
"metadata": {},
|
393 |
-
"outputs": [
|
394 |
-
{
|
395 |
-
"data": {
|
396 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = true;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'plotly': 'https://cdn.plot.ly/plotly-2.18.0.min', 'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"plotly\"], function(Plotly) {\n\twindow.Plotly = Plotly\n\ton_load()\n })\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 10;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['Plotly'] !== undefined) && (!(window['Plotly'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/plotlyplot/plotly-2.18.0.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/1.1.1/dist/bundled/jquery/jquery.slim.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/bundled/plotlyplot/plotly-2.18.0.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
397 |
-
"application/vnd.holoviews_load.v0+json": ""
|
398 |
-
},
|
399 |
-
"metadata": {},
|
400 |
-
"output_type": "display_data"
|
401 |
-
},
|
402 |
-
{
|
403 |
-
"data": {
|
404 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
405 |
-
"application/vnd.holoviews_load.v0+json": ""
|
406 |
-
},
|
407 |
-
"metadata": {},
|
408 |
-
"output_type": "display_data"
|
409 |
-
},
|
410 |
-
{
|
411 |
-
"data": {
|
412 |
-
"text/html": [
|
413 |
-
"<style>*[data-root-id],\n",
|
414 |
-
"*[data-root-id] > * {\n",
|
415 |
-
" box-sizing: border-box;\n",
|
416 |
-
" font-family: var(--jp-ui-font-family);\n",
|
417 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
418 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
419 |
-
"}\n",
|
420 |
-
"\n",
|
421 |
-
"/* Override VSCode background color */\n",
|
422 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
423 |
-
" > .lm-Widget\n",
|
424 |
-
" > *[data-root-id]),\n",
|
425 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
426 |
-
" background-color: transparent !important;\n",
|
427 |
-
"}\n",
|
428 |
-
"</style>"
|
429 |
-
]
|
430 |
-
},
|
431 |
-
"metadata": {},
|
432 |
-
"output_type": "display_data"
|
433 |
-
},
|
434 |
-
{
|
435 |
-
"data": {
|
436 |
-
"application/vnd.jupyter.widget-view+json": {
|
437 |
-
"model_id": "49cd388784a7420f8243cbcf76d1cd8b",
|
438 |
-
"version_major": 2,
|
439 |
-
"version_minor": 0
|
440 |
-
},
|
441 |
-
"text/plain": [
|
442 |
-
"BokehModel(combine_events=True, render_bundle={'docs_json': {'fba37937-2449-4574-bb28-cb6a96c8cbc3': {'version…"
|
443 |
-
]
|
444 |
-
},
|
445 |
-
"execution_count": 133,
|
446 |
-
"metadata": {},
|
447 |
-
"output_type": "execute_result"
|
448 |
-
}
|
449 |
-
],
|
450 |
-
"source": [
|
451 |
-
"import plotly.express as px\n",
|
452 |
-
"import panel as pn\n",
|
453 |
-
"pn.extension('plotly')\n",
|
454 |
-
"fig = px.bar(agg_bhb_result,x='period_str',y=[\n",
|
455 |
-
" 'allocation', 'selection', 'interaction', 'notional_active_return', 'active_return'])\n",
|
456 |
-
"pn.pane.Plotly(fig)"
|
457 |
-
]
|
458 |
-
},
|
459 |
-
{
|
460 |
-
"cell_type": "code",
|
461 |
-
"execution_count": null,
|
462 |
-
"metadata": {},
|
463 |
-
"outputs": [],
|
464 |
-
"source": [
|
465 |
-
"bhb_result"
|
466 |
-
]
|
467 |
-
},
|
468 |
-
{
|
469 |
-
"cell_type": "code",
|
470 |
-
"execution_count": null,
|
471 |
-
"metadata": {},
|
472 |
-
"outputs": [
|
473 |
-
{
|
474 |
-
"data": {
|
475 |
-
"text/html": [
|
476 |
-
"<div>\n",
|
477 |
-
"<style scoped>\n",
|
478 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
479 |
-
" vertical-align: middle;\n",
|
480 |
-
" }\n",
|
481 |
-
"\n",
|
482 |
-
" .dataframe tbody tr th {\n",
|
483 |
-
" vertical-align: top;\n",
|
484 |
-
" }\n",
|
485 |
-
"\n",
|
486 |
-
" .dataframe thead th {\n",
|
487 |
-
" text-align: right;\n",
|
488 |
-
" }\n",
|
489 |
-
"</style>\n",
|
490 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
491 |
-
" <thead>\n",
|
492 |
-
" <tr style=\"text-align: right;\">\n",
|
493 |
-
" <th></th>\n",
|
494 |
-
" <th>time</th>\n",
|
495 |
-
" <th>ticker</th>\n",
|
496 |
-
" <th>open</th>\n",
|
497 |
-
" <th>close</th>\n",
|
498 |
-
" <th>high</th>\n",
|
499 |
-
" <th>low</th>\n",
|
500 |
-
" <th>volume</th>\n",
|
501 |
-
" <th>money</th>\n",
|
502 |
-
" <th>shares</th>\n",
|
503 |
-
" <th>sector</th>\n",
|
504 |
-
" <th>aggregate_sector</th>\n",
|
505 |
-
" <th>display_name</th>\n",
|
506 |
-
" <th>name</th>\n",
|
507 |
-
" <th>cash</th>\n",
|
508 |
-
" <th>ini_w</th>\n",
|
509 |
-
" <th>ave_price</th>\n",
|
510 |
-
" <th>weight</th>\n",
|
511 |
-
" <th>pct</th>\n",
|
512 |
-
" <th>norm_pct</th>\n",
|
513 |
-
" <th>return</th>\n",
|
514 |
-
" </tr>\n",
|
515 |
-
" </thead>\n",
|
516 |
-
" <tbody>\n",
|
517 |
-
" </tbody>\n",
|
518 |
-
"</table>\n",
|
519 |
-
"</div>"
|
520 |
-
],
|
521 |
-
"text/plain": [
|
522 |
-
"Empty DataFrame\n",
|
523 |
-
"Columns: [time, ticker, open, close, high, low, volume, money, shares, sector, aggregate_sector, display_name, name, cash, ini_w, ave_price, weight, pct, norm_pct, return]\n",
|
524 |
-
"Index: []"
|
525 |
-
]
|
526 |
-
},
|
527 |
-
"execution_count": 11,
|
528 |
-
"metadata": {},
|
529 |
-
"output_type": "execute_result"
|
530 |
-
}
|
531 |
-
],
|
532 |
-
"source": [
|
533 |
-
"# check if there a row with same ticker and time\n",
|
534 |
-
"analytic_b[analytic_b.duplicated(['ticker', 'time'])]\n",
|
535 |
-
"analytic_p[analytic_p.duplicated(['ticker', 'time'])]"
|
536 |
-
]
|
537 |
-
}
|
538 |
-
],
|
539 |
-
"metadata": {
|
540 |
-
"kernelspec": {
|
541 |
-
"display_name": "risk-dashboard",
|
542 |
-
"language": "python",
|
543 |
-
"name": "python3"
|
544 |
-
},
|
545 |
-
"language_info": {
|
546 |
-
"codemirror_mode": {
|
547 |
-
"name": "ipython",
|
548 |
-
"version": 3
|
549 |
-
},
|
550 |
-
"file_extension": ".py",
|
551 |
-
"mimetype": "text/x-python",
|
552 |
-
"name": "python",
|
553 |
-
"nbconvert_exporter": "python",
|
554 |
-
"pygments_lexer": "ipython3",
|
555 |
-
"version": "3.11.4"
|
556 |
-
},
|
557 |
-
"orig_nbformat": 4
|
558 |
-
},
|
559 |
-
"nbformat": 4,
|
560 |
-
"nbformat_minor": 2
|
561 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
total_return.ipynb
DELETED
@@ -1,713 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"data": {
|
10 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.1.1/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
11 |
-
"application/vnd.holoviews_load.v0+json": ""
|
12 |
-
},
|
13 |
-
"metadata": {},
|
14 |
-
"output_type": "display_data"
|
15 |
-
},
|
16 |
-
{
|
17 |
-
"data": {
|
18 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
19 |
-
"application/vnd.holoviews_load.v0+json": ""
|
20 |
-
},
|
21 |
-
"metadata": {},
|
22 |
-
"output_type": "display_data"
|
23 |
-
},
|
24 |
-
{
|
25 |
-
"data": {
|
26 |
-
"text/html": [
|
27 |
-
"<style>*[data-root-id],\n",
|
28 |
-
"*[data-root-id] > * {\n",
|
29 |
-
" box-sizing: border-box;\n",
|
30 |
-
" font-family: var(--jp-ui-font-family);\n",
|
31 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
32 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
33 |
-
"}\n",
|
34 |
-
"\n",
|
35 |
-
"/* Override VSCode background color */\n",
|
36 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
37 |
-
" > .lm-Widget\n",
|
38 |
-
" > *[data-root-id]),\n",
|
39 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
40 |
-
" background-color: transparent !important;\n",
|
41 |
-
"}\n",
|
42 |
-
"</style>"
|
43 |
-
]
|
44 |
-
},
|
45 |
-
"metadata": {},
|
46 |
-
"output_type": "display_data"
|
47 |
-
},
|
48 |
-
{
|
49 |
-
"data": {
|
50 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = true;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
51 |
-
"application/vnd.holoviews_load.v0+json": ""
|
52 |
-
},
|
53 |
-
"metadata": {},
|
54 |
-
"output_type": "display_data"
|
55 |
-
},
|
56 |
-
{
|
57 |
-
"data": {
|
58 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
59 |
-
"application/vnd.holoviews_load.v0+json": ""
|
60 |
-
},
|
61 |
-
"metadata": {},
|
62 |
-
"output_type": "display_data"
|
63 |
-
},
|
64 |
-
{
|
65 |
-
"data": {
|
66 |
-
"text/html": [
|
67 |
-
"<style>*[data-root-id],\n",
|
68 |
-
"*[data-root-id] > * {\n",
|
69 |
-
" box-sizing: border-box;\n",
|
70 |
-
" font-family: var(--jp-ui-font-family);\n",
|
71 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
72 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
73 |
-
"}\n",
|
74 |
-
"\n",
|
75 |
-
"/* Override VSCode background color */\n",
|
76 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
77 |
-
" > .lm-Widget\n",
|
78 |
-
" > *[data-root-id]),\n",
|
79 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
80 |
-
" background-color: transparent !important;\n",
|
81 |
-
"}\n",
|
82 |
-
"</style>"
|
83 |
-
]
|
84 |
-
},
|
85 |
-
"metadata": {},
|
86 |
-
"output_type": "display_data"
|
87 |
-
},
|
88 |
-
{
|
89 |
-
"data": {
|
90 |
-
"application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = true;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'mathjax': '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML', 'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'mathjax': {'exports': 'MathJax'}, 'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"mathjax\"], function() {\n\ton_load()\n })\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 10;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['MathJax'] !== undefined) && (!(window['MathJax'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.1.1/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.1.1/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));",
|
91 |
-
"application/vnd.holoviews_load.v0+json": ""
|
92 |
-
},
|
93 |
-
"metadata": {},
|
94 |
-
"output_type": "display_data"
|
95 |
-
},
|
96 |
-
{
|
97 |
-
"data": {
|
98 |
-
"application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n",
|
99 |
-
"application/vnd.holoviews_load.v0+json": ""
|
100 |
-
},
|
101 |
-
"metadata": {},
|
102 |
-
"output_type": "display_data"
|
103 |
-
},
|
104 |
-
{
|
105 |
-
"data": {
|
106 |
-
"text/html": [
|
107 |
-
"<style>*[data-root-id],\n",
|
108 |
-
"*[data-root-id] > * {\n",
|
109 |
-
" box-sizing: border-box;\n",
|
110 |
-
" font-family: var(--jp-ui-font-family);\n",
|
111 |
-
" font-size: var(--jp-ui-font-size1);\n",
|
112 |
-
" color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
|
113 |
-
"}\n",
|
114 |
-
"\n",
|
115 |
-
"/* Override VSCode background color */\n",
|
116 |
-
".cell-output-ipywidget-background:has(> .cell-output-ipywidget-background\n",
|
117 |
-
" > .lm-Widget\n",
|
118 |
-
" > *[data-root-id]),\n",
|
119 |
-
".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
|
120 |
-
" background-color: transparent !important;\n",
|
121 |
-
"}\n",
|
122 |
-
"</style>"
|
123 |
-
]
|
124 |
-
},
|
125 |
-
"metadata": {},
|
126 |
-
"output_type": "display_data"
|
127 |
-
}
|
128 |
-
],
|
129 |
-
"source": [
|
130 |
-
"import panel as pn\n",
|
131 |
-
"import pandas as pd\n",
|
132 |
-
"import scipy.stats as stats\n",
|
133 |
-
"from sqlalchemy import create_engine\n",
|
134 |
-
"import hvplot.pandas\n",
|
135 |
-
"from datetime import datetime, timedelta\n",
|
136 |
-
"from script import processing\n",
|
137 |
-
"import numpy as np\n",
|
138 |
-
"pn.extension()\n",
|
139 |
-
"db_url = 'sqlite:///instance/local.db'\n",
|
140 |
-
"engine = create_engine(db_url)\n",
|
141 |
-
"import plotly.express as px\n",
|
142 |
-
"pn.extension('mathjax')"
|
143 |
-
]
|
144 |
-
},
|
145 |
-
{
|
146 |
-
"cell_type": "code",
|
147 |
-
"execution_count": 2,
|
148 |
-
"metadata": {},
|
149 |
-
"outputs": [],
|
150 |
-
"source": [
|
151 |
-
"%load_ext autoreload\n",
|
152 |
-
"%autoreload 2"
|
153 |
-
]
|
154 |
-
},
|
155 |
-
{
|
156 |
-
"cell_type": "code",
|
157 |
-
"execution_count": 3,
|
158 |
-
"metadata": {},
|
159 |
-
"outputs": [],
|
160 |
-
"source": [
|
161 |
-
"p_eval_df = None\n",
|
162 |
-
"calculated_b_stock = None\n",
|
163 |
-
"calculated_p_stock = None\n",
|
164 |
-
"# load benchmark stock\n",
|
165 |
-
"with engine.connect() as connection:\n",
|
166 |
-
" calculated_b_stock = pd.read_sql('calculated_b_stock', con=connection)\n",
|
167 |
-
" calculated_p_stock = pd.read_sql('calculated_p_stock', con=connection)\n",
|
168 |
-
" p_eval_df = pd.read_sql('p_eval_result', con=connection)"
|
169 |
-
]
|
170 |
-
},
|
171 |
-
{
|
172 |
-
"cell_type": "code",
|
173 |
-
"execution_count": 139,
|
174 |
-
"metadata": {},
|
175 |
-
"outputs": [
|
176 |
-
{
|
177 |
-
"name": "stdout",
|
178 |
-
"output_type": "stream",
|
179 |
-
"text": [
|
180 |
-
"2023-06-29 00:00:00\n",
|
181 |
-
"interaction 0.012116\n",
|
182 |
-
"allocation 0.002211\n",
|
183 |
-
"selection -0.012116\n",
|
184 |
-
"active_return 0.002211\n",
|
185 |
-
"notional_return 0.002211\n",
|
186 |
-
"dtype: float64\n"
|
187 |
-
]
|
188 |
-
},
|
189 |
-
{
|
190 |
-
"data": {
|
191 |
-
"text/html": [
|
192 |
-
"<div>\n",
|
193 |
-
"<style scoped>\n",
|
194 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
195 |
-
" vertical-align: middle;\n",
|
196 |
-
" }\n",
|
197 |
-
"\n",
|
198 |
-
" .dataframe tbody tr th {\n",
|
199 |
-
" vertical-align: top;\n",
|
200 |
-
" }\n",
|
201 |
-
"\n",
|
202 |
-
" .dataframe thead th {\n",
|
203 |
-
" text-align: right;\n",
|
204 |
-
" }\n",
|
205 |
-
"</style>\n",
|
206 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
207 |
-
" <thead>\n",
|
208 |
-
" <tr style=\"text-align: right;\">\n",
|
209 |
-
" <th></th>\n",
|
210 |
-
" <th>date</th>\n",
|
211 |
-
" <th>portfolio_return_p</th>\n",
|
212 |
-
" <th>portfolio_pct_p</th>\n",
|
213 |
-
" <th>portfolio_return_b</th>\n",
|
214 |
-
" <th>portfolio_pct_b</th>\n",
|
215 |
-
" <th>mkt_cap</th>\n",
|
216 |
-
" <th>prev_mkt_cap</th>\n",
|
217 |
-
" <th>pnl</th>\n",
|
218 |
-
" <th>risk</th>\n",
|
219 |
-
" <th>active_return</th>\n",
|
220 |
-
" <th>tracking_error</th>\n",
|
221 |
-
" <th>cum_pnl</th>\n",
|
222 |
-
" <th>return_p</th>\n",
|
223 |
-
" <th>return_b</th>\n",
|
224 |
-
" </tr>\n",
|
225 |
-
" </thead>\n",
|
226 |
-
" <tbody>\n",
|
227 |
-
" <tr>\n",
|
228 |
-
" <th>600</th>\n",
|
229 |
-
" <td>2023-06-29</td>\n",
|
230 |
-
" <td>0.343213</td>\n",
|
231 |
-
" <td>0.006552</td>\n",
|
232 |
-
" <td>-0.017097</td>\n",
|
233 |
-
" <td>-0.000125</td>\n",
|
234 |
-
" <td>1219.334595</td>\n",
|
235 |
-
" <td>1211.396987</td>\n",
|
236 |
-
" <td>7.937608</td>\n",
|
237 |
-
" <td>0.309501</td>\n",
|
238 |
-
" <td>0.002785</td>\n",
|
239 |
-
" <td>0.218361</td>\n",
|
240 |
-
" <td>140.338486</td>\n",
|
241 |
-
" <td>0.014219</td>\n",
|
242 |
-
" <td>0.011434</td>\n",
|
243 |
-
" </tr>\n",
|
244 |
-
" </tbody>\n",
|
245 |
-
"</table>\n",
|
246 |
-
"</div>"
|
247 |
-
],
|
248 |
-
"text/plain": [
|
249 |
-
" date portfolio_return_p portfolio_pct_p portfolio_return_b \\\n",
|
250 |
-
"600 2023-06-29 0.343213 0.006552 -0.017097 \n",
|
251 |
-
"\n",
|
252 |
-
" portfolio_pct_b mkt_cap prev_mkt_cap pnl risk \\\n",
|
253 |
-
"600 -0.000125 1219.334595 1211.396987 7.937608 0.309501 \n",
|
254 |
-
"\n",
|
255 |
-
" active_return tracking_error cum_pnl return_p return_b \n",
|
256 |
-
"600 0.002785 0.218361 140.338486 0.014219 0.011434 "
|
257 |
-
]
|
258 |
-
},
|
259 |
-
"execution_count": 139,
|
260 |
-
"metadata": {},
|
261 |
-
"output_type": "execute_result"
|
262 |
-
}
|
263 |
-
],
|
264 |
-
"source": [
|
265 |
-
"## check why activate return and nominal return is not same \n",
|
266 |
-
"# start_date = p_eval_df['date'].min()\n",
|
267 |
-
"# start_date = datetime(2022, 12, 14)\n",
|
268 |
-
"start_date = datetime(2023,6,25)\n",
|
269 |
-
"end_date = p_eval_df['date'].max()\n",
|
270 |
-
"print(end_date)\n",
|
271 |
-
"ticker = \"601117.XSHG\"\n",
|
272 |
-
"attributes_df = processing.calculate_attributes_between_dates(\n",
|
273 |
-
" start_date, end_date, calculated_b_stock=calculated_b_stock, calculated_p_stock=calculated_p_stock)\n",
|
274 |
-
"total_attributes = attributes_df.aggregate({\n",
|
275 |
-
" 'interaction': 'sum',\n",
|
276 |
-
" 'allocation': 'sum',\n",
|
277 |
-
" 'selection': 'sum',\n",
|
278 |
-
" 'active_return': 'sum',\n",
|
279 |
-
" 'notional_return': 'sum'\n",
|
280 |
-
" }) \n",
|
281 |
-
"# print(attributes_df.columns)\n",
|
282 |
-
"print(total_attributes)\n",
|
283 |
-
"return_df = processing.calculate_return(p_eval_df, start_date, end_date)\n",
|
284 |
-
"return_df\n",
|
285 |
-
"most_recent_row = return_df.tail(1)\n",
|
286 |
-
"# print(return_df.head(1))\n",
|
287 |
-
"most_recent_row\n",
|
288 |
-
"\n",
|
289 |
-
"\n"
|
290 |
-
]
|
291 |
-
},
|
292 |
-
{
|
293 |
-
"cell_type": "code",
|
294 |
-
"execution_count": 124,
|
295 |
-
"metadata": {},
|
296 |
-
"outputs": [
|
297 |
-
{
|
298 |
-
"data": {
|
299 |
-
"text/plain": [
|
300 |
-
"1219.334714348576"
|
301 |
-
]
|
302 |
-
},
|
303 |
-
"execution_count": 124,
|
304 |
-
"metadata": {},
|
305 |
-
"output_type": "execute_result"
|
306 |
-
}
|
307 |
-
],
|
308 |
-
"source": [
|
309 |
-
"1038.573137 * (1 + 0.174048)"
|
310 |
-
]
|
311 |
-
},
|
312 |
-
{
|
313 |
-
"cell_type": "code",
|
314 |
-
"execution_count": 137,
|
315 |
-
"metadata": {},
|
316 |
-
"outputs": [
|
317 |
-
{
|
318 |
-
"data": {
|
319 |
-
"text/plain": [
|
320 |
-
"0.01448137201285984"
|
321 |
-
]
|
322 |
-
},
|
323 |
-
"execution_count": 137,
|
324 |
-
"metadata": {},
|
325 |
-
"output_type": "execute_result"
|
326 |
-
}
|
327 |
-
],
|
328 |
-
"source": [
|
329 |
-
"# portfolio return\n",
|
330 |
-
"attributes_df['w_return_p'] = attributes_df.pct_p * attributes_df.prev_w_in_p_p\n",
|
331 |
-
"attributes_df.w_return_p.sum()"
|
332 |
-
]
|
333 |
-
},
|
334 |
-
{
|
335 |
-
"cell_type": "code",
|
336 |
-
"execution_count": 129,
|
337 |
-
"metadata": {},
|
338 |
-
"outputs": [
|
339 |
-
{
|
340 |
-
"data": {
|
341 |
-
"text/plain": [
|
342 |
-
"0.09551009084622147"
|
343 |
-
]
|
344 |
-
},
|
345 |
-
"execution_count": 129,
|
346 |
-
"metadata": {},
|
347 |
-
"output_type": "execute_result"
|
348 |
-
}
|
349 |
-
],
|
350 |
-
"source": [
|
351 |
-
"0.17190200433908703 - 0.07639191349286556"
|
352 |
-
]
|
353 |
-
},
|
354 |
-
{
|
355 |
-
"cell_type": "code",
|
356 |
-
"execution_count": 138,
|
357 |
-
"metadata": {},
|
358 |
-
"outputs": [
|
359 |
-
{
|
360 |
-
"data": {
|
361 |
-
"text/plain": [
|
362 |
-
"0.011250737770502067"
|
363 |
-
]
|
364 |
-
},
|
365 |
-
"execution_count": 138,
|
366 |
-
"metadata": {},
|
367 |
-
"output_type": "execute_result"
|
368 |
-
}
|
369 |
-
],
|
370 |
-
"source": [
|
371 |
-
"# benchmark return\n",
|
372 |
-
"attributes_df['w_return_b'] = attributes_df.pct_b * attributes_df.prev_w_in_p_b\n",
|
373 |
-
"attributes_df.w_return_b.sum()"
|
374 |
-
]
|
375 |
-
},
|
376 |
-
{
|
377 |
-
"cell_type": "code",
|
378 |
-
"execution_count": 120,
|
379 |
-
"metadata": {},
|
380 |
-
"outputs": [
|
381 |
-
{
|
382 |
-
"name": "stderr",
|
383 |
-
"output_type": "stream",
|
384 |
-
"text": [
|
385 |
-
"/var/folders/v5/2108rh5964q9j741wg_s8r1w0000gn/T/ipykernel_87460/2230555833.py:4: SettingWithCopyWarning: \n",
|
386 |
-
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
387 |
-
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
388 |
-
"\n",
|
389 |
-
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
390 |
-
" selected_df['return_p'] = (1 + selected_df.portfolio_pct_p).cumprod()\n"
|
391 |
-
]
|
392 |
-
},
|
393 |
-
{
|
394 |
-
"data": {
|
395 |
-
"text/html": [
|
396 |
-
"<div>\n",
|
397 |
-
"<style scoped>\n",
|
398 |
-
" .dataframe tbody tr th:only-of-type {\n",
|
399 |
-
" vertical-align: middle;\n",
|
400 |
-
" }\n",
|
401 |
-
"\n",
|
402 |
-
" .dataframe tbody tr th {\n",
|
403 |
-
" vertical-align: top;\n",
|
404 |
-
" }\n",
|
405 |
-
"\n",
|
406 |
-
" .dataframe thead th {\n",
|
407 |
-
" text-align: right;\n",
|
408 |
-
" }\n",
|
409 |
-
"</style>\n",
|
410 |
-
"<table border=\"1\" class=\"dataframe\">\n",
|
411 |
-
" <thead>\n",
|
412 |
-
" <tr style=\"text-align: right;\">\n",
|
413 |
-
" <th></th>\n",
|
414 |
-
" <th>date</th>\n",
|
415 |
-
" <th>portfolio_return_p</th>\n",
|
416 |
-
" <th>portfolio_pct_p</th>\n",
|
417 |
-
" <th>portfolio_return_b</th>\n",
|
418 |
-
" <th>portfolio_pct_b</th>\n",
|
419 |
-
" <th>mkt_cap</th>\n",
|
420 |
-
" <th>prev_mkt_cap</th>\n",
|
421 |
-
" <th>pnl</th>\n",
|
422 |
-
" <th>risk</th>\n",
|
423 |
-
" <th>active_return</th>\n",
|
424 |
-
" <th>tracking_error</th>\n",
|
425 |
-
" <th>cum_pnl</th>\n",
|
426 |
-
" <th>return_p</th>\n",
|
427 |
-
" </tr>\n",
|
428 |
-
" </thead>\n",
|
429 |
-
" <tbody>\n",
|
430 |
-
" <tr>\n",
|
431 |
-
" <th>471</th>\n",
|
432 |
-
" <td>2022-12-14</td>\n",
|
433 |
-
" <td>0.151775</td>\n",
|
434 |
-
" <td>0.000000</td>\n",
|
435 |
-
" <td>0.002796</td>\n",
|
436 |
-
" <td>0.000000</td>\n",
|
437 |
-
" <td>1038.573137</td>\n",
|
438 |
-
" <td>1043.453255</td>\n",
|
439 |
-
" <td>-4.880117</td>\n",
|
440 |
-
" <td>0.327324</td>\n",
|
441 |
-
" <td>-0.000508</td>\n",
|
442 |
-
" <td>0.225463</td>\n",
|
443 |
-
" <td>-40.422972</td>\n",
|
444 |
-
" <td>1.000000</td>\n",
|
445 |
-
" </tr>\n",
|
446 |
-
" <tr>\n",
|
447 |
-
" <th>472</th>\n",
|
448 |
-
" <td>2022-12-15</td>\n",
|
449 |
-
" <td>0.166816</td>\n",
|
450 |
-
" <td>0.013638</td>\n",
|
451 |
-
" <td>0.004505</td>\n",
|
452 |
-
" <td>0.001707</td>\n",
|
453 |
-
" <td>1052.737107</td>\n",
|
454 |
-
" <td>1038.573137</td>\n",
|
455 |
-
" <td>14.163970</td>\n",
|
456 |
-
" <td>0.327122</td>\n",
|
457 |
-
" <td>0.011931</td>\n",
|
458 |
-
" <td>0.225384</td>\n",
|
459 |
-
" <td>-26.259002</td>\n",
|
460 |
-
" <td>1.013638</td>\n",
|
461 |
-
" </tr>\n",
|
462 |
-
" <tr>\n",
|
463 |
-
" <th>473</th>\n",
|
464 |
-
" <td>2022-12-16</td>\n",
|
465 |
-
" <td>0.156618</td>\n",
|
466 |
-
" <td>-0.009792</td>\n",
|
467 |
-
" <td>-0.000671</td>\n",
|
468 |
-
" <td>-0.005172</td>\n",
|
469 |
-
" <td>1042.429190</td>\n",
|
470 |
-
" <td>1052.737107</td>\n",
|
471 |
-
" <td>-10.307917</td>\n",
|
472 |
-
" <td>0.326859</td>\n",
|
473 |
-
" <td>-0.004619</td>\n",
|
474 |
-
" <td>0.225175</td>\n",
|
475 |
-
" <td>-36.566919</td>\n",
|
476 |
-
" <td>1.003713</td>\n",
|
477 |
-
" </tr>\n",
|
478 |
-
" <tr>\n",
|
479 |
-
" <th>474</th>\n",
|
480 |
-
" <td>2022-12-19</td>\n",
|
481 |
-
" <td>0.144766</td>\n",
|
482 |
-
" <td>-0.012217</td>\n",
|
483 |
-
" <td>-0.022720</td>\n",
|
484 |
-
" <td>-0.022046</td>\n",
|
485 |
-
" <td>1029.693832</td>\n",
|
486 |
-
" <td>1042.429190</td>\n",
|
487 |
-
" <td>-12.735359</td>\n",
|
488 |
-
" <td>0.326642</td>\n",
|
489 |
-
" <td>0.009829</td>\n",
|
490 |
-
" <td>0.225043</td>\n",
|
491 |
-
" <td>-49.302277</td>\n",
|
492 |
-
" <td>0.991450</td>\n",
|
493 |
-
" </tr>\n",
|
494 |
-
" <tr>\n",
|
495 |
-
" <th>475</th>\n",
|
496 |
-
" <td>2022-12-20</td>\n",
|
497 |
-
" <td>0.140936</td>\n",
|
498 |
-
" <td>-0.003925</td>\n",
|
499 |
-
" <td>-0.032668</td>\n",
|
500 |
-
" <td>-0.009947</td>\n",
|
501 |
-
" <td>1025.652205</td>\n",
|
502 |
-
" <td>1029.693832</td>\n",
|
503 |
-
" <td>-4.041626</td>\n",
|
504 |
-
" <td>0.326312</td>\n",
|
505 |
-
" <td>0.006022</td>\n",
|
506 |
-
" <td>0.224844</td>\n",
|
507 |
-
" <td>-53.343904</td>\n",
|
508 |
-
" <td>0.987559</td>\n",
|
509 |
-
" </tr>\n",
|
510 |
-
" <tr>\n",
|
511 |
-
" <th>...</th>\n",
|
512 |
-
" <td>...</td>\n",
|
513 |
-
" <td>...</td>\n",
|
514 |
-
" <td>...</td>\n",
|
515 |
-
" <td>...</td>\n",
|
516 |
-
" <td>...</td>\n",
|
517 |
-
" <td>...</td>\n",
|
518 |
-
" <td>...</td>\n",
|
519 |
-
" <td>...</td>\n",
|
520 |
-
" <td>...</td>\n",
|
521 |
-
" <td>...</td>\n",
|
522 |
-
" <td>...</td>\n",
|
523 |
-
" <td>...</td>\n",
|
524 |
-
" <td>...</td>\n",
|
525 |
-
" </tr>\n",
|
526 |
-
" <tr>\n",
|
527 |
-
" <th>596</th>\n",
|
528 |
-
" <td>2023-06-21</td>\n",
|
529 |
-
" <td>0.338226</td>\n",
|
530 |
-
" <td>-0.012860</td>\n",
|
531 |
-
" <td>-0.012265</td>\n",
|
532 |
-
" <td>-0.020746</td>\n",
|
533 |
-
" <td>1213.343064</td>\n",
|
534 |
-
" <td>1229.149762</td>\n",
|
535 |
-
" <td>-15.806698</td>\n",
|
536 |
-
" <td>0.310372</td>\n",
|
537 |
-
" <td>0.007886</td>\n",
|
538 |
-
" <td>0.219003</td>\n",
|
539 |
-
" <td>134.346955</td>\n",
|
540 |
-
" <td>1.168279</td>\n",
|
541 |
-
" </tr>\n",
|
542 |
-
" <tr>\n",
|
543 |
-
" <th>597</th>\n",
|
544 |
-
" <td>2023-06-26</td>\n",
|
545 |
-
" <td>0.327466</td>\n",
|
546 |
-
" <td>-0.009151</td>\n",
|
547 |
-
" <td>-0.028546</td>\n",
|
548 |
-
" <td>-0.016269</td>\n",
|
549 |
-
" <td>1202.239760</td>\n",
|
550 |
-
" <td>1213.343064</td>\n",
|
551 |
-
" <td>-11.103304</td>\n",
|
552 |
-
" <td>0.310175</td>\n",
|
553 |
-
" <td>0.007118</td>\n",
|
554 |
-
" <td>0.218860</td>\n",
|
555 |
-
" <td>123.243651</td>\n",
|
556 |
-
" <td>1.157588</td>\n",
|
557 |
-
" </tr>\n",
|
558 |
-
" <tr>\n",
|
559 |
-
" <th>598</th>\n",
|
560 |
-
" <td>2023-06-27</td>\n",
|
561 |
-
" <td>0.339179</td>\n",
|
562 |
-
" <td>0.010630</td>\n",
|
563 |
-
" <td>-0.016308</td>\n",
|
564 |
-
" <td>0.012234</td>\n",
|
565 |
-
" <td>1215.019735</td>\n",
|
566 |
-
" <td>1202.239760</td>\n",
|
567 |
-
" <td>12.779975</td>\n",
|
568 |
-
" <td>0.309985</td>\n",
|
569 |
-
" <td>-0.001604</td>\n",
|
570 |
-
" <td>0.218682</td>\n",
|
571 |
-
" <td>136.023626</td>\n",
|
572 |
-
" <td>1.169893</td>\n",
|
573 |
-
" </tr>\n",
|
574 |
-
" <tr>\n",
|
575 |
-
" <th>599</th>\n",
|
576 |
-
" <td>2023-06-28</td>\n",
|
577 |
-
" <td>0.335389</td>\n",
|
578 |
-
" <td>-0.002982</td>\n",
|
579 |
-
" <td>-0.016974</td>\n",
|
580 |
-
" <td>-0.000665</td>\n",
|
581 |
-
" <td>1211.396987</td>\n",
|
582 |
-
" <td>1215.019735</td>\n",
|
583 |
-
" <td>-3.622748</td>\n",
|
584 |
-
" <td>0.309735</td>\n",
|
585 |
-
" <td>-0.002316</td>\n",
|
586 |
-
" <td>0.218507</td>\n",
|
587 |
-
" <td>132.400878</td>\n",
|
588 |
-
" <td>1.166405</td>\n",
|
589 |
-
" </tr>\n",
|
590 |
-
" <tr>\n",
|
591 |
-
" <th>600</th>\n",
|
592 |
-
" <td>2023-06-29</td>\n",
|
593 |
-
" <td>0.343213</td>\n",
|
594 |
-
" <td>0.006552</td>\n",
|
595 |
-
" <td>-0.017097</td>\n",
|
596 |
-
" <td>-0.000125</td>\n",
|
597 |
-
" <td>1219.334595</td>\n",
|
598 |
-
" <td>1211.396987</td>\n",
|
599 |
-
" <td>7.937608</td>\n",
|
600 |
-
" <td>0.309501</td>\n",
|
601 |
-
" <td>0.006678</td>\n",
|
602 |
-
" <td>0.218361</td>\n",
|
603 |
-
" <td>140.338486</td>\n",
|
604 |
-
" <td>1.174048</td>\n",
|
605 |
-
" </tr>\n",
|
606 |
-
" </tbody>\n",
|
607 |
-
"</table>\n",
|
608 |
-
"<p>130 rows × 13 columns</p>\n",
|
609 |
-
"</div>"
|
610 |
-
],
|
611 |
-
"text/plain": [
|
612 |
-
" date portfolio_return_p portfolio_pct_p portfolio_return_b \\\n",
|
613 |
-
"471 2022-12-14 0.151775 0.000000 0.002796 \n",
|
614 |
-
"472 2022-12-15 0.166816 0.013638 0.004505 \n",
|
615 |
-
"473 2022-12-16 0.156618 -0.009792 -0.000671 \n",
|
616 |
-
"474 2022-12-19 0.144766 -0.012217 -0.022720 \n",
|
617 |
-
"475 2022-12-20 0.140936 -0.003925 -0.032668 \n",
|
618 |
-
".. ... ... ... ... \n",
|
619 |
-
"596 2023-06-21 0.338226 -0.012860 -0.012265 \n",
|
620 |
-
"597 2023-06-26 0.327466 -0.009151 -0.028546 \n",
|
621 |
-
"598 2023-06-27 0.339179 0.010630 -0.016308 \n",
|
622 |
-
"599 2023-06-28 0.335389 -0.002982 -0.016974 \n",
|
623 |
-
"600 2023-06-29 0.343213 0.006552 -0.017097 \n",
|
624 |
-
"\n",
|
625 |
-
" portfolio_pct_b mkt_cap prev_mkt_cap pnl risk \\\n",
|
626 |
-
"471 0.000000 1038.573137 1043.453255 -4.880117 0.327324 \n",
|
627 |
-
"472 0.001707 1052.737107 1038.573137 14.163970 0.327122 \n",
|
628 |
-
"473 -0.005172 1042.429190 1052.737107 -10.307917 0.326859 \n",
|
629 |
-
"474 -0.022046 1029.693832 1042.429190 -12.735359 0.326642 \n",
|
630 |
-
"475 -0.009947 1025.652205 1029.693832 -4.041626 0.326312 \n",
|
631 |
-
".. ... ... ... ... ... \n",
|
632 |
-
"596 -0.020746 1213.343064 1229.149762 -15.806698 0.310372 \n",
|
633 |
-
"597 -0.016269 1202.239760 1213.343064 -11.103304 0.310175 \n",
|
634 |
-
"598 0.012234 1215.019735 1202.239760 12.779975 0.309985 \n",
|
635 |
-
"599 -0.000665 1211.396987 1215.019735 -3.622748 0.309735 \n",
|
636 |
-
"600 -0.000125 1219.334595 1211.396987 7.937608 0.309501 \n",
|
637 |
-
"\n",
|
638 |
-
" active_return tracking_error cum_pnl return_p \n",
|
639 |
-
"471 -0.000508 0.225463 -40.422972 1.000000 \n",
|
640 |
-
"472 0.011931 0.225384 -26.259002 1.013638 \n",
|
641 |
-
"473 -0.004619 0.225175 -36.566919 1.003713 \n",
|
642 |
-
"474 0.009829 0.225043 -49.302277 0.991450 \n",
|
643 |
-
"475 0.006022 0.224844 -53.343904 0.987559 \n",
|
644 |
-
".. ... ... ... ... \n",
|
645 |
-
"596 0.007886 0.219003 134.346955 1.168279 \n",
|
646 |
-
"597 0.007118 0.218860 123.243651 1.157588 \n",
|
647 |
-
"598 -0.001604 0.218682 136.023626 1.169893 \n",
|
648 |
-
"599 -0.002316 0.218507 132.400878 1.166405 \n",
|
649 |
-
"600 0.006678 0.218361 140.338486 1.174048 \n",
|
650 |
-
"\n",
|
651 |
-
"[130 rows x 13 columns]"
|
652 |
-
]
|
653 |
-
},
|
654 |
-
"execution_count": 120,
|
655 |
-
"metadata": {},
|
656 |
-
"output_type": "execute_result"
|
657 |
-
}
|
658 |
-
],
|
659 |
-
"source": [
|
660 |
-
"selected_df = p_eval_df[p_eval_df.date.between(start_date, end_date)]\n",
|
661 |
-
"selected_df.iloc[0, selected_df.columns.get_indexer(\n",
|
662 |
-
" ['portfolio_pct_p', 'portfolio_pct_b'])] = 0\n",
|
663 |
-
"selected_df['return_p'] = (1 + selected_df.portfolio_pct_p).cumprod()\n",
|
664 |
-
"selected_df"
|
665 |
-
]
|
666 |
-
},
|
667 |
-
{
|
668 |
-
"cell_type": "code",
|
669 |
-
"execution_count": 140,
|
670 |
-
"metadata": {},
|
671 |
-
"outputs": [
|
672 |
-
{
|
673 |
-
"data": {
|
674 |
-
"text/plain": [
|
675 |
-
"Index(['date', 'portfolio_return_p', 'portfolio_pct_p', 'portfolio_return_b',\n",
|
676 |
-
" 'portfolio_pct_b', 'mkt_cap', 'prev_mkt_cap', 'pnl', 'risk',\n",
|
677 |
-
" 'active_return', 'tracking_error', 'cum_pnl'],\n",
|
678 |
-
" dtype='object')"
|
679 |
-
]
|
680 |
-
},
|
681 |
-
"execution_count": 140,
|
682 |
-
"metadata": {},
|
683 |
-
"output_type": "execute_result"
|
684 |
-
}
|
685 |
-
],
|
686 |
-
"source": [
|
687 |
-
"p_eval_df.columns"
|
688 |
-
]
|
689 |
-
}
|
690 |
-
],
|
691 |
-
"metadata": {
|
692 |
-
"kernelspec": {
|
693 |
-
"display_name": "portfolio_risk_assesment",
|
694 |
-
"language": "python",
|
695 |
-
"name": "python3"
|
696 |
-
},
|
697 |
-
"language_info": {
|
698 |
-
"codemirror_mode": {
|
699 |
-
"name": "ipython",
|
700 |
-
"version": 3
|
701 |
-
},
|
702 |
-
"file_extension": ".py",
|
703 |
-
"mimetype": "text/x-python",
|
704 |
-
"name": "python",
|
705 |
-
"nbconvert_exporter": "python",
|
706 |
-
"pygments_lexer": "ipython3",
|
707 |
-
"version": "3.11.4"
|
708 |
-
},
|
709 |
-
"orig_nbformat": 4
|
710 |
-
},
|
711 |
-
"nbformat": 4,
|
712 |
-
"nbformat_minor": 2
|
713 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|