{ "cells": [ { "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", "from datetime import timedelta, datetime\n", "import vectorbtpro as vbt\n", "import os\n", "from itables import init_notebook_mode, show\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", "# Alpaca API credentials\n", "ALPACA_API_KEY = os.environ.get('ACCOUNT1_PAPER_API_KEY')\n", "ALPACA_API_SECRET = os.environ.get('ACCOUNT1_PAPER_SECRET_KEY')\n", "\n", "# Initialize Alpaca data client\n", "alpaca_data = vbt.AlpacaData.set_custom_settings(client_config=dict(\n", " api_key=ALPACA_API_KEY,\n", " secret_key=ALPACA_API_SECRET\n", " )\n", ")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Fetch Data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Define the symbol, start, and end dates for your data\n", "symbol = 'BAC'\n", "start_date = datetime.now() - timedelta(days=10) # Last 30 days\n", "end_date = datetime.now() - timedelta(days=1) # yesterday\n", "time_interval = '1T' # 1-minute intervals '1 minute'\n", "\n", "basic_data = vbt.AlpacaData.pull([\"BAC\"], start=start_date, end=end_date, timeframe=time_interval, tz=\"America/New_York\")\n", "basic_data = basic_data.transform(lambda x: x.between_time(\"9:30\",\"16:00\"))\n", "#basic_data.data[\"BAC\"].vbt.ohlcv.plot()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# filter dates" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#filter na dny\n", "# dates_of_interest = pd.to_datetime(['2024-04-22', '2024-04-23']).tz_localize('US/Eastern')\n", "# filtered_df = df.loc[df.index.normalize().isin(dates_of_interest)]\n", "\n", "# df = filtered_df\n", "# df.info()\n", "\n", "basic_data.data[\"BAC\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m1_data = basic_data[['Open', 'High', 'Low', 'Close', 'Volume']]\n", "\n", "m1_data.data[\"BAC\"]\n", "#m5_data = m1_data.resample(\"5T\")\n", "\n", "#m5_data.data[\"BAC\"].head(10)\n", "\n", "m15_data = m1_data.resample(\"15T\")\n", "\n", "m15_data = m15_data.transform(lambda x: x.between_time(\"9:30\",\"15:59\"))\n", "\n", "m15 = m15_data.data[\"BAC\"]\n", "\n", "m15.vbt.ohlcv.plot()\n", "\n", "m15\n", "\n", "# m1_data.wrapper.index\n", "\n", "# m1_resampler = m1_data.wrapper.get_resampler(\"1T\")\n", "# m1_resampler.index_difference(reverse=True)\n", "\n", "\n", "# m5_resampler.prettify()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Calculate VWAP" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#WWAP\n", "vbt.phelp(vbt.VWAP.run)\n", "close = m1_data.close\n", "high = m1_data.high\n", "low = m1_data.low\n", "volume = m1_data.volume\n", "vwapD = vbt.VWAP.run(high, low, close, volume, anchor=\"D\")\n", "# vwapT = vbt.VWAP.run(high, low, close, volume, anchor=\"T\")\n", "\n", "#vwap.vwap\n", "\n", "fig = m1_data.data[\"BAC\"].vbt.ohlcv.plot()\n", "vwapD.vwap.vbt.plot(fig=fig)\n", "#vwapT.vwap.vbt.plot(fig=fig)\n", "fig.show()\n", "\n", "vwapD.vwap\n", "\n", "#vwap = vbt.VWAP.run()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m1_data.data[\"BAC\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# defining ENTRY WINDOW and forced EXIT window" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#m1_data.data[\"BAC\"].info()\n", "import datetime\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 = 350\n", "\n", "forced_exit_start = 360\n", "forced_exit_end = 390\n", "\n", "forced_exit = m1_data.symbol_wrapper.fill(False)\n", "entry_window_open= m1_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", "forced_exit[(elapsed_min_from_open >= forced_exit_start) & (elapsed_min_from_open < forced_exit_end)] = True\n", "\n", "#entry_window_open.info()\n", "# forced_exit.tail(100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "close = m1_data.close\n", "\n", "rsi = vbt.RSI.run(close, window=14)\n", "\n", "long_entries = (rsi.rsi.vbt.crossed_below(28) & entry_window_open)\n", "long_exits = (rsi.rsi.vbt.crossed_above(70) | forced_exit)\n", "#long_entries.info()\n", "#number of trues and falses in long_entries\n", "#long_entries.value_counts()\n", "long_exits.value_counts()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "close" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def plot_rsi(rsi, close, entries, exits):\n", " fig = vbt.make_subplots(rows=1, cols=1, shared_xaxes=True, specs=[[{\"secondary_y\": True}]], vertical_spacing=0.02, subplot_titles=(\"RSI\", \"Price\" ))\n", " close.vbt.plot(fig=fig, add_trace_kwargs=dict(secondary_y=True))\n", " rsi.plot(fig=fig, add_trace_kwargs=dict(secondary_y=False))\n", " entries.vbt.signals.plot_as_entries(close, fig=fig, add_trace_kwargs=dict(secondary_y=True)) \n", " exits.vbt.signals.plot_as_exits(close, fig=fig, add_trace_kwargs=dict(secondary_y=True)) \n", " return fig\n", "\n", "plot_rsi(rsi, close, long_entries, long_exits)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rsi.rsi" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vbt.phelp(vbt.Portfolio.from_signals)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sl_stop = np.arange(0.03/100, 0.4/100, 0.05/100).tolist()\n", "# Using the round function\n", "sl_stop = [round(val, 4) for val in sl_stop]\n", "print(sl_stop)\n", "sl_stop = vbt.Param(sl_stop) #np.nan mean s no stoploss\n", "\n", "pf = vbt.Portfolio.from_signals(close=close, entries=long_entries, exits=long_exits, sl_stop=sl_stop, tp_stop = sl_stop, fees=0.0167/100, freq=\"1s\") #sl_stop=sl_stop, tp_stop = sl_stop,\n", "\n", "pf.stats()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf[(0.0003,0.0018)].plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf[0.03].plot_trade_signals()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# pristup k pf jako multi index" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#pf[0.03].plot()\n", "#pf.order_records\n", "pf[(0.03)].stats()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#zgrupovane statistiky\n", "stats_df = pf.stats([\n", " 'total_return',\n", " 'total_trades',\n", " 'win_rate',\n", " 'expectancy'\n", "], agg_func=None)\n", "stats_df\n", "\n", "\n", "stats_df.nlargest(10, 'Total Return [%]')\n", "#stats_df.info()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pf[(0.0011,0.0013000000000000002)].plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pandas.tseries.offsets import DateOffset\n", "\n", "temp_data = basic_data['2024-4-22']\n", "temp_data\n", "res1m = temp_data[[\"Open\", \"High\", \"Low\", \"Close\", \"Volume\"]]\n", "\n", "# Define a custom date offset that starts at 9:30 AM and spans 4 hours\n", "custom_offset = DateOffset(hours=4, minutes=30)\n", "\n", "# res1m = res1m.get().resample(\"4H\").agg({ \n", "# \"Open\": \"first\",\n", "# \"High\": \"max\",\n", "# \"Low\": \"min\",\n", "# \"Close\": \"last\",\n", "# \"Volume\": \"sum\"\n", "# })\n", "\n", "res4h = res1m.resample(\"1h\", resample_kwargs=dict(origin=\"start\"))\n", "\n", "res4h.data\n", "\n", "res15m = res1m.resample(\"15T\", resample_kwargs=dict(origin=\"start\"))\n", "\n", "res15m.data[\"BAC\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@vbt.njit\n", "def long_entry_place_func_nb(c, low, close, time_in_ns, rsi14, window_open, window_close):\n", " market_open_minutes = 570 # 9 hours * 60 minutes + 30 minutes\n", "\n", " for out_i in range(len(c.out)):\n", " i = c.from_i + out_i\n", "\n", " current_minutes = vbt.dt_nb.hour_nb(time_in_ns[i]) * 60 + vbt.dt_nb.minute_nb(time_in_ns[i])\n", " #print(\"current_minutes\", current_minutes)\n", " # Calculate elapsed minutes since market open at 9:30 AM\n", " elapsed_from_open = current_minutes - market_open_minutes\n", " elapsed_from_open = elapsed_from_open if elapsed_from_open >= 0 else 0\n", " #print( \"elapsed_from_open\", elapsed_from_open)\n", "\n", " #elapsed_from_open = elapsed_minutes_from_open_nb(time_in_ns) \n", " in_window = elapsed_from_open > window_open and elapsed_from_open < window_close\n", " #print(\"in_window\", in_window)\n", " # if in_window:\n", " # print(\"in window\")\n", "\n", " if in_window and rsi14[i] > 60: # and low[i, c.col] <= hit_price: # and hour == 9: # (4)!\n", " return out_i\n", " return -1\n", "\n", "@vbt.njit\n", "def long_exit_place_func_nb(c, high, close, time_index, tp, sl): # (5)!\n", " entry_i = c.from_i - c.wait\n", " entry_price = close[entry_i, c.col]\n", " hit_price = entry_price * (1 + tp)\n", " stop_price = entry_price * (1 - sl)\n", " for out_i in range(len(c.out)):\n", " i = c.from_i + out_i\n", " last_bar_of_day = vbt.dt_nb.day_changed_nb(time_index[i], time_index[i + 1])\n", "\n", " #print(next_day)\n", " if last_bar_of_day: #pokud je dalsi next day, tak zavirame posledni\n", " print(\"ted\",out_i)\n", " return out_i\n", " if close[i, c.col] >= hit_price or close[i, c.col] <= stop_price :\n", " return out_i\n", " return -1\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.random(size=(5, 10)), columns=list('abcdefghij'))\n", "\n", "df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.sum()" ] } ], "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 }