Files
strategy-lab/to_explore/notebooks/SignalDevelopment.ipynb

2558 lines
65 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "906f22ee-4fda-4b00-86b5-666eeba85526",
"metadata": {},
"source": [
"# Signal development"
]
},
{
"cell_type": "markdown",
"id": "ea0a17e8-dede-43b7-8d69-ae44fa9eeef0",
"metadata": {},
"source": [
"## Generation"
]
},
{
"cell_type": "markdown",
"id": "c92e74cd-bef9-43e1-a78e-f39d308798df",
"metadata": {},
"source": [
"### Comparison"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bc046d2c-54c8-4363-aa50-9535db8c1fa7",
"metadata": {},
"outputs": [],
"source": [
"from vectorbtpro import *\n",
"# whats_imported()\n",
"\n",
"vbt.settings.set_theme(\"dark\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a5fa071-d8c4-4443-8528-88c5cab650cf",
"metadata": {},
"outputs": [],
"source": [
"data = vbt.BinanceData.pull(\n",
" [\"BTCUSDT\", \"ETHUSDT\"], \n",
" start=\"2021-01-01\",\n",
" end=\"2022-01-01\"\n",
")\n",
"print(data.get(\"Low\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b43d9cc2-631e-44a4-9a0b-83aa08c3a722",
"metadata": {},
"outputs": [],
"source": [
"bb = vbt.talib(\"BBANDS\").run(\n",
" data.get(\"Close\"),\n",
" timeperiod=vbt.Default(14),\n",
" nbdevup=vbt.Default(2),\n",
" nbdevdn=vbt.Default(2)\n",
")\n",
"print(bb.lowerband)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e3ee3576-aa6f-4652-83de-fbaa47eb7137",
"metadata": {},
"outputs": [],
"source": [
"mask = data.get(\"Low\") < bb.lowerband\n",
"print(mask)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "73b16f6b-cd9d-4ccb-92b8-d374f59dfe4b",
"metadata": {},
"outputs": [],
"source": [
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f1032773-752b-435f-8a96-3aea5e7fec6e",
"metadata": {},
"outputs": [],
"source": [
"bb_mult = vbt.talib(\"BBANDS\").run(\n",
" data.get(\"Close\"),\n",
" timeperiod=vbt.Default(14),\n",
" nbdevup=[2, 3],\n",
" nbdevdn=[2, 3]\n",
")\n",
"# mask = data.get(\"Low\") < bb_mult.lowerband"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6aafc576-9b8a-4475-ad4c-1aaa7f71d4b1",
"metadata": {},
"outputs": [],
"source": [
"mask = data.get(\"Low\").vbt < bb_mult.lowerband\n",
"print(mask)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dbe069e6-47c0-4760-b6d7-ebc2e8bf9e62",
"metadata": {},
"outputs": [],
"source": [
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6db65b8-b971-433f-b4bc-fe97263baa30",
"metadata": {},
"outputs": [],
"source": [
"mask = bb_mult.lowerband_above(data.get(\"Low\"))\n",
"mask.sum()"
]
},
{
"cell_type": "markdown",
"id": "7301f0a1-6e79-4da1-9daf-8345c35da38d",
"metadata": {},
"source": [
"#### Thresholds"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2487f5f5-2277-4608-a6ee-bd26a88b3d48",
"metadata": {},
"outputs": [],
"source": [
"bandwidth = (bb.upperband - bb.lowerband) / bb.middleband\n",
"\n",
"mask = bandwidth.vbt > vbt.Param([0.15, 0.3], name=\"threshold\")\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f634615-3e6f-4ba8-a3e4-843748fb6663",
"metadata": {},
"outputs": [],
"source": [
"mask = bandwidth.vbt.combine(\n",
" [0.15, 0.3],\n",
" combine_func=np.greater, \n",
" keys=pd.Index([0.15, 0.3], name=\"threshold\")\n",
")\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6bda89d4-6381-4ec1-b1bc-ffe302454181",
"metadata": {},
"outputs": [],
"source": [
"mask = pd.concat(\n",
" (bandwidth > 0.15, bandwidth > 0.3), \n",
" keys=pd.Index([0.15, 0.3], name=\"threshold\"), \n",
" axis=1\n",
")\n",
"mask.sum()"
]
},
{
"cell_type": "markdown",
"id": "66ef2746-1d4f-48bd-887e-da3ce86aa2d9",
"metadata": {},
"source": [
"#### Crossovers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "112ffe71-78da-4bba-a9d4-7f5ffeb5cb3e",
"metadata": {},
"outputs": [],
"source": [
"low_below_lband = data.get(\"Low\") < bb.lowerband\n",
"mask = low_below_lband.vbt.signals.first()\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e92bbb10-724a-4f28-9a54-6d41f36f7bf4",
"metadata": {},
"outputs": [],
"source": [
"btc_low = data.get(\"Low\", \"BTCUSDT\").rename(\"Low\")\n",
"btc_lowerband = bb.lowerband[\"BTCUSDT\"].rename(\"Lower Band\")\n",
"btc_mask = mask[\"BTCUSDT\"].rename(\"Signals\")\n",
"\n",
"fig = btc_low.vbt.plot()\n",
"btc_lowerband.vbt.plot(fig=fig)\n",
"btc_mask.vbt.signals.plot_as_markers(\n",
" y=btc_low, \n",
" trace_kwargs=dict(\n",
" marker=dict(\n",
" color=\"#DFFF00\"\n",
" )\n",
" ),\n",
" fig=fig\n",
").show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9caf1ea8-18b8-42d6-b759-e3ef87ea23ab",
"metadata": {},
"outputs": [],
"source": [
"mask = low_below_lband.vbt.signals.first(after_false=True)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d22b9fb1-2757-4fe9-b257-233e8a6428b9",
"metadata": {},
"outputs": [],
"source": [
"sample_low = pd.Series([10, 9, 8, 9, 8])\n",
"sample_lband = pd.Series([np.nan, np.nan, 9, 8, 9])\n",
"sample_mask = sample_low < sample_lband\n",
"sample_mask.vbt.signals.first(after_false=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd63d8f4-f71e-4b77-ba9e-f3aa5fab70d3",
"metadata": {},
"outputs": [],
"source": [
"sample_mask[sample_lband.ffill().isnull()] = True\n",
"sample_mask.vbt.signals.first(after_false=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "48ec8914-6279-4e04-9577-7a61123e8f9b",
"metadata": {},
"outputs": [],
"source": [
"buffer = sample_lband.ffill().isnull().sum(axis=0).max()\n",
"buffer"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9e7b37d6-435b-4d05-b813-c71e3533d7f6",
"metadata": {},
"outputs": [],
"source": [
"sample_buf_mask = sample_low.iloc[buffer:] < sample_lband.iloc[buffer:]\n",
"sample_buf_mask = sample_buf_mask.vbt.signals.first(after_false=True)\n",
"sample_mask = sample_low.vbt.wrapper.fill(False)\n",
"sample_mask.loc[sample_buf_mask.index] = sample_buf_mask\n",
"sample_mask"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "497a1101-5e73-4bd3-9d6d-ceb51bd6ac58",
"metadata": {},
"outputs": [],
"source": [
"mask = data.get(\"Low\").vbt.crossed_below(bb.lowerband, wait=1)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e385bd31-4be5-40c8-95eb-23ec488dcff2",
"metadata": {},
"outputs": [],
"source": [
"mask = bb.lowerband_crossed_above(data.get(\"Low\"), wait=1)\n",
"mask.sum()"
]
},
{
"cell_type": "markdown",
"id": "67ac0af5-b8bc-4e4f-8351-e33661778165",
"metadata": {},
"source": [
"### Logical operators"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "931d10e3-7259-49f7-bde3-3c6b11e356d0",
"metadata": {},
"outputs": [],
"source": [
"cond1 = data.get(\"Low\") < bb.lowerband\n",
"cond2 = bandwidth > 0.3\n",
"cond3 = data.get(\"High\") > bb.upperband\n",
"cond4 = bandwidth < 0.15\n",
"\n",
"mask = (cond1 & cond2) | (cond3 & cond4)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7a8e5bb5-3a3f-4e95-8805-78dbeb73e119",
"metadata": {},
"outputs": [],
"source": [
"cond1 = data.get(\"Low\").vbt < bb.lowerband\n",
"cond2 = bandwidth.vbt > vbt.Param([0.3, 0.3, 0.4, 0.4], name=\"cond2_th\")\n",
"cond3 = data.get(\"High\").vbt > bb.upperband\n",
"cond4 = bandwidth.vbt < vbt.Param([0.1, 0.2, 0.1, 0.2], name=\"cond4_th\")\n",
"\n",
"mask = (cond1.vbt & cond2).vbt | (cond3.vbt & cond4)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "96fec8a9-27fe-4ec0-9745-06b612a8beeb",
"metadata": {},
"outputs": [],
"source": [
"cond1 = data.get(\"Low\").vbt < bb.lowerband\n",
"cond2 = bandwidth.vbt > vbt.Param([0.3, 0.4], name=\"cond2_th\")\n",
"cond3 = data.get(\"High\").vbt > bb.upperband\n",
"cond4 = bandwidth.vbt < vbt.Param([0.1, 0.2], name=\"cond4_th\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "553a64f0-a358-4e98-a0f6-e05d44ba84be",
"metadata": {},
"outputs": [],
"source": [
"i1 = np.split(np.arange(len(cond1.columns)), len(cond1.columns) // 2)\n",
"i2 = np.split(np.arange(len(cond2.columns)), len(cond2.columns) // 2)\n",
"i3 = np.split(np.arange(len(cond3.columns)), len(cond3.columns) // 2)\n",
"i4 = np.split(np.arange(len(cond4.columns)), len(cond4.columns) // 2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "55799254-e8c1-4b67-aba1-a7015ebe5b92",
"metadata": {},
"outputs": [],
"source": [
"print(i1)\n",
"print(i2)\n",
"print(i3)\n",
"print(i4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6cef9c96-52bf-42be-8c70-750c39bea02a",
"metadata": {},
"outputs": [],
"source": [
"i1, i2, i3, i4 = zip(*product(i1, i2, i3, i4))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7348da68-f874-4334-88ac-be80db0ec4e7",
"metadata": {},
"outputs": [],
"source": [
"print(i1)\n",
"print(i2)\n",
"print(i3)\n",
"print(i4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f055cbef-62ef-4958-a6c2-9c253e023e9d",
"metadata": {},
"outputs": [],
"source": [
"i1 = np.asarray(i1).flatten()\n",
"i2 = np.asarray(i2).flatten()\n",
"i3 = np.asarray(i3).flatten()\n",
"i4 = np.asarray(i4).flatten()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f7941975-2907-4a19-811f-e98848822d66",
"metadata": {},
"outputs": [],
"source": [
"print(i1)\n",
"print(i2)\n",
"print(i3)\n",
"print(i4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8ed4ad6f-3182-4da6-9bfa-8ecb705af57e",
"metadata": {},
"outputs": [],
"source": [
"cond1 = cond1.iloc[:, i1]\n",
"cond2 = cond2.iloc[:, i2]\n",
"cond3 = cond3.iloc[:, i3]\n",
"cond4 = cond4.iloc[:, i4]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "38fb824d-8aa5-494d-b2f8-bea49e2d584e",
"metadata": {},
"outputs": [],
"source": [
"mask = (cond1.vbt & cond2).vbt | (cond3.vbt & cond4)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e5545a3-b347-41de-bee5-9954ff2b0698",
"metadata": {},
"outputs": [],
"source": [
"MaskGenerator = vbt.IF.from_expr(\"\"\"\n",
"upperband, middleband, lowerband = @res_talib_bbands\n",
"bandwidth = (upperband - lowerband) / middleband\n",
"cond1 = low < lowerband\n",
"cond2 = bandwidth > @p_cond2_th\n",
"cond3 = high > upperband\n",
"cond4 = bandwidth < @p_cond4_th\n",
"@out_mask:(cond1 & cond2) | (cond3 & cond4)\n",
"\"\"\")\n",
"\n",
"print(vbt.format_func(MaskGenerator.run, incl_doc=False))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3bbbab02-1e9e-497c-8616-cbfaa19cd39e",
"metadata": {},
"outputs": [],
"source": [
"mask_generator = MaskGenerator.run(\n",
" high=data.get(\"High\"),\n",
" low=data.get(\"Low\"),\n",
" close=data.get(\"Close\"),\n",
" cond2_th=[0.3, 0.4],\n",
" cond4_th=[0.1, 0.2],\n",
" bbands_timeperiod=vbt.Default(14),\n",
" param_product=True\n",
")\n",
"mask_generator.mask.sum()"
]
},
{
"cell_type": "markdown",
"id": "8d6deb30-8e48-48e1-b06e-699454a28098",
"metadata": {},
"source": [
"### Shifting"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "58f200ec-96b8-450b-afc4-76307bf59549",
"metadata": {},
"outputs": [],
"source": [
"cond1 = data.get(\"Low\") < bb.lowerband\n",
"cond2 = bandwidth > bandwidth.shift(1)\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "efef3852-ba5a-4670-8ccf-cb51e5d41432",
"metadata": {},
"outputs": [],
"source": [
"cond2 = bandwidth > bandwidth.rolling(\"7d\").apply(lambda x: x[0])\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5b308a3e-f8e8-46b0-b016-2aa1933dc44d",
"metadata": {},
"outputs": [],
"source": [
"def exactly_ago(sr):\n",
" if sr.index[0] == sr.index[-1] - vbt.timedelta(\"7d\"):\n",
" return sr.iloc[0]\n",
" return np.nan\n",
"\n",
"cond_7d_ago = bandwidth.rolling(\"8d\").apply(exactly_ago, raw=False)\n",
"cond2 = bandwidth > cond_7d_ago\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a41f9fe9-51d8-420b-8352-2238cf58208f",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def exactly_ago_meta_nb(from_i, to_i, col, index, freq, arr):\n",
" if index[from_i] == index[to_i - 1] - freq:\n",
" return arr[from_i, col]\n",
" return np.nan\n",
"\n",
"cond_7d_ago = vbt.pd_acc.rolling_apply(\n",
" \"8d\",\n",
" exactly_ago_meta_nb,\n",
" bandwidth.index.values,\n",
" vbt.timedelta(\"7d\").to_timedelta64(),\n",
" vbt.to_2d_array(bandwidth),\n",
" wrapper=bandwidth.vbt.wrapper\n",
")\n",
"cond2 = bandwidth > cond_7d_ago\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fa58a149-9754-41da-ab53-e7642d0c3410",
"metadata": {},
"outputs": [],
"source": [
"cond2 = bandwidth > bandwidth.vbt.ago(\"7d\")\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ae73e445-ca38-4b64-acee-daed9f4ba6fe",
"metadata": {},
"outputs": [],
"source": [
"bandwidth.iloc[-8]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bba2e968-9d6a-422a-a88f-abad435da438",
"metadata": {},
"outputs": [],
"source": [
"bandwidth.vbt.ago(\"7d\").iloc[-1]"
]
},
{
"cell_type": "markdown",
"id": "50937a93-0f50-47c2-a28f-578baa33609a",
"metadata": {},
"source": [
"### Truth value testing"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f1e5ab80-5cda-46cf-8a30-d20ab4ab9aab",
"metadata": {},
"outputs": [],
"source": [
"cond2 = data.get(\"Close\").vbt.crossed_below(bb.middleband)\n",
"cond2 = cond2.rolling(5, min_periods=1).max().astype(bool)\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4a4231aa-0152-4aba-b1ff-b40c98f2f196",
"metadata": {},
"outputs": [],
"source": [
"cond2 = data.get(\"Close\").vbt.crossed_below(bb.middleband)\n",
"cond2 = cond2.vbt.rolling_any(5)\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "df8a2ad1-3ba1-4b81-8d63-ebca8e656a2b",
"metadata": {},
"outputs": [],
"source": [
"cond2 = data.get(\"Close\").vbt.crossed_below(bb.middleband)\n",
"cond2 = cond2.vbt.rolling_apply(\n",
" \"W\", \"any\", \n",
" minp=1, \n",
" wrap_kwargs=dict(fillna=0, dtype=bool)\n",
")\n",
"\n",
"mask = cond1 & cond2\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39b1b59c-d0ad-4757-bfe6-789a12e11026",
"metadata": {},
"outputs": [],
"source": [
"anchor_points = data.wrapper.get_index_points(\n",
" every=\"M\", \n",
" start=0, \n",
" exact_start=True\n",
")\n",
"anchor_points"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d6b79fd8-b86e-486b-8e87-663e2ddff2c9",
"metadata": {},
"outputs": [],
"source": [
"left_bound = np.full(len(data.wrapper.index), np.nan)\n",
"left_bound[anchor_points] = anchor_points\n",
"left_bound = vbt.dt.to_ns(vbt.nb.ffill_1d_nb(left_bound))\n",
"left_bound = bandwidth.index[left_bound]\n",
"left_bound"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "86481972-0ab1-4f65-9fa3-4c3a7f38d3a1",
"metadata": {},
"outputs": [],
"source": [
"right_bound = data.wrapper.index\n",
"right_bound"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5177843a-f65a-42ba-9e1d-c1744aee9e7b",
"metadata": {},
"outputs": [],
"source": [
"mask = (bandwidth <= 0.1).vbt.resample_between_bounds(\n",
" left_bound, \n",
" right_bound,\n",
" \"any\",\n",
" closed_lbound=True,\n",
" closed_rbound=True,\n",
" wrap_with_lbound=False,\n",
" wrap_kwargs=dict(fillna=0, dtype=bool)\n",
")\n",
"mask.index = right_bound\n",
"mask.astype(int).vbt.ts_heatmap().show_svg()"
]
},
{
"cell_type": "markdown",
"id": "73d0ca33-a66b-4fe6-8e7d-144df6bd0882",
"metadata": {},
"source": [
"### Periodically"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a27fa7cc-6c65-4ff4-aebf-aacdaf160ca1",
"metadata": {},
"outputs": [],
"source": [
"min_data = vbt.BinanceData.pull(\n",
" [\"BTCUSDT\", \"ETHUSDT\"], \n",
" start=\"2021-01-01 UTC\",\n",
" end=\"2021-02-01 UTC\",\n",
" timeframe=\"1h\"\n",
")\n",
"index = min_data.wrapper.index\n",
"tuesday_index = index[index.weekday == 1]\n",
"tuesday_index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "61283286-8bc4-4a67-8385-54b88926b078",
"metadata": {},
"outputs": [],
"source": [
"tuesday_1800_index = tuesday_index[tuesday_index.hour == 18]\n",
"tuesday_1800_index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8c1f8c57-df34-4cd0-99b3-f9511f987f99",
"metadata": {},
"outputs": [],
"source": [
"tuesday_1730_index = index[\n",
" (index.weekday == 1) & \n",
" (index.hour == 17) & \n",
" (index.minute == 30)\n",
"]\n",
"tuesday_1730_index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "52657759-5799-4aae-ac79-cd588037fcea",
"metadata": {},
"outputs": [],
"source": [
"index.get_indexer([vbt.timestamp(\"2021-01-07\", tz=index.tz)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7e13344f-4c60-4e46-a2ff-9dcecc989475",
"metadata": {},
"outputs": [],
"source": [
"index.get_indexer([vbt.timestamp(\"2021-01-07 17:30:00\", tz=index.tz)]) "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bbdd67e5-4b86-4e5a-86f3-d2c123f3bf01",
"metadata": {},
"outputs": [],
"source": [
"index[index.get_indexer(\n",
" [vbt.timestamp(\"2021-01-07 17:30:00\", tz=index.tz)],\n",
" method=\"ffill\"\n",
")]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "241ed072-2873-4f0b-9cba-7fa5d8bd5401",
"metadata": {},
"outputs": [],
"source": [
"index[index.get_indexer(\n",
" [vbt.timestamp(\"2021-01-07 17:30:00\", tz=index.tz)],\n",
" method=\"bfill\"\n",
")]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e31841d0-3c4a-4967-a0a1-62b5c680cd85",
"metadata": {},
"outputs": [],
"source": [
"each_tuesday = vbt.date_range(index[0], index[-1], freq=\"tuesday\")\n",
"each_tuesday_1730 = each_tuesday + pd.Timedelta(hours=17, minutes=30)\n",
"each_tuesday_1730"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21d5f7eb-f18e-4327-8d20-9cdc72cad6d8",
"metadata": {},
"outputs": [],
"source": [
"positions = index.get_indexer(each_tuesday_1730, method=\"bfill\")\n",
"\n",
"min_symbol_wrapper = min_data.get_symbol_wrapper()\n",
"mask = min_symbol_wrapper.fill(False)\n",
"mask.iloc[positions] = True\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bfadfca9-23df-4372-aab6-ecfb9e5c4046",
"metadata": {},
"outputs": [],
"source": [
"mask[mask.any(axis=1)].index.strftime(\"%A %T\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1206dc67-91f7-4207-ae3e-05e579576fe3",
"metadata": {},
"outputs": [],
"source": [
"tuesday_after_1700 = (index.weekday == 1) & (index.hour >= 17)\n",
"wednesday_before_1700 = (index.weekday == 2) & (index.hour < 17)\n",
"main_cond = tuesday_after_1700 | wednesday_before_1700\n",
"mask = min_symbol_wrapper.fill(False)\n",
"mask[main_cond] = True\n",
"mask = mask.vbt.signals.first()\n",
"mask[mask.any(axis=1)].index.strftime(\"%A %T\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e011aa6b-94a2-4a76-a3e6-f2998e4bdc5e",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set(\n",
" True, \n",
" every=\"tuesday\", \n",
" at_time=\"17:30\", \n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index.strftime(\"%A %T\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3849cd8e-63ab-4603-b84a-ea2f0e0cb282",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set(\n",
" True, \n",
" every=\"tuesday\", \n",
" at_time=\"18:00\", \n",
" add_delta=pd.Timedelta(nanoseconds=1),\n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index.strftime(\"%A %T\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0bcd77bd-b5f9-4e03-8a1b-a2f1646d2887",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set_between(\n",
" True, \n",
" every=\"monday\", \n",
" start_time=\"12:00\", \n",
" end_time=\"17:00\", \n",
" add_end_delta=pd.Timedelta(days=1),\n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index.strftime(\"%A %T\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0335ab31-4ae0-4e2d-be6e-412949468b6f",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set(\n",
" True, \n",
" on=\"January 7th 2021 UTC\",\n",
" indexer_method=None,\n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8383ce7c-dda3-472c-af61-5b1f33b67b3f",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set_between(\n",
" True, \n",
" start=[\"2021-01-01 12:00:00\", \"2021-01-07 12:00:00\"],\n",
" end=[\"2021-01-02 12:00:00\", \"2021-01-08 12:00:00\"],\n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1be65183-69dc-4576-925f-ba51c2d9b16d",
"metadata": {},
"outputs": [],
"source": [
"mask = min_symbol_wrapper.fill(False)\n",
"mask.vbt.set_between(\n",
" True, \n",
" every=\"monday\",\n",
" split_every=False,\n",
" add_end_delta=\"2h\",\n",
" inplace=True\n",
")\n",
"mask[mask.any(axis=1)].index"
]
},
{
"cell_type": "markdown",
"id": "0942b710-9089-4203-812c-087c90458e50",
"metadata": {},
"source": [
"### Iteratively"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9da35717-67da-421a-acf7-e3e1a81d34f1",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def generate_mask_1d_nb(\n",
" high, low,\n",
" uband, mband, lband,\n",
" cond2_th, cond4_th\n",
"):\n",
" out = np.full(high.shape, False)\n",
" \n",
" for i in range(high.shape[0]):\n",
"\n",
" \n",
" bandwidth = (uband[i] - lband[i]) / mband[i]\n",
" cond1 = low[i] < lband[i]\n",
" cond2 = bandwidth > cond2_th\n",
" cond3 = high[i] > uband[i]\n",
" cond4 = bandwidth < cond4_th\n",
" signal = (cond1 and cond2) or (cond3 and cond4)\n",
" \n",
" out[i] = signal\n",
" \n",
" return out\n",
"\n",
"mask = generate_mask_1d_nb(\n",
" data.get(\"High\")[\"BTCUSDT\"].values,\n",
" data.get(\"Low\")[\"BTCUSDT\"].values,\n",
" bb.upperband[\"BTCUSDT\"].values,\n",
" bb.middleband[\"BTCUSDT\"].values,\n",
" bb.lowerband[\"BTCUSDT\"].values,\n",
" 0.30,\n",
" 0.15\n",
")\n",
"symbol_wrapper = data.get_symbol_wrapper()\n",
"mask = symbol_wrapper[\"BTCUSDT\"].wrap(mask)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ff27246a-d96c-428a-a391-56decc8a457c",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def generate_mask_nb(\n",
" high, low,\n",
" uband, mband, lband,\n",
" cond2_th, cond4_th\n",
"):\n",
" out = np.empty(high.shape, dtype=np.bool_)\n",
" \n",
" for col in range(high.shape[1]):\n",
" out[:, col] = generate_mask_1d_nb(\n",
" high[:, col], low[:, col],\n",
" uband[:, col], mband[:, col], lband[:, col],\n",
" cond2_th, cond4_th\n",
" )\n",
" \n",
" return out\n",
"\n",
"mask = generate_mask_nb(\n",
" vbt.to_2d_array(data.get(\"High\")),\n",
" vbt.to_2d_array(data.get(\"Low\")),\n",
" vbt.to_2d_array(bb.upperband),\n",
" vbt.to_2d_array(bb.middleband),\n",
" vbt.to_2d_array(bb.lowerband),\n",
" 0.30,\n",
" 0.15\n",
")\n",
"mask = symbol_wrapper.wrap(mask)\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7e38705d-863f-40c7-bfad-127b7551999d",
"metadata": {},
"outputs": [],
"source": [
"MaskGenerator = vbt.IF(\n",
" input_names=[\"high\", \"low\", \"uband\", \"mband\", \"lband\"],\n",
" param_names=[\"cond2_th\", \"cond4_th\"],\n",
" output_names=[\"mask\"]\n",
").with_apply_func(generate_mask_1d_nb, takes_1d=True)\n",
"mask_generator = MaskGenerator.run(\n",
" data.get(\"High\"),\n",
" data.get(\"Low\"),\n",
" bb.upperband,\n",
" bb.middleband,\n",
" bb.lowerband,\n",
" [0.3, 0.4],\n",
" [0.1, 0.2],\n",
" param_product=True\n",
")\n",
"mask_generator.mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d2989ca1-0925-4d8f-bfb1-82606aed0d80",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def value_ago_1d_nb(arr, ago):\n",
" out = np.empty(arr.shape, dtype=np.float_)\n",
" for i in range(out.shape[0]):\n",
" if i - ago >= 0:\n",
" out[i] = arr[i - ago]\n",
" else:\n",
" out[i] = np.nan\n",
" return out\n",
"\n",
"arr = np.array([1, 2, 3])\n",
"value_ago_1d_nb(arr, 1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24455bb7-98c0-45c1-9333-78c9424838ef",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def any_in_window_1d_nb(arr, window):\n",
" out = np.empty(arr.shape, dtype=np.bool_)\n",
" for i in range(out.shape[0]):\n",
" from_i = max(0, i + 1 - window)\n",
" to_i = i + 1\n",
" out[i] = np.any(arr[from_i:to_i])\n",
" return out\n",
"\n",
"arr = np.array([False, True, True, False, False])\n",
"any_in_window_1d_nb(arr, 2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a4cf9d70-b97c-4c47-b65a-8a4c13f4ab9f",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def any_in_var_window_1d_nb(arr, index, freq):\n",
" out = np.empty(arr.shape, dtype=np.bool_)\n",
" from_i = 0\n",
" for i in range(out.shape[0]):\n",
" if index[from_i] <= index[i] - freq:\n",
" for j in range(from_i + 1, index.shape[0]):\n",
" if index[j] > index[i] - freq:\n",
" from_i = j\n",
" break\n",
" to_i = i + 1\n",
" out[i] = np.any(arr[from_i:to_i])\n",
" return out\n",
"\n",
"arr = np.array([False, True, True, False, False])\n",
"index = vbt.date_range(\"2020\", freq=\"5min\", periods=len(arr)).values\n",
"freq = vbt.timedelta(\"10min\").to_timedelta64()\n",
"any_in_var_window_1d_nb(arr, index, freq)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3fd6c643-a018-4f56-a52d-2352a5ecb430",
"metadata": {},
"outputs": [],
"source": [
"any_in_var_window_1d_nb(arr, vbt.dt.to_ns(index), vbt.dt.to_ns(freq))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2a375903-eea0-4bd1-b46f-d71c0dbc719c",
"metadata": {},
"outputs": [],
"source": [
"vbt.dt.to_ns(index)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e32610d0-01e8-4d4d-a3e6-b83218a8e877",
"metadata": {},
"outputs": [],
"source": [
"vbt.dt.to_ns(index - np.datetime64(0, \"ns\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b775b6a0-2e64-4027-b84a-9aed88e0ae66",
"metadata": {},
"outputs": [],
"source": [
"vbt.dt.to_ns(freq)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "20a5f083-2f52-436e-9d23-3a0ef67d929d",
"metadata": {},
"outputs": [],
"source": [
"vbt.dt.to_ns(freq) / 1000 / 1000 / 1000 / 60"
]
},
{
"cell_type": "markdown",
"id": "d1dc72ab-3858-49a0-93c2-a7d37c8073c7",
"metadata": {},
"source": [
"### Generators"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6bb839a-61f5-44be-8643-495078dbd208",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def place_func_nb(c, index):\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" weekday = vbt.dt_nb.weekday_nb(index[i])\n",
" hour = vbt.dt_nb.hour_nb(index[i])\n",
" if weekday == 2 and hour == 17:\n",
" c.out[out_i] = True\n",
" return out_i\n",
" return -1\n",
"\n",
"mask = vbt.pd_acc.signals.generate(\n",
" symbol_wrapper.shape,\n",
" place_func_nb,\n",
" vbt.dt.to_ns(symbol_wrapper.index),\n",
" wrapper=symbol_wrapper\n",
")\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b3124c4b-c02c-4e0e-9362-5c5b8114dd1b",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def place_func_nb(c, index):\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" weekday = vbt.dt_nb.weekday_nb(index[i])\n",
" hour = vbt.dt_nb.hour_nb(index[i])\n",
" if weekday == 2 and hour == 17:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" else:\n",
" past_target_midnight = vbt.dt_nb.past_weekday_nb(index[i], 2)\n",
" past_target = past_target_midnight + 17 * vbt.dt_nb.h_ns\n",
" if (i > 0 and index[i - 1] < past_target) and \\\n",
" index[i] > past_target:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" return last_i\n",
"\n",
"mask = vbt.pd_acc.signals.generate(\n",
" symbol_wrapper.shape,\n",
" place_func_nb,\n",
" vbt.dt.to_ns(symbol_wrapper.index),\n",
" wrapper=symbol_wrapper\n",
")\n",
"mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dce0bdc1-7956-4760-9b29-05cb8a7d13b6",
"metadata": {},
"outputs": [],
"source": [
"mask.index[mask.any(axis=1)].strftime('%A %m/%d/%Y')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c1a5a0e2-23cd-48d3-ab36-2f94d8a03adc",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def place_func_nb(c, weekday, hour, index):\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" weekday_now = vbt.dt_nb.weekday_nb(index[i])\n",
" hour_now = vbt.dt_nb.hour_nb(index[i])\n",
" if weekday_now == weekday and hour_now == hour:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" return last_i\n",
"\n",
"EntryGenerator = vbt.SignalFactory(\n",
" mode=\"entries\",\n",
" param_names=[\"weekday\", \"hour\"]\n",
").with_place_func(\n",
" entry_place_func_nb=place_func_nb,\n",
" entry_settings=dict(\n",
" pass_params=[\"weekday\", \"hour\"],\n",
" ),\n",
" var_args=True\n",
")\n",
"entry_generator = EntryGenerator.run(\n",
" symbol_wrapper.shape,\n",
" 2, \n",
" [0, 17],\n",
" vbt.dt.to_ns(symbol_wrapper.index),\n",
" input_index=symbol_wrapper.index,\n",
" input_columns=symbol_wrapper.columns\n",
")\n",
"entry_generator.entries.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f29a5bde-9025-4946-932d-94d23e4b5ac0",
"metadata": {},
"outputs": [],
"source": [
"entry_generator.plot(column=(2, 0, \"BTCUSDT\")).show_svg()"
]
},
{
"cell_type": "markdown",
"id": "21f7b441-5d5a-4ac9-93bb-e0289eefa5d6",
"metadata": {},
"source": [
"#### Exits"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a58d3a9-e3fa-4839-908d-e6d8a0009e04",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def exit_place_func_nb(c):\n",
" c.out[0] = True\n",
" return 0\n",
"\n",
"entries = symbol_wrapper.fill(False)\n",
"entries.vbt.set(True, every=\"Q\", inplace=True)\n",
"entries.index[entries.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "03872da1-6712-4f1e-809d-92303661364e",
"metadata": {},
"outputs": [],
"source": [
"exits = entries.vbt.signals.generate_exits(exit_place_func_nb)\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c80edcb4-602b-48e8-bf7b-98e805259758",
"metadata": {},
"outputs": [],
"source": [
"exits = entries.vbt.signals.generate_exits(\n",
" exit_place_func_nb,\n",
" wait=0\n",
")\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "02c6a9cc-13f0-4998-8992-61110ea2d66f",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def exit_place_func_nb(c, index, wait_td):\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" if index[i] >= index[c.from_i] + wait_td:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" break\n",
" return last_i\n",
"\n",
"exits = entries.vbt.signals.generate_exits(\n",
" exit_place_func_nb,\n",
" vbt.dt.to_ns(entries.index),\n",
" vbt.dt.to_ns(vbt.timedelta(\"7d\")),\n",
" wait=0\n",
")\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da4bdca3-d5e6-47f4-bf53-9ac89228df0a",
"metadata": {},
"outputs": [],
"source": [
"entries = symbol_wrapper.fill(False)\n",
"entries.vbt.set(True, every=\"5d\", inplace=True)\n",
"exits = entries.vbt.signals.generate_exits(\n",
" exit_place_func_nb,\n",
" vbt.dt.to_ns(entries.index),\n",
" vbt.dt.to_ns(vbt.timedelta(\"7d\")),\n",
" wait=0\n",
")\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6690a670-24a5-4eb9-8552-16f845ab3c50",
"metadata": {},
"outputs": [],
"source": [
"exits = entries.vbt.signals.generate_exits(\n",
" exit_place_func_nb,\n",
" vbt.dt.to_ns(entries.index),\n",
" vbt.dt.to_ns(vbt.timedelta(\"7d\")),\n",
" wait=0,\n",
" until_next=False\n",
")\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b3729138-f008-4371-883f-31240e1aadb3",
"metadata": {},
"outputs": [],
"source": [
"exits = entries.vbt.signals.generate_exits(\n",
" exit_place_func_nb,\n",
" vbt.dt.to_ns(entries.index),\n",
" vbt.dt.to_ns(vbt.timedelta(\"7d\")),\n",
" wait=0,\n",
" until_next=False,\n",
" skip_until_exit=True\n",
")\n",
"exits.index[exits.any(axis=1)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "939bb536-1973-4798-9f9e-bb65314a6f31",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def exit_place_func_nb(c, wait_td, index):\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" if index[i] >= index[c.from_i] + wait_td:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" break\n",
" return last_i\n",
"\n",
"ExitGenerator = vbt.SignalFactory(\n",
" mode=\"exits\",\n",
" param_names=[\"wait_td\"]\n",
").with_place_func(\n",
" exit_place_func_nb=exit_place_func_nb,\n",
" exit_settings=dict(\n",
" pass_params=[\"wait_td\"],\n",
" ),\n",
" var_args=True,\n",
" wait=0,\n",
" until_next=False,\n",
" skip_until_exit=True,\n",
" param_settings=dict(\n",
" wait_td=dict(\n",
" post_index_func=lambda x: x.map(lambda y: str(vbt.timedelta(y)))\n",
" )\n",
" ),\n",
")\n",
"exit_generator = ExitGenerator.run(\n",
" entries,\n",
" [\n",
" vbt.timedelta(\"3d\").to_timedelta64(),\n",
" vbt.timedelta(\"7d\").to_timedelta64()\n",
" ],\n",
" symbol_wrapper.index.values\n",
")\n",
"exit_generator.exits.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de964714-e321-4d79-bfe1-b466a087b293",
"metadata": {},
"outputs": [],
"source": [
"new_entries = exit_generator.entries.vbt.signals.first(\n",
" reset_by=exit_generator.exits,\n",
" allow_gaps=True, \n",
")\n",
"new_entries.index[new_entries[(\"7 days 00:00:00\", \"BTCUSDT\")]]"
]
},
{
"cell_type": "markdown",
"id": "5b97e203-9f56-4390-a5cd-30ee65beb85f",
"metadata": {},
"source": [
"#### Both"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d838e1e5-0060-4a04-8c33-4c1f96e701a4",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def entry_place_func_nb(c, low, close, th):\n",
" if c.from_i == 0:\n",
" c.out[0] = True\n",
" return 0\n",
" exit_price = close[c.from_i - c.wait, c.col]\n",
" hit_price = exit_price * (1 - th)\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" if low[i, c.col] <= hit_price:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" break\n",
" return last_i\n",
"\n",
"@njit\n",
"def exit_place_func_nb(c, high, close, th):\n",
" entry_price = close[c.from_i - c.wait, c.col]\n",
" hit_price = entry_price * (1 + th)\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" if high[i, c.col] >= hit_price:\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" break\n",
" return last_i\n",
"\n",
"entries, exits = vbt.pd_acc.signals.generate_both(\n",
" symbol_wrapper.shape,\n",
" entry_place_func_nb=entry_place_func_nb,\n",
" entry_place_args=(vbt.Rep(\"low\"), vbt.Rep(\"close\"), 0.1),\n",
" exit_place_func_nb=exit_place_func_nb,\n",
" exit_place_args=(vbt.Rep(\"high\"), vbt.Rep(\"close\"), 0.2),\n",
" wrapper=symbol_wrapper,\n",
" broadcast_named_args=dict(\n",
" high=data.get(\"High\"),\n",
" low=data.get(\"Low\"),\n",
" close=data.get(\"Close\")\n",
" ),\n",
" broadcast_kwargs=dict(\n",
" post_func=vbt.to_2d_array\n",
" )\n",
")\n",
"\n",
"fig = data.plot(\n",
" symbol=\"BTCUSDT\", \n",
" ohlc_trace_kwargs=dict(opacity=0.5), \n",
" plot_volume=False\n",
")\n",
"entries[\"BTCUSDT\"].vbt.signals.plot_as_entries(\n",
" y=data.get(\"Close\", \"BTCUSDT\"), fig=fig)\n",
"exits[\"BTCUSDT\"].vbt.signals.plot_as_exits(\n",
" y=data.get(\"Close\", \"BTCUSDT\"), fig=fig)\n",
"fig.show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1241ad12-8874-43f9-868f-337dba360343",
"metadata": {},
"outputs": [],
"source": [
"BothGenerator = vbt.SignalFactory(\n",
" mode=\"both\",\n",
" input_names=[\"high\", \"low\", \"close\"],\n",
" param_names=[\"entry_th\", \"exit_th\"]\n",
").with_place_func(\n",
" entry_place_func_nb=entry_place_func_nb,\n",
" entry_settings=dict(\n",
" pass_inputs=[\"low\", \"close\"],\n",
" pass_params=[\"entry_th\"],\n",
" ),\n",
" exit_place_func_nb=exit_place_func_nb,\n",
" exit_settings=dict(\n",
" pass_inputs=[\"high\", \"close\"],\n",
" pass_params=[\"exit_th\"],\n",
" )\n",
")\n",
"both_generator = BothGenerator.run(\n",
" data.get(\"High\"),\n",
" data.get(\"Low\"),\n",
" data.get(\"Close\"),\n",
" [0.1, 0.2],\n",
" [0.2, 0.3],\n",
" param_product=True\n",
")\n",
"fig = data.plot(\n",
" symbol=\"BTCUSDT\", \n",
" ohlc_trace_kwargs=dict(opacity=0.5), \n",
" plot_volume=False\n",
")\n",
"both_generator.plot(\n",
" column=(0.1, 0.3, \"BTCUSDT\"), \n",
" entry_y=data.get(\"Close\", \"BTCUSDT\"), \n",
" exit_y=data.get(\"Close\", \"BTCUSDT\"), \n",
" fig=fig\n",
").show_svg()"
]
},
{
"cell_type": "markdown",
"id": "b3e76f00-2927-4af1-90e3-2c288f81225a",
"metadata": {},
"source": [
"#### Chained exits"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "92d515cf-394e-4b2a-b5c9-8a7c702e9f45",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def exit_place_func_nb(c, low, request_price, fill_price_out):\n",
" _request_price = request_price[c.from_i - c.wait, c.col]\n",
" last_i = -1\n",
" for out_i in range(len(c.out)):\n",
" i = c.from_i + out_i\n",
" if low[i, c.col] <= _request_price:\n",
" fill_price_out[i, c.col] = _request_price\n",
" c.out[out_i] = True\n",
" last_i = out_i\n",
" break\n",
" return last_i\n",
"\n",
"ChainGenerator = vbt.SignalFactory(\n",
" mode=\"chain\",\n",
" input_names=[\"low\", \"request_price\"],\n",
" in_output_names=[\"fill_price_out\"]\n",
").with_place_func(\n",
" exit_place_func_nb=exit_place_func_nb,\n",
" exit_settings=dict(\n",
" pass_inputs=[\"low\", \"request_price\"],\n",
" pass_in_outputs=[\"fill_price_out\"],\n",
" ),\n",
" fill_price_out=np.nan\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "66e50dd1-4984-432a-8a3e-4ca8fa6a6a29",
"metadata": {},
"outputs": [],
"source": [
"fast_ma = vbt.talib(\"SMA\").run(\n",
" data.get(\"Close\"), \n",
" vbt.Default(10), \n",
" short_name=\"fast_ma\"\n",
")\n",
"slow_ma = vbt.talib(\"SMA\").run(\n",
" data.get(\"Close\"), \n",
" vbt.Default(20), \n",
" short_name=\"slow_ma\"\n",
")\n",
"entries = fast_ma.real_crossed_above(slow_ma)\n",
"entries.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "45ad9fbd-9250-463a-b599-7c69eeb1247d",
"metadata": {},
"outputs": [],
"source": [
"chain_generator = ChainGenerator.run(\n",
" entries,\n",
" data.get(\"Low\"),\n",
" data.get(\"Close\") * (1 - 0.1)\n",
")\n",
"request_mask = chain_generator.new_entries\n",
"request_mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f7a80bb3-b778-45df-a375-0df6672cf36b",
"metadata": {},
"outputs": [],
"source": [
"request_price = chain_generator.request_price\n",
"print(request_price[request_mask.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd9c6dd2-5da2-437f-b750-050b031160a1",
"metadata": {},
"outputs": [],
"source": [
"fill_mask = chain_generator.exits\n",
"fill_mask.sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0691fbf4-4b08-43c0-a8ae-6075bdf0af12",
"metadata": {},
"outputs": [],
"source": [
"fill_price = chain_generator.fill_price_out\n",
"print(fill_price[fill_mask.any(axis=1)])"
]
},
{
"cell_type": "markdown",
"id": "0566319a-0cb4-4dd1-81f8-3ed7d2d5f9d6",
"metadata": {},
"source": [
"### Preset generators"
]
},
{
"cell_type": "markdown",
"id": "07b9bd34-8bc7-4383-9b3b-13d8fbb7ae99",
"metadata": {},
"source": [
"#### Random"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0081e390-e918-4edb-ac65-297da562a4a2",
"metadata": {},
"outputs": [],
"source": [
"btcusdt_wrapper = symbol_wrapper[\"BTCUSDT\"]\n",
"mask = vbt.pd_acc.signals.generate_random(\n",
" btcusdt_wrapper.shape,\n",
" prob=1 / 10,\n",
" wrapper=btcusdt_wrapper,\n",
" seed=42\n",
")\n",
"mask_index = mask.index[mask]\n",
"(mask_index[1:] - mask_index[:-1]).mean()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9cca388d-e1d0-4c83-a86b-ec7087d34e05",
"metadata": {},
"outputs": [],
"source": [
"monday_mask = btcusdt_wrapper.fill(False)\n",
"monday_mask.vbt.set(True, every=\"monday\", inplace=True)\n",
"mask = monday_mask.vbt.signals.generate_random_exits(wait=0)\n",
"mask_index = mask.index[mask]\n",
"mask_index.strftime(\"%W %A\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5df8383a-7c16-4d54-8b7a-6695d9b24546",
"metadata": {},
"outputs": [],
"source": [
"prob = np.linspace(0, 1, len(symbol_wrapper.index))\n",
"rprob = vbt.RPROB.run(\n",
" symbol_wrapper.shape,\n",
" vbt.Default(vbt.to_2d_pr_array(prob)),\n",
" seed=42,\n",
" input_index=symbol_wrapper.index,\n",
" input_columns=symbol_wrapper.columns\n",
")\n",
"rprob.entries.astype(int).vbt.ts_heatmap().show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2ecf3d7f-ecb2-4cda-bd89-756d0a278c4c",
"metadata": {},
"outputs": [],
"source": [
"rprob = vbt.RPROB.run(\n",
" symbol_wrapper.shape,\n",
" [0.5, vbt.to_2d_pr_array(prob)],\n",
" seed=42,\n",
" input_index=symbol_wrapper.index,\n",
" input_columns=symbol_wrapper.columns\n",
")\n",
"rprob.entries.sum()"
]
},
{
"cell_type": "markdown",
"id": "1646593e-9669-4757-8df9-3713a8e46ad6",
"metadata": {},
"source": [
"#### Stops"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ecf076e4-697a-4da7-8afa-287820c2c1da",
"metadata": {},
"outputs": [],
"source": [
"new_entries, exits = entries.vbt.signals.generate_stop_exits(\n",
" data.get(\"Close\"),\n",
" data.get(\"High\"),\n",
" stop=0.1,\n",
" chain=True\n",
")\n",
"print(new_entries[new_entries.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe64925a-0fc3-42fa-b128-7f92cb650456",
"metadata": {},
"outputs": [],
"source": [
"print(exits[exits.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e84b01df-1e52-4b51-8d91-5a057bed798a",
"metadata": {},
"outputs": [],
"source": [
"out_dict = {}\n",
"new_entries, exits = entries.vbt.signals.generate_stop_exits(\n",
" data.get(\"Close\"),\n",
" data.get(\"High\"),\n",
" stop=0.1,\n",
" chain=True,\n",
" out_dict=out_dict\n",
")\n",
"print(out_dict[\"stop_ts\"][exits.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "92b3b055-6b0d-4968-8042-943ad3612b38",
"metadata": {},
"outputs": [],
"source": [
"stcx = vbt.STCX.run(\n",
" entries,\n",
" data.get(\"Open\"),\n",
" ts=data.get(\"Low\"),\n",
" follow_ts=data.get(\"High\"),\n",
" stop=-0.1,\n",
" trailing=[False, True],\n",
" wait=0\n",
")\n",
"fig = data.plot(\n",
" symbol=\"BTCUSDT\", \n",
" ohlc_trace_kwargs=dict(opacity=0.5), \n",
" plot_volume=False\n",
")\n",
"stcx.plot(\n",
" column=(-0.1, True, \"BTCUSDT\"), \n",
" entry_y=\"entry_ts\",\n",
" exit_y=\"stop_ts\", \n",
" fig=fig\n",
").show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef68d113-7f90-4b68-810b-d31f6f13e1ea",
"metadata": {},
"outputs": [],
"source": [
"ohlcstcx = vbt.OHLCSTCX.run(\n",
" entries,\n",
" data.get(\"Close\"),\n",
" data.get(\"Open\"),\n",
" data.get(\"High\"),\n",
" data.get(\"Low\"),\n",
" data.get(\"Close\"),\n",
" sl_stop=vbt.Default(0.1),\n",
" tsl_stop=vbt.Default(0.15),\n",
" is_entry_open=False\n",
")\n",
"ohlcstcx.plot(column=(\"BTCUSDT\")).show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "222b01c5-3d86-4c5a-9c1e-dbfdd568407f",
"metadata": {},
"outputs": [],
"source": [
"print(ohlcstcx.stop_type_readable[ohlcstcx.exits.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7b7d0fdc-e793-46be-8559-398c418ccffc",
"metadata": {},
"outputs": [],
"source": [
"ohlcstcx = vbt.OHLCSTCX.run(\n",
" entries,\n",
" data.get(\"Close\"),\n",
" sl_stop=vbt.Default(0.1),\n",
" tsl_stop=vbt.Default(0.15),\n",
" is_entry_open=False\n",
")\n",
"ohlcstcx.plot(column=(\"BTCUSDT\")).show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04992035-5ab7-47c5-b4c1-468bc22221ce",
"metadata": {},
"outputs": [],
"source": [
"entry_pos_rank = entries.vbt.signals.pos_rank(allow_gaps=True)\n",
"short_entries = (entry_pos_rank >= 0) & (entry_pos_rank % 2 == 1)\n",
"\n",
"ohlcstcx = vbt.OHLCSTCX.run(\n",
" entries,\n",
" data.get(\"Close\"),\n",
" data.get(\"Open\"),\n",
" data.get(\"High\"),\n",
" data.get(\"Low\"),\n",
" data.get(\"Close\"),\n",
" tsl_th=vbt.Default(0.2),\n",
" tsl_stop=vbt.Default(0.1),\n",
" reverse=vbt.Default(short_entries),\n",
" is_entry_open=False\n",
")\n",
"ohlcstcx.plot(column=(\"BTCUSDT\")).show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9d5b66ff-5a7f-46da-b515-a8d84c1c2334",
"metadata": {},
"outputs": [],
"source": [
"long_entries = ohlcstcx.new_entries.vbt & (~short_entries)\n",
"long_exits = ohlcstcx.exits.vbt.signals.first_after(long_entries)\n",
"short_entries = ohlcstcx.new_entries.vbt & short_entries\n",
"short_exits = ohlcstcx.exits.vbt.signals.first_after(short_entries)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad0ad046-3df7-4872-b943-03049982ce10",
"metadata": {},
"outputs": [],
"source": [
"fig = data.plot(\n",
" symbol=\"BTCUSDT\", \n",
" ohlc_trace_kwargs=dict(opacity=0.5), \n",
" plot_volume=False\n",
")\n",
"long_entries[\"BTCUSDT\"].vbt.signals.plot_as_entries(\n",
" ohlcstcx.entry_price[\"BTCUSDT\"],\n",
" trace_kwargs=dict(marker=dict(color=\"limegreen\"), name=\"Long entries\"), \n",
" fig=fig\n",
")\n",
"long_exits[\"BTCUSDT\"].vbt.signals.plot_as_exits(\n",
" ohlcstcx.stop_price[\"BTCUSDT\"],\n",
" trace_kwargs=dict(marker=dict(color=\"orange\"), name=\"Long exits\"),\n",
" fig=fig\n",
")\n",
"short_entries[\"BTCUSDT\"].vbt.signals.plot_as_entries(\n",
" ohlcstcx.entry_price[\"BTCUSDT\"],\n",
" trace_kwargs=dict(marker=dict(color=\"magenta\"), name=\"Short entries\"),\n",
" fig=fig\n",
")\n",
"short_exits[\"BTCUSDT\"].vbt.signals.plot_as_exits(\n",
" ohlcstcx.stop_price[\"BTCUSDT\"],\n",
" trace_kwargs=dict(marker=dict(color=\"red\"), name=\"Short exits\"),\n",
" fig=fig\n",
").show_svg()"
]
},
{
"cell_type": "markdown",
"id": "bf356e79-4c3b-4819-ad6e-7f5c556be5fd",
"metadata": {},
"source": [
"## Pre-analysis"
]
},
{
"cell_type": "markdown",
"id": "30097f36-14d4-4a9b-bad9-d0cf8b6668f1",
"metadata": {},
"source": [
"### Ranking"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "13ca8377-310f-4240-babf-5c99023e3d9f",
"metadata": {},
"outputs": [],
"source": [
"@njit\n",
"def rank_func_nb(c):\n",
" if c.sig_in_part_cnt == 1:\n",
" return 1\n",
" return 0\n",
"\n",
"sample_mask = pd.Series([True, True, False, True, True])\n",
"ranked = sample_mask.vbt.signals.rank(rank_func_nb)\n",
"ranked"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7c44fcd0-d678-4ad8-8ef1-99d0f91aad40",
"metadata": {},
"outputs": [],
"source": [
"ranked == 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "693bd2d7-24bf-4c0c-80e4-8665b1649d2d",
"metadata": {},
"outputs": [],
"source": [
"ranked = sample_mask.vbt.signals.rank(rank_func_nb, after_false=True)\n",
"ranked == 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2ba16d6f-f5fa-4bca-b8a5-fa4891c10587",
"metadata": {},
"outputs": [],
"source": [
"sample_entries = pd.Series([True, True, True, True, True])\n",
"sample_exits = pd.Series([False, False, True, False, False])\n",
"ranked = sample_entries.vbt.signals.rank(\n",
" rank_func_nb, \n",
" reset_by=sample_exits\n",
")\n",
"ranked == 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "caff048c-a2ae-4e1f-ab1c-15c60a87a7ec",
"metadata": {},
"outputs": [],
"source": [
"ranked = sample_entries.vbt.signals.rank(\n",
" rank_func_nb, \n",
" reset_by=sample_exits,\n",
" after_reset=True\n",
")\n",
"ranked == 1"
]
},
{
"cell_type": "markdown",
"id": "a973bf32-e451-4786-867e-5c90c82bc6f5",
"metadata": {},
"source": [
"#### Preset rankers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0e2b978-480f-4149-8b31-63004f9ef9b9",
"metadata": {},
"outputs": [],
"source": [
"sample_mask = pd.Series([True, True, False, True, True])\n",
"ranked = sample_mask.vbt.signals.pos_rank()\n",
"ranked"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6415bbd4-2e5d-4484-ab21-0478566513c8",
"metadata": {},
"outputs": [],
"source": [
"ranked == 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d4b19ce3-2a0e-47ff-bc1b-c1a3695cbcaa",
"metadata": {},
"outputs": [],
"source": [
"ranked = sample_mask.vbt.signals.pos_rank(allow_gaps=True)\n",
"ranked"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "369d7a73-c8cb-4579-8f42-28510b948f63",
"metadata": {},
"outputs": [],
"source": [
"(ranked > -1) & (ranked % 2 == 1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "50d51cf9-c42b-4468-a54f-be011327e474",
"metadata": {},
"outputs": [],
"source": [
"ranked = sample_mask.vbt.signals.partition_pos_rank(allow_gaps=True)\n",
"ranked"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7d4864bb-e549-4016-bced-cd39ca4b5b70",
"metadata": {},
"outputs": [],
"source": [
"ranked == 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c624d629-f1fc-4c33-ad43-5c85496cb483",
"metadata": {},
"outputs": [],
"source": [
"entry_cond1 = data.get(\"Low\") < bb.lowerband\n",
"entry_cond2 = bandwidth > 0.3\n",
"entry_cond3 = data.get(\"High\") > bb.upperband\n",
"entry_cond4 = bandwidth < 0.15\n",
"entries = (entry_cond1 & entry_cond2) | (entry_cond3 & entry_cond4)\n",
"\n",
"entries.vbt.signals.from_nth(0).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a8b250d1-ba86-44ba-b532-cd42d261545a",
"metadata": {},
"outputs": [],
"source": [
"entries.vbt.signals.from_nth(1).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "047fbe11-5da9-439f-b5c5-b1109f32fcbf",
"metadata": {},
"outputs": [],
"source": [
"entries.vbt.signals.from_nth(2).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "80f7a1d3-16eb-4aee-bb06-91cc09556a8e",
"metadata": {},
"outputs": [],
"source": [
"exit_cond1 = data.get(\"High\") > bb.upperband\n",
"exit_cond2 = bandwidth > 0.3\n",
"exit_cond3 = data.get(\"Low\") < bb.lowerband\n",
"exit_cond4 = bandwidth < 0.15\n",
"exits = (exit_cond1 & exit_cond2) | (exit_cond3 & exit_cond4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24028cc0-e4f5-4025-a107-38d92c01c4c1",
"metadata": {},
"outputs": [],
"source": [
"exits.vbt.signals.pos_rank_after(entries, reset_wait=0).max() + 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a4b2be2-8e5c-463a-9655-1f420b0017c9",
"metadata": {},
"outputs": [],
"source": [
"entries.vbt.signals.pos_rank_after(exits).max() + 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c0beeb7b-b5c4-4f48-9791-8a0828e956ec",
"metadata": {},
"outputs": [],
"source": [
"ranked = exits.vbt.signals.pos_rank_after(entries, reset_wait=0)\n",
"highest_ranked = ranked == ranked.max()\n",
"print(ranked[highest_ranked.any(axis=1)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "805ef372-1748-4dc4-825a-46e3f55fb3f7",
"metadata": {},
"outputs": [],
"source": [
"exits_after = exits.vbt.signals.from_nth_after(0, entries, reset_wait=0)\n",
"(exits ^ exits_after).sum()"
]
},
{
"cell_type": "markdown",
"id": "0db70553-be70-4a1c-9ce4-92f906ba291b",
"metadata": {},
"source": [
"#### Mapped ranks"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9aeaa467-6a09-4a45-8c4a-abd587c7148d",
"metadata": {},
"outputs": [],
"source": [
"mask = bandwidth.vbt > vbt.Param(np.arange(1, 10) / 10, name=\"bw_th\")\n",
"mapped_ranks = mask.vbt.signals.pos_rank(as_mapped=True)\n",
"mapped_ranks.max(group_by=vbt.ExceptLevel(\"symbol\"))"
]
},
{
"cell_type": "markdown",
"id": "5ef8deef-a5d9-40b0-9819-78dbac8f5b27",
"metadata": {},
"source": [
"### Cleaning"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "402c23ed-0a63-4b9c-b215-ac7dacf083e5",
"metadata": {},
"outputs": [],
"source": [
"new_exits = exits.vbt.signals.first_after(entries, reset_wait=0)\n",
"new_entries = entries.vbt.signals.first_after(exits)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b79491ce-3291-46ee-a2a6-5aa3ac9a2de3",
"metadata": {},
"outputs": [],
"source": [
"symbol = \"ETHUSDT\"\n",
"fig = data.plot(\n",
" symbol=symbol, \n",
" ohlc_trace_kwargs=dict(opacity=0.5), \n",
" plot_volume=False\n",
")\n",
"entries[symbol].vbt.signals.plot_as_entries(\n",
" y=data.get(\"Close\", symbol), fig=fig)\n",
"exits[symbol].vbt.signals.plot_as_exits(\n",
" y=data.get(\"Close\", symbol), fig=fig)\n",
"new_entries[symbol].vbt.signals.plot_as_entry_marks(\n",
" y=data.get(\"Close\", symbol), fig=fig, \n",
" trace_kwargs=dict(name=\"New entries\"))\n",
"new_exits[symbol].vbt.signals.plot_as_exit_marks(\n",
" y=data.get(\"Close\", symbol), fig=fig, \n",
" trace_kwargs=dict(name=\"New exits\")).show_svg()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "883ff6e0-7777-487e-b58b-80bc38f2634c",
"metadata": {},
"outputs": [],
"source": [
"new_entries, new_exits = entries.vbt.signals.clean(exits)"
]
},
{
"cell_type": "markdown",
"id": "82b4e080-808a-4ab3-a700-81ecf0b75d98",
"metadata": {},
"source": [
"### Duration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1b9ac018-2643-4ef5-aded-a617062e726a",
"metadata": {},
"outputs": [],
"source": [
"ranges = entries.vbt.signals.between_ranges()\n",
"print(ranges.records)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aa971658-1359-403b-9e65-a4a3ce390751",
"metadata": {},
"outputs": [],
"source": [
"ranges.start_idx.min(wrap_kwargs=dict(to_index=True))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "35efd36c-c2f2-43c0-af21-9df040ec7cc8",
"metadata": {},
"outputs": [],
"source": [
"print(ranges.duration.describe(wrap_kwargs=dict(to_timedelta=True)))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b944e41-0a8f-498e-82ce-30c46d4b2db6",
"metadata": {},
"outputs": [],
"source": [
"ranges = entries.vbt.signals.between_ranges(target=exits)\n",
"ranges.avg_duration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7b920e56-d16d-400a-9382-a23d63162fda",
"metadata": {},
"outputs": [],
"source": [
"new_ranges = new_entries.vbt.signals.between_ranges(target=new_exits)\n",
"new_ranges.avg_duration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8528ab4c-22b6-4af0-87f5-5c6063bf68c4",
"metadata": {},
"outputs": [],
"source": [
"ranges = entries.vbt.signals.between_ranges(target=exits, relation=\"manyone\")\n",
"ranges.avg_duration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a047b2b8-a27c-4ac0-b124-9f6cfbe513b4",
"metadata": {},
"outputs": [],
"source": [
"new_ranges = new_entries.vbt.signals.between_ranges(target=new_exits, relation=\"manyone\")\n",
"new_ranges.avg_duration"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ab9a53b-2f2e-4601-8e58-c04d86892ee5",
"metadata": {},
"outputs": [],
"source": [
"ranges = entries.vbt.signals.partition_ranges()\n",
"print(ranges.duration.describe())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c35fb94f-04e8-4e6f-a2a4-1f1542d02edb",
"metadata": {},
"outputs": [],
"source": [
"new_ranges = new_entries.vbt.signals.partition_ranges()\n",
"print(new_ranges.duration.describe())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5cdef2ce-f8ef-44c6-8eac-42172560d93c",
"metadata": {},
"outputs": [],
"source": [
"ranges = entries.vbt.signals.between_partition_ranges()\n",
"print(ranges.duration.describe(wrap_kwargs=dict(to_timedelta=True)))"
]
},
{
"cell_type": "markdown",
"id": "541e5a28-aa4f-4056-b4de-6ea7ecdb9064",
"metadata": {},
"source": [
"### Overview"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe7bcbc0-4300-4c7b-a4d6-17e903bb18bb",
"metadata": {},
"outputs": [],
"source": [
"entries.vbt.signals.stats(column=\"BTCUSDT\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a650256c-a112-4ef2-9480-b867ae5b1892",
"metadata": {},
"outputs": [],
"source": [
"entries.vbt.signals.stats(column=\"BTCUSDT\", settings=dict(target=exits))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1cf7ad48-e516-4f88-897b-29cc5a0f7d64",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}