{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "celkovy optimalizacni backtest na vetsim oknu 1 - 300\n", "a možná take to udělat jako parametr\n", "zkusit CV\n", "zobrazit nejak robustnost parametru" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from v2realbot.tools.loadbatch import load_batch\n", "from v2realbot.utils.utils import zoneNY\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", "\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\n", "\n", "# 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", "\n", "forced_exit_start = 380\n", "forced_exit_end = 390\n", "\n", "res, df = load_batch(batch_id=\"f1ac6651\", #138170bc 0fb5043a bde6d0be f1ac6651\n", " space_resolution_evenly=False,\n", " indicators_columns=[\"Rsi14\"],\n", " main_session_only=True,\n", " verbose = False)\n", "if res < 0:\n", " print(\"Error\" + str(res) + str(df))\n", "df = df[\"bars\"]\n", "\n", "df\n", "\n", "basic_data = vbt.Data.from_data(vbt.symbol_dict({\"BAC\": df}), tz_convert=zoneNY)\n", "#m1_data = basic_data[['Open', 'High', 'Low', 'Close', 'Volume']]\n", "basic_data = basic_data.transform(lambda df: df.between_time('09:30', '16:00'))\n", "#basic_data.info()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vbt.open_api_ref(vbt.base)\n", "\n", "vbt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "##na toto udelat crosssvalidationu nebo alespon na testovacim ci jinem obdobi\n", "#take udelat long leg - tato je shortovaci\n", "\n", "#8\t-0.06\t-0.2\t0.0028\t0.0048\t4.156254\n", "\n", "#short combination ok for train(4)/test(0.1) (window 1-90, fe 95-100)\n", "#2,\t-0.02,\t-0.25,\t0.0018,\t0.0068\n", "\n", "#dalsi ok hodnota shortu for train/test 4/1\n", "#70,\t8,\t-0.06,\t-0.2,\t0.0013,\t0.0053\t\n", "\n", "\n", "#kombinace bez roc_th, train/test 7/-1.5\n", "#70\t7\t-0.07\t0.0033\t0.0063\n", "\n", "#opet bez roc_th, train(5.77)/test 0.9 - spolus tsl_stop + tsl_th\n", "#29\t7\t-0.09\t0.0033\t0.0068\n", "\n", "#bez roc_th a s trailing sl train/test 8.1/-0.8 \n", "#70\t2\t-0.05\t0.0018\t0.0068\n", "\n", "\n", "# TODO:\n", "#- vyzkouset zda nejvyhodnejsi kombinace krom train/testu funguje i na nasledujicich dnech po trainu\n", "# -zkusit najit v short datasetu neco vyhodneho co funguji i na testu\n", "# - dodelat kombinace pro long signaly\n", "# - zkusit walk forward\n", "# - vytvorit vysledkove totoznou na v2realbot\n", "# - podivat se jak detailne funguji tsl_stop a tsl_th\n", "\n", "#70,\t4,\t-0.07,\t0.0048,\t0.0068\t\n", "\n", "\n", "entry_window_closes, mom_timeperiod, mom_th, sl_stop, tp_stop = 8,\t3,\t0.07,\t0.0028,\t0.0033\t\n", "roc_th = 0\n", "momshort = vbt.indicator(\"talib:MOM\").run(basic_data.close, timeperiod=mom_timeperiod, short_name = \"slope_short\")\n", "rocp = vbt.indicator(\"talib:ROC\").run(basic_data.close, short_name = \"rocp\")\n", "#rate of change + momentum\n", "\n", "#momshort.plot rocp.real_crossed_below(roc_th) & \n", "short_signal = momshort.real_crossed_below(mom_th)\n", "\n", "long_signal = momshort.real_crossed_above(mom_th)\n", "\n", "# print(\"short signal\")\n", "# print(short_signal.value_counts())\n", "\n", "#forced_exit = pd.Series(False, index=close.index)\n", "forced_exit = basic_data.symbol_wrapper.fill(False)\n", "#entry_window_open = pd.Series(False, index=close.index)\n", "entry_window_open= basic_data.symbol_wrapper.fill(False)\n", "\n", "# Calculate the time difference in minutes from market open for each timestamp\n", "elapsed_min_from_open = (forced_exit.index.hour - market_open.hour) * 60 + (forced_exit.index.minute - market_open.minute)\n", "\n", "entry_window_open[(elapsed_min_from_open >= entry_window_opens) & (elapsed_min_from_open < entry_window_closes)] = True\n", "\n", "#print(entry_window_open.value_counts())\n", "\n", "forced_exit[(elapsed_min_from_open >= forced_exit_start) & (elapsed_min_from_open < forced_exit_end)] = True\n", "short_entries = (short_signal & entry_window_open)\n", "short_exits = forced_exit\n", "\n", "entries = (long_signal & entry_window_open)\n", "exits = forced_exit\n", "#long_entries.info()\n", "#number of trues and falses in long_entries\n", "# print(short_exits.value_counts())\n", "# print(short_entries.value_counts())\n", "\n", "#fig = plot_2y_close([],[momshort, rocp], close)\n", "#short_signal.vbt.signals.plot_as_entries(close, fig=fig, add_trace_kwargs=dict(secondary_y=False))\n", "#print(sl_stop)\n", "#short_entries=short_entries, short_exits=short_exits,\n", "pf = vbt.Portfolio.from_signals(close=basic_data, entries=entries, exits=exits, tsl_stop=sl_stop, tp_stop = tp_stop, fees=0.0167/100, freq=\"1s\") #sl_stop=sl_stop, tp_stop = sl_stop,\n", "\n", "pf.stats()\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf.plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf.get_drawdowns().records_readable" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf.orders.records_readable" ] } ], "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 }