309 lines
9.2 KiB
Plaintext
309 lines
9.2 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Robustness evaluation\n",
|
|
"\n",
|
|
"Input is backtest results in the format:\n",
|
|
"\n",
|
|
"- Parameter combination (multiindex)\n",
|
|
"- Profitability metrics (columns)\n",
|
|
"\n",
|
|
"Lets explore various way to evaluate robustness."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#!pip install git+https://github.com/drew2323/lightweight-charts-python.git\n",
|
|
"#!pip install git+https://gitea.stratlab.dev/Stratlab/db.git\n",
|
|
"from lightweight_charts import Panel, chart, PlotSRAccessor, PlotDFAccessor\n",
|
|
"import pandas as pd\n",
|
|
"import numpy as np\n",
|
|
"import vectorbtpro as vbt\n",
|
|
"# from itables import init_notebook_mode, show\n",
|
|
"import datetime\n",
|
|
"from itertools import product\n",
|
|
"from IPython.display import display\n",
|
|
"# init_notebook_mode(all_interactive=True)\n",
|
|
"\n",
|
|
"vbt.settings.set_theme(\"dark\")\n",
|
|
"vbt.settings['plotting']['layout']['width'] = 1280\n",
|
|
"vbt.settings.plotting.auto_rangebreaks = True\n",
|
|
"# Set the option to display with pagination\n",
|
|
"pd.set_option('display.notebook_repr_html', True)\n",
|
|
"pd.set_option('display.max_rows', 10) # Number of rows per page"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#fetching US-STOCKS ohlcv_1s\n",
|
|
"from lib.db import Connection\n",
|
|
"SYMBOL = \"BAC\"\n",
|
|
"SCHEMA = \"ohlcv_1s\" #time based 1s other options ohlcv_vol_200 (volume based ohlcv with resolution of 200), ohlcv_renko_20 (renko with 20 bricks size) ...\n",
|
|
"DB = \"market_data\"\n",
|
|
"\n",
|
|
"con = Connection(db_name=DB, default_schema=SCHEMA, create_db=True)\n",
|
|
"basic_data = con.pull(symbols=[SYMBOL], schema=SCHEMA,start=\"2024-08-01\", end=\"2024-08-05\", tz_convert='America/New_York')\n",
|
|
"\n",
|
|
"basic_data.data[SYMBOL].info()\n",
|
|
"\n",
|
|
"#1month 1s data - 15s - 24MB\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#basic_data.ohlcv.data[SYMBOL].lw.plot()\n",
|
|
"basic_data.data[SYMBOL].lw.plot(size=\"s\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"basic_data.data[SYMBOL].vwap.lw.plot()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"basic_data.data[SYMBOL].vwap.lw.plot(histogram=(basic_data.data[SYMBOL].trades, \"trades\"))\n",
|
|
"\n",
|
|
" #xloc[\"2024-08-05\":\"2024-08-10\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Define the market open and close times\n",
|
|
"market_open = datetime.time(9, 30)\n",
|
|
"market_close = datetime.time(16, 0)\n",
|
|
"entry_window_opens = 1\n",
|
|
"entry_window_closes = 370\n",
|
|
"forced_exit_start = 380\n",
|
|
"forced_exit_end = 390\n",
|
|
"\n",
|
|
"#NUMDAYS\n",
|
|
"basic_data.wrapper.index.normalize().nunique()\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Add resample function to custom columns"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from vectorbtpro.utils.config import merge_dicts, Config, HybridConfig\n",
|
|
"from vectorbtpro import _typing as tp\n",
|
|
"from vectorbtpro.generic import nb as generic_nb\n",
|
|
"\n",
|
|
"_feature_config: tp.ClassVar[Config] = HybridConfig(\n",
|
|
" {\n",
|
|
" \"buyvolume\": dict(\n",
|
|
" resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(\n",
|
|
" resampler,\n",
|
|
" generic_nb.sum_reduce_nb,\n",
|
|
" )\n",
|
|
" ),\n",
|
|
" \"sellvolume\": dict(\n",
|
|
" resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(\n",
|
|
" resampler,\n",
|
|
" generic_nb.sum_reduce_nb,\n",
|
|
" )\n",
|
|
" ),\n",
|
|
" \"trades\": dict(\n",
|
|
" resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(\n",
|
|
" resampler,\n",
|
|
" generic_nb.sum_reduce_nb,\n",
|
|
" )\n",
|
|
" )\n",
|
|
" }\n",
|
|
")\n",
|
|
"\n",
|
|
"basic_data._feature_config = _feature_config"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"s1data = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']]\n",
|
|
"\n",
|
|
"# s5data = s1data.resample(\"12s\")\n",
|
|
"# s5data = s5data.transform(lambda df: df.between_time('09:30', '16:00').dropna())\n",
|
|
"\n",
|
|
"t1data = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']].resample(\"1T\")\n",
|
|
"t1data = t1data.transform(lambda df: df.between_time('09:30', '16:00').dropna())\n",
|
|
"# t1data.data[\"BAC\"].info()\n",
|
|
"\n",
|
|
"# t30data = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']].resample(\"30T\")\n",
|
|
"# t30data = t30data.transform(lambda df: df.between_time('09:30', '16:00').dropna())\n",
|
|
"# # t30data.data[\"BAC\"].info()\n",
|
|
"\n",
|
|
"s1close = s1data.close\n",
|
|
"t1close = t1data.close\n",
|
|
"\n",
|
|
"t1data.data[\"BAC\"].close.lw.plot()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from lightweight_charts import JupyterChart, chart, Panel, PlotAccessor\n",
|
|
"s5data.close.lw.plot()\n",
|
|
"\n",
|
|
"# pane1 = Panel(\n",
|
|
"# ohlcv=(s5data.ohlcv.get(),))\n",
|
|
"\n",
|
|
"# # Create the chart with the panel\n",
|
|
"# ch = chart([pane1], title=\"Chart\", sync=True, session=None, size=\"s\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"s1data.data[\"BAC\"].head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#resample on specific index \n",
|
|
"resampler = vbt.Resampler(t30data.index, s1data.index, source_freq=\"30T\", target_freq=\"1s\")\n",
|
|
"t30close_realigned = t30close.vbt.realign_closing(resampler)\n",
|
|
"\n",
|
|
"#resample 1min to s\n",
|
|
"resampler_s = vbt.Resampler(t1data.index, s1data.index, source_freq=\"1T\", target_freq=\"1s\")\n",
|
|
"t1close_realigned = t1close.vbt.realign_closing(resampler_s)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"vbt.IF.list_indicators(\"*vwap\")\n",
|
|
"vbt.phelp(vbt.VWAP.run)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# VWAP"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"t1vwap_h = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor=\"H\")\n",
|
|
"t1vwap_d = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor=\"D\")\n",
|
|
"t1vwap_t = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor=\"T\")\n",
|
|
"\n",
|
|
"t1vwap_h_real = t1vwap_h.vwap.vbt.realign_closing(resampler_s)\n",
|
|
"t1vwap_d_real = t1vwap_d.vwap.vbt.realign_closing(resampler_s)\n",
|
|
"t1vwap_t_real = t1vwap_t.vwap.vbt.realign_closing(resampler_s)\n",
|
|
"\n",
|
|
"#t1vwap_5t.xloc[\"2024-01-3 09:30:00\":\"2024-01-03 16:00:00\"].plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"#m30data.close.lw.plot()\n",
|
|
"#quick few liner\n",
|
|
"pane1 = Panel(\n",
|
|
" histogram=[\n",
|
|
" #(s1data.volume, \"volume\",None, 0.8),\n",
|
|
" #(m30volume, \"m30volume\",None, 1)\n",
|
|
" ], # [(series, name, \"rgba(53, 94, 59, 0.6)\", opacity)]\n",
|
|
" right=[\n",
|
|
" (s1data.close, \"1s close\"),\n",
|
|
" (t1data.close, \"1min close\"),\n",
|
|
" (t1vwap_t, \"1mvwap_t\"),\n",
|
|
" (t1vwap_h, \"1mvwap_h\"),\n",
|
|
" (t1vwap_d, \"1mvwap_d\"),\n",
|
|
" (t1vwap_t_real, \"1mvwap_t_real\"),\n",
|
|
" (t1vwap_h_real, \"1mvwap_h_real\"),\n",
|
|
" (t1vwap_d_real, \"1mvwap_d_real\")\n",
|
|
" # (t1close_realigned, \"1min close realigned\"),\n",
|
|
" # (m30data.close, \"30min-close\"),\n",
|
|
" # (m30close_realigned, \"30min close realigned\"),\n",
|
|
" ],\n",
|
|
")\n",
|
|
"ch = chart([pane1], size=\"s\" ) #xloc=slice(\"2024-05-1 09:30:00\",\"2024-05-25 16:00:00\"))"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": ".venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.11"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|