diff --git a/.gitignore b/.gitignore index 7b64a2e..5e77e9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ *.pyo cache/ *.parquet +*.pth \ No newline at end of file diff --git a/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/models.py b/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/models.py new file mode 100644 index 0000000..ffea307 --- /dev/null +++ b/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/models.py @@ -0,0 +1,23 @@ +import torch.nn as nn + +# Simple Linear Model +class LinearModel(nn.Module): + def __init__(self, input_features): + super(LinearModel, self).__init__() + self.linear = nn.Linear(input_features, 1) # Single output (return prediction) + + def forward(self, x): + return self.linear(x) + +# Non-Linear Neural Network Model +class NonLinearModel(nn.Module): + def __init__(self, input_features, hidden_size=64): + super(NonLinearModel, self).__init__() + self.network = nn.Sequential( + nn.Linear(input_features, hidden_size), + nn.ReLU(), # Non-linear activation + nn.Linear(hidden_size , 1) # Output layer + ) + + def forward(self, x): + return self.network(x) \ No newline at end of file diff --git a/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/part1.ipynb b/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/part1.ipynb index 3409506..b7e035d 100644 --- a/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/part1.ipynb +++ b/tutorials/20260622164035_Let's Build a Quant Trading Strategy, MemLabs/part1.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "0ba75c87", "metadata": {}, "outputs": [], @@ -28,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "id": "ee4d8884", "metadata": {}, "outputs": [ @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "id": "390e1b3d", "metadata": {}, "outputs": [], @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "id": "3849b967", "metadata": {}, "outputs": [ @@ -68,7 +68,7 @@ "polars.config.Config" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -89,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "id": "f60cc47e", "metadata": {}, "outputs": [ @@ -118,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "id": "a935f32c", "metadata": {}, "outputs": [ @@ -126,7 +126,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Downloading BTCUSDT: 100%|██████████| 346/346 [00:12<00:00, 27.60it/s]\n" + "Downloading BTCUSDT: 100%|██████████| 346/346 [00:13<00:00, 26.29it/s]\n" ] } ], @@ -138,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "id": "282ade73", "metadata": {}, "outputs": [ @@ -146,7 +146,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Loading BTCUSDT: 100%|██████████| 346/346 [00:19<00:00, 18.01day/s]\n" + "Loading BTCUSDT: 100%|██████████| 346/346 [00:20<00:00, 16.98day/s]\n" ] }, { @@ -182,7 +182,7 @@ "└─────────────────────┴──────────┴──────────┴──────────┴──────────┘" ] }, - "execution_count": 8, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -194,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "id": "2901fe88", "metadata": {}, "outputs": [ @@ -202,7 +202,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Loading BTCUSDT: 100%|██████████| 346/346 [00:19<00:00, 17.43day/s]\n" + "Loading BTCUSDT: 100%|██████████| 346/346 [00:21<00:00, 16.36day/s]\n" ] }, { @@ -238,7 +238,7 @@ "└─────────────────────┴──────────────┘" ] }, - "execution_count": 9, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -249,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 14, "id": "f8d34868", "metadata": {}, "outputs": [ @@ -270,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 15, "id": "ee7b4018", "metadata": {}, "outputs": [ @@ -279,23 +279,23 @@ "text/html": [ "\n", "\n", - "
\n", + "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, - "execution_count": 11, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -370,7 +370,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 16, "id": "fe1ac560", "metadata": {}, "outputs": [ @@ -379,23 +379,23 @@ "text/html": [ "\n", "\n", - "
\n", + "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, - "execution_count": 12, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -462,7 +462,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 17, "id": "497659ef", "metadata": {}, "outputs": [ @@ -491,7 +491,7 @@ "└───────┴───────┴───────────┴────────────┘" ] }, - "execution_count": 13, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -514,7 +514,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "4e5bd81f", "metadata": {}, "outputs": [ @@ -551,7 +551,7 @@ "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┘" ] }, - "execution_count": 16, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -564,7 +564,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "c6f5b2e3", "metadata": {}, "outputs": [ @@ -601,7 +601,7 @@ "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -613,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "ff5f2dd0", "metadata": {}, "outputs": [ @@ -622,23 +622,23 @@ "text/html": [ "\n", "\n", - "
\n", + "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, - "execution_count": 21, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -705,7 +705,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "id": "b32adf51", "metadata": {}, "outputs": [ @@ -714,23 +714,23 @@ "text/html": [ "\n", "\n", - "
\n", + "
\n", "" ], "text/plain": [ "alt.Chart(...)" ] }, - "execution_count": 23, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -805,7 +805,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "id": "5d2b9580", "metadata": {}, "outputs": [], @@ -821,7 +821,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "id": "59fffc10", "metadata": {}, "outputs": [ @@ -852,7 +852,7 @@ "2" ] }, - "execution_count": 25, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -886,7 +886,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "id": "f8317ae6", "metadata": {}, "outputs": [], @@ -898,7 +898,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "id": "c50bddb5", "metadata": {}, "outputs": [ @@ -908,7 +908,7 @@ "8299" ] }, - "execution_count": 27, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -919,7 +919,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "id": "cfc966d3", "metadata": {}, "outputs": [ @@ -929,7 +929,7 @@ "6224" ] }, - "execution_count": 28, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -941,7 +941,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 27, "id": "285aaaf0", "metadata": {}, "outputs": [], @@ -952,7 +952,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 28, "id": "4baefd68", "metadata": {}, "outputs": [ @@ -989,7 +989,7 @@ "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" ] }, - "execution_count": 33, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1000,7 +1000,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 29, "id": "af26db01", "metadata": {}, "outputs": [ @@ -1037,7 +1037,7 @@ "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" ] }, - "execution_count": 34, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1048,7 +1048,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 30, "id": "ef986897", "metadata": {}, "outputs": [], @@ -1061,7 +1061,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 31, "id": "4e29831b", "metadata": {}, "outputs": [ @@ -1077,7 +1077,7 @@ " [ 4.7317e-04]])" ] }, - "execution_count": 36, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1085,6 +1085,2223 @@ "source": [ "X_train" ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "5b98cbfd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([6224, 1])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "e1fa246f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([-0.0007, 0.0030, -0.0031, ..., 0.0025, 0.0005, 0.0007])" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_train" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "8f92af7e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([6224])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "1a28bf47", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[-0.0007],\n", + " [ 0.0030],\n", + " [-0.0031],\n", + " ...,\n", + " [ 0.0025],\n", + " [ 0.0005],\n", + " [ 0.0007]])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_train = y_train.reshape(-1, 1)\n", + "y_train" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "fd23ec92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([6224, 1])" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "2ffc7c12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[ 0.0074],\n", + " [-0.0178],\n", + " [ 0.0036],\n", + " ...,\n", + " [ 0.0030],\n", + " [ 0.0017],\n", + " [-0.0003]])" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_test = y_test.reshape(-1, 1)\n", + "y_test" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "ddd97644", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(tensor([[ 1.9030e-03],\n", + " [-7.2779e-04],\n", + " [ 3.0330e-03],\n", + " ...,\n", + " [-1.3703e-05],\n", + " [ 2.4814e-03],\n", + " [ 4.7317e-04]]),\n", + " tensor([[ 0.0007],\n", + " [ 0.0074],\n", + " [-0.0178],\n", + " ...,\n", + " [ 0.0012],\n", + " [ 0.0030],\n", + " [ 0.0017]]),\n", + " tensor([[-0.0007],\n", + " [ 0.0030],\n", + " [-0.0031],\n", + " ...,\n", + " [ 0.0025],\n", + " [ 0.0005],\n", + " [ 0.0007]]),\n", + " tensor([[ 0.0074],\n", + " [-0.0178],\n", + " [ 0.0036],\n", + " ...,\n", + " [ 0.0030],\n", + " [ 0.0017],\n", + " [-0.0003]]))" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.timeseries_train_test_split(ts, features, target, test_size)" + ] + }, + { + "cell_type": "markdown", + "id": "d7291399", + "metadata": {}, + "source": [ + "### Batch Gradient Descent" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a168dd10", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Training model...\n", + "Epoch [500/5000], Loss: 0.468828\n", + "Epoch [1000/5000], Loss: 0.234599\n", + "Epoch [1500/5000], Loss: 0.101732\n", + "Epoch [2000/5000], Loss: 0.036157\n", + "Epoch [2500/5000], Loss: 0.009766\n", + "Epoch [3000/5000], Loss: 0.001831\n", + "Epoch [3500/5000], Loss: 0.000232\n", + "Epoch [4000/5000], Loss: 0.000041\n", + "Epoch [4500/5000], Loss: 0.000029\n", + "Epoch [5000/5000], Loss: 0.000028\n", + "\n", + "Learned parameters\n", + "linear.weight:\n", + "[[-0.05389139]]\n", + "linear.bias:\n", + "[0.00013368]\n", + "\n", + "Test Loss: 0.000011, Train Loss: 0.000028\n" + ] + } + ], + "source": [ + "# hyperparameters\n", + "no_epochs = 1000 * 5\n", + "lr = 0.0005\n", + "\n", + "# create model\n", + "model = LinearModel(len(features))\n", + "# loss function\n", + "criterion = nn.MSELoss()\n", + "\n", + "# optimizer\n", + "optimizer = optim.Adam(model.parameters(), lr = lr)\n", + "\n", + "print(\"\\nTraining model...\")\n", + "\n", + "for epoch in range(no_epochs):\n", + " # forward pass\n", + " y_hat = model(X_train)\n", + " loss = criterion(y_hat, y_train)\n", + "\n", + " # backward pass\n", + " optimizer.zero_grad() # 1. clear old gradients\n", + " loss.backward() # 2. compute new gradients\n", + " optimizer.step() # 3. update weights\n", + "\n", + " # check for improvement\n", + " train_loss = loss.item()\n", + "\n", + " # logging\n", + " if (epoch + 1) % 500 == 0:\n", + " print(f\"Epoch [{epoch+1}/{no_epochs}], Loss: {train_loss:.6f}\")\n", + "\n", + "print(\"\\nLearned parameters\")\n", + "\n", + "for name, param in model.named_parameters():\n", + " if param.requires_grad:\n", + " print(f\"{name}:\\n{param.data.numpy()}\")\n", + "\n", + "# Evaluation\n", + "model.eval()\n", + "with torch.no_grad():\n", + " y_hat = model(X_test)\n", + " test_loss = criterion(y_hat, y_test)\n", + " print(f\"\\nTest Loss: {test_loss.item():.6f}, Train Loss: {train_loss:.6f}\")\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "fa63132f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (2_075, 6)
y_hatyis_wonsignaltrade_log_returnequity_curve
f32f32boolf32f32f32
0.0000960.007435true1.00.0074350.007435
-0.000267-0.017844true-1.00.0178440.025279
0.0010950.003558true1.00.0035580.028837
-0.0000580.006874false-1.0-0.0068740.021963
-0.0002370.001873false-1.0-0.0018730.02009
0.0002750.002465true1.00.0024650.018513
8.6137e-70.001222true1.00.0012220.019735
0.0000680.002989true1.00.0029890.022724
-0.0000270.001742false-1.0-0.0017420.020982
0.00004-0.000331false1.0-0.0003310.020651
" + ], + "text/plain": [ + "shape: (2_075, 6)\n", + "┌───────────┬───────────┬────────┬────────┬──────────────────┬──────────────┐\n", + "│ y_hat ┆ y ┆ is_won ┆ signal ┆ trade_log_return ┆ equity_curve │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ f32 ┆ f32 ┆ bool ┆ f32 ┆ f32 ┆ f32 │\n", + "╞═══════════╪═══════════╪════════╪════════╪══════════════════╪══════════════╡\n", + "│ 0.000096 ┆ 0.007435 ┆ true ┆ 1.0 ┆ 0.007435 ┆ 0.007435 │\n", + "│ -0.000267 ┆ -0.017844 ┆ true ┆ -1.0 ┆ 0.017844 ┆ 0.025279 │\n", + "│ 0.001095 ┆ 0.003558 ┆ true ┆ 1.0 ┆ 0.003558 ┆ 0.028837 │\n", + "│ -0.000058 ┆ 0.006874 ┆ false ┆ -1.0 ┆ -0.006874 ┆ 0.021963 │\n", + "│ -0.000237 ┆ 0.001873 ┆ false ┆ -1.0 ┆ -0.001873 ┆ 0.02009 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 0.000275 ┆ 0.002465 ┆ true ┆ 1.0 ┆ 0.002465 ┆ 0.018513 │\n", + "│ 8.6137e-7 ┆ 0.001222 ┆ true ┆ 1.0 ┆ 0.001222 ┆ 0.019735 │\n", + "│ 0.000068 ┆ 0.002989 ┆ true ┆ 1.0 ┆ 0.002989 ┆ 0.022724 │\n", + "│ -0.000027 ┆ 0.001742 ┆ false ┆ -1.0 ┆ -0.001742 ┆ 0.020982 │\n", + "│ 0.00004 ┆ -0.000331 ┆ false ┆ 1.0 ┆ -0.000331 ┆ 0.020651 │\n", + "└───────────┴───────────┴────────┴────────┴──────────────────┴──────────────┘" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trade_results = pl.DataFrame({\n", + " 'y_hat': y_hat.squeeze(),\n", + " 'y': y_test.squeeze()\n", + "}).with_columns(\n", + " (pl.col('y_hat').sign()==pl.col('y').sign()).alias('is_won'),\n", + " pl.col('y_hat').sign().alias('signal'),\n", + ").with_columns(\n", + " (pl.col('signal') * pl.col('y')).alias('trade_log_return')\n", + ").with_columns(\n", + " pl.col('trade_log_return').cum_sum().alias('equity_curve')\n", + ")\n", + "trade_results" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "a38267cb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.plot_column(trade_results, 'equity_curve')" + ] + }, + { + "cell_type": "markdown", + "id": "43ce785d", + "metadata": {}, + "source": [ + "This model is not profitable, looking at the graph above equity curve hovers around 0" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "130a4c78", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (2_075, 7)
y_hatyis_wonsignaltrade_log_returnequity_curvedrawdown_log
f32f32boolf32f32f32f32
0.0000960.007435true1.00.0074350.0074350.0
-0.000267-0.017844true-1.00.0178440.0252790.0
0.0010950.003558true1.00.0035580.0288370.0
-0.0000580.006874false-1.0-0.0068740.021963-0.006874
-0.0002370.001873false-1.0-0.0018730.02009-0.008747
0.0002750.002465true1.00.0024650.018513-0.077479
8.6137e-70.001222true1.00.0012220.019735-0.076257
0.0000680.002989true1.00.0029890.022724-0.073268
-0.0000270.001742false-1.0-0.0017420.020982-0.07501
0.00004-0.000331false1.0-0.0003310.020651-0.075341
" + ], + "text/plain": [ + "shape: (2_075, 7)\n", + "┌───────────┬───────────┬────────┬────────┬──────────────────┬──────────────┬──────────────┐\n", + "│ y_hat ┆ y ┆ is_won ┆ signal ┆ trade_log_return ┆ equity_curve ┆ drawdown_log │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ f32 ┆ f32 ┆ bool ┆ f32 ┆ f32 ┆ f32 ┆ f32 │\n", + "╞═══════════╪═══════════╪════════╪════════╪══════════════════╪══════════════╪══════════════╡\n", + "│ 0.000096 ┆ 0.007435 ┆ true ┆ 1.0 ┆ 0.007435 ┆ 0.007435 ┆ 0.0 │\n", + "│ -0.000267 ┆ -0.017844 ┆ true ┆ -1.0 ┆ 0.017844 ┆ 0.025279 ┆ 0.0 │\n", + "│ 0.001095 ┆ 0.003558 ┆ true ┆ 1.0 ┆ 0.003558 ┆ 0.028837 ┆ 0.0 │\n", + "│ -0.000058 ┆ 0.006874 ┆ false ┆ -1.0 ┆ -0.006874 ┆ 0.021963 ┆ -0.006874 │\n", + "│ -0.000237 ┆ 0.001873 ┆ false ┆ -1.0 ┆ -0.001873 ┆ 0.02009 ┆ -0.008747 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 0.000275 ┆ 0.002465 ┆ true ┆ 1.0 ┆ 0.002465 ┆ 0.018513 ┆ -0.077479 │\n", + "│ 8.6137e-7 ┆ 0.001222 ┆ true ┆ 1.0 ┆ 0.001222 ┆ 0.019735 ┆ -0.076257 │\n", + "│ 0.000068 ┆ 0.002989 ┆ true ┆ 1.0 ┆ 0.002989 ┆ 0.022724 ┆ -0.073268 │\n", + "│ -0.000027 ┆ 0.001742 ┆ false ┆ -1.0 ┆ -0.001742 ┆ 0.020982 ┆ -0.07501 │\n", + "│ 0.00004 ┆ -0.000331 ┆ false ┆ 1.0 ┆ -0.000331 ┆ 0.020651 ┆ -0.075341 │\n", + "└───────────┴───────────┴────────┴────────┴──────────────────┴──────────────┴──────────────┘" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trade_results = trade_results.with_columns(\n", + " (pl.col('equity_curve')-pl.col('equity_curve').cum_max()).alias('drawdown_log')\n", + ")\n", + "trade_results" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "d14e3e51", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-0.14714771509170532" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max_drawdown_log = trade_results['drawdown_log'].min()\n", + "max_drawdown_log" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "5ee38ca6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(-0.13683353471475834)" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "drawdown_pct = np.exp(max_drawdown_log) - 1\n", + "drawdown_pct" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "6356479d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(-136.83353471475834)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "equity_peak = 1000\n", + "equity_peak * drawdown_pct" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "a9cf28aa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.4959036144578313" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win_rate = trade_results['is_won'].mean()\n", + "win_rate" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "c43c8a95", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9.952400906535321e-06" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "avg_win = trade_results.filter(pl.col('is_won')==True)['trade_log_return'].mean()\n", + "avg_loss = trade_results.filter(pl.col('is_won')==False)['trade_log_return'].mean()\n", + "ev = win_rate * avg_win + (1 - win_rate) * avg_loss\n", + "ev" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "f4a92843", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.020651236176490784" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total_log_return = trade_results['trade_log_return'].sum()\n", + "total_log_return" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "8d453bd7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(1.020865948431715)" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "compound_return = np.exp(total_log_return)\n", + "compound_return" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "22b406c5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(1020.8659484317151)" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1000*compound_return" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "f3c98a26", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-0.05115591362118721" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "equity_trough = trade_results['equity_curve'].min()\n", + "equity_trough" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "58ff6e73", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.09599180519580841" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "equity_peak = trade_results['equity_curve'].max()\n", + "equity_peak" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "3915b065", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0033079273998737335" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "std = trade_results['trade_log_return'].std()\n", + "std" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "83403565", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(0.2815943558905409)" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sharpe = ev / std * annualized_rate\n", + "sharpe" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "3e3bd1a5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'features': 'close_log_return_lag_1',\n", + " 'target': 'close_log_return',\n", + " 'no_trades': 2075,\n", + " 'win_rate': 0.4959036144578313,\n", + " 'avg_win': 0.0022900966530581563,\n", + " 'avg_loss': -0.002233134057472067,\n", + " 'best_trade': 0.02901790291070938,\n", + " 'worst_trade': -0.02237566001713276,\n", + " 'ev': 9.952400906535321e-06,\n", + " 'std': 0.0033079273998737335,\n", + " 'total_log_return': 0.020651236176490784,\n", + " 'compound_return': np.float64(1.020865948431715),\n", + " 'max_drawdown': -0.14714771509170532,\n", + " 'equity_trough': -0.05115591362118721,\n", + " 'equity_peak': 0.09599180519580841,\n", + " 'sharpe': np.float64(0.2815943558905437)}" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.eval_model_performance(y_test, y_hat, features, target, annualized_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "7b362166", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'features': 'close_log_return_lag_2',\n", + " 'target': 'close_log_return',\n", + " 'no_trades': 2075,\n", + " 'win_rate': 0.5204819277108433,\n", + " 'avg_win': 0.002264919135606647,\n", + " 'avg_loss': -0.002257542727293916,\n", + " 'best_trade': 0.02901790291070938,\n", + " 'worst_trade': -0.019244860857725143,\n", + " 'ev': 9.631694110734065e-05,\n", + " 'std': 0.0033065390307456255,\n", + " 'total_log_return': 0.1998576521873474,\n", + " 'compound_return': np.float64(1.2212289065231716),\n", + " 'max_drawdown': -0.1928328275680542,\n", + " 'equity_trough': -0.03486982360482216,\n", + " 'equity_peak': 0.23000681400299072,\n", + " 'sharpe': np.float64(2.726346689774677),\n", + " 'weights': '[-0.02535994]',\n", + " 'biases': '7.355681009357795e-05'}" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target = 'close_log_return'\n", + "features = ['close_log_return_lag_2']\n", + "model = LinearModel(len(features))\n", + "perf = research.benchmark_reg_model(ts, features, target, model, annualized_rate, no_epochs=50)\n", + "perf" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "1110b94a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (4, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_2""close_log_return"20750.5209640.002264-0.0022590.029018-0.0192450.0000970.0033070.2015881.223344-0.191103-0.033140.2317372.749969"[-0.02508093]""7.279599958565086e-05"
"close_log_return_lag_3""close_log_return"20750.5021690.002302-0.002220.029018-0.0223760.0000510.0033080.1060111.111835-0.24125-0.1880490.1063421.445707"[-0.03205177]""8.784193050814793e-05"
"close_log_return_lag_4""close_log_return"20750.4997590.00228-0.0022430.029018-0.0223760.0000180.0033080.0367441.037427-0.142968-0.087550.0723480.501032"[-0.00144515]""7.324843318201602e-05"
"close_log_return_lag_1""close_log_return"20750.4968670.002284-0.0022390.029018-0.0223760.0000090.0033080.0179921.018154-0.2092860.0028880.2121740.245327"[-0.07195751]""8.91545569174923e-05"
" + ], + "text/plain": [ + "shape: (4, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 2075 ┆ 0.520964 ┆ 0.002264 ┆ -0.00225 ┆ 0.029018 ┆ -0.01924 ┆ 0.000097 ┆ 0.003307 ┆ 0.201588 ┆ 1.223344 ┆ -0.19110 ┆ -0.03314 ┆ 0.231737 ┆ 2.749969 ┆ [-0.0250 ┆ 7.279599 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 9 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ ┆ ┆ ┆ 8093] ┆ 95856508 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 6e-05 │\n", + "│ close_log ┆ close_lo ┆ 2075 ┆ 0.502169 ┆ 0.002302 ┆ -0.00222 ┆ 0.029018 ┆ -0.02237 ┆ 0.000051 ┆ 0.003308 ┆ 0.106011 ┆ 1.111835 ┆ -0.24125 ┆ -0.18804 ┆ 0.106342 ┆ 1.445707 ┆ [-0.0320 ┆ 8.784193 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ ┆ ┆ 6 ┆ ┆ ┆ ┆ ┆ ┆ 9 ┆ ┆ ┆ 5177] ┆ 05081479 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 3e-05 │\n", + "│ close_log ┆ close_lo ┆ 2075 ┆ 0.499759 ┆ 0.00228 ┆ -0.00224 ┆ 0.029018 ┆ -0.02237 ┆ 0.000018 ┆ 0.003308 ┆ 0.036744 ┆ 1.037427 ┆ -0.14296 ┆ -0.08755 ┆ 0.072348 ┆ 0.501032 ┆ [-0.0014 ┆ 7.324843 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 3 ┆ ┆ 6 ┆ ┆ ┆ ┆ ┆ 8 ┆ ┆ ┆ ┆ 4515] ┆ 31820160 │\n", + "│ ag_4 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 2e-05 │\n", + "│ close_log ┆ close_lo ┆ 2075 ┆ 0.496867 ┆ 0.002284 ┆ -0.00223 ┆ 0.029018 ┆ -0.02237 ┆ 0.000009 ┆ 0.003308 ┆ 0.017992 ┆ 1.018154 ┆ -0.20928 ┆ 0.002888 ┆ 0.212174 ┆ 0.245327 ┆ [-0.0719 ┆ 8.915455 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 9 ┆ ┆ 6 ┆ ┆ ┆ ┆ ┆ 6 ┆ ┆ ┆ ┆ 5751] ┆ 69174923 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ e-05 │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import itertools\n", + "\n", + "benchmarks = []\n", + "feature_pool = [f'{target}_lag_{i}' for i in range(1, max_lags + 1)]\n", + "combos = list(itertools.combinations(feature_pool, 1))\n", + "\n", + "for features in combos: \n", + " model = LinearModel(len(features))\n", + " benchmarks.append(research.benchmark_reg_model(ts, list(features), target, model, annualized_rate, test_size=test_size, no_epochs=200, loss=nn.L1Loss()))\n", + "\n", + "benchmark = pl.DataFrame(benchmarks)\n", + "benchmark.sort('sharpe', descending=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "ba4ba034", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (5, 5)
close_log_returnclose_log_return_lag_1close_log_return_lag_2close_log_return_lag_3close_log_return_lag_4
f64f64f64f64f64
1.0-0.0205270.004165-0.0240770.006435
-0.0205271.0-0.0205550.004284-0.024028
0.004165-0.0205551.0-0.0207930.004187
-0.0240770.004284-0.0207931.0-0.020495
0.006435-0.0240280.004187-0.0204951.0
" + ], + "text/plain": [ + "shape: (5, 5)\n", + "┌──────────────────┬────────────────────────┬────────────────────────┬────────────────────────┬────────────────────────┐\n", + "│ close_log_return ┆ close_log_return_lag_1 ┆ close_log_return_lag_2 ┆ close_log_return_lag_3 ┆ close_log_return_lag_4 │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞══════════════════╪════════════════════════╪════════════════════════╪════════════════════════╪════════════════════════╡\n", + "│ 1.0 ┆ -0.020527 ┆ 0.004165 ┆ -0.024077 ┆ 0.006435 │\n", + "│ -0.020527 ┆ 1.0 ┆ -0.020555 ┆ 0.004284 ┆ -0.024028 │\n", + "│ 0.004165 ┆ -0.020555 ┆ 1.0 ┆ -0.020793 ┆ 0.004187 │\n", + "│ -0.024077 ┆ 0.004284 ┆ -0.020793 ┆ 1.0 ┆ -0.020495 │\n", + "│ 0.006435 ┆ -0.024028 ┆ 0.004187 ┆ -0.020495 ┆ 1.0 │\n", + "└──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.auto_reg_corr_matrx(ts, target, max_lags)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "8740fd78", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features = ['close_log_return_lag_2']\n", + "model = LinearModel(len(features))\n", + "model_trades = research.learn_model_trades(ts, features, target, model, no_epochs=200, loss=nn.L1Loss())\n", + "\n", + "research.plot_column(model_trades, 'equity_curve')" + ] + }, + { + "cell_type": "markdown", + "id": "a4660590", + "metadata": {}, + "source": [ + "### Add Transaction Fees" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "c7174809", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (2_075, 10)
y_predy_trueis_wonpositiontrade_log_returnequity_curvedrawdown_log_returntx_fee_logtrade_log_return_netequity_curve_net
f32f32boolf32f32f32f32f64f64f64
0.000060.007435true1.00.0074350.0074350.0-0.00060.0068350.006835
0.000054-0.017844false1.0-0.017844-0.010409-0.017844-0.0006-0.018444-0.011609
-0.0001170.003558false-1.0-0.003558-0.013967-0.021402-0.0006-0.004158-0.015767
0.0005250.006874true1.00.006874-0.007092-0.014527-0.00060.006274-0.009493
-0.0000180.001873false-1.0-0.001873-0.008965-0.0164-0.0006-0.002473-0.011966
-0.0001730.002465false-1.0-0.0024650.175485-0.049873-0.0006-0.003065-1.067488
0.0001380.001222true1.00.0012220.176707-0.048651-0.00060.000622-1.066866
0.0000090.002989true1.00.0029890.179696-0.045661-0.00060.002389-1.064477
0.0000410.001742true1.00.0017420.181438-0.043919-0.00060.001142-1.063335
-0.000004-0.000331true-1.00.0003310.181769-0.043589-0.0006-0.00027-1.063605
" + ], + "text/plain": [ + "shape: (2_075, 10)\n", + "┌───────────┬───────────┬────────┬──────────┬──────────────────┬──────────────┬─────────────────────┬────────────┬──────────────────────┬──────────────────┐\n", + "│ y_pred ┆ y_true ┆ is_won ┆ position ┆ trade_log_return ┆ equity_curve ┆ drawdown_log_return ┆ tx_fee_log ┆ trade_log_return_net ┆ equity_curve_net │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ f32 ┆ f32 ┆ bool ┆ f32 ┆ f32 ┆ f32 ┆ f32 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═══════════╪═══════════╪════════╪══════════╪══════════════════╪══════════════╪═════════════════════╪════════════╪══════════════════════╪══════════════════╡\n", + "│ 0.00006 ┆ 0.007435 ┆ true ┆ 1.0 ┆ 0.007435 ┆ 0.007435 ┆ 0.0 ┆ -0.0006 ┆ 0.006835 ┆ 0.006835 │\n", + "│ 0.000054 ┆ -0.017844 ┆ false ┆ 1.0 ┆ -0.017844 ┆ -0.010409 ┆ -0.017844 ┆ -0.0006 ┆ -0.018444 ┆ -0.011609 │\n", + "│ -0.000117 ┆ 0.003558 ┆ false ┆ -1.0 ┆ -0.003558 ┆ -0.013967 ┆ -0.021402 ┆ -0.0006 ┆ -0.004158 ┆ -0.015767 │\n", + "│ 0.000525 ┆ 0.006874 ┆ true ┆ 1.0 ┆ 0.006874 ┆ -0.007092 ┆ -0.014527 ┆ -0.0006 ┆ 0.006274 ┆ -0.009493 │\n", + "│ -0.000018 ┆ 0.001873 ┆ false ┆ -1.0 ┆ -0.001873 ┆ -0.008965 ┆ -0.0164 ┆ -0.0006 ┆ -0.002473 ┆ -0.011966 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ -0.000173 ┆ 0.002465 ┆ false ┆ -1.0 ┆ -0.002465 ┆ 0.175485 ┆ -0.049873 ┆ -0.0006 ┆ -0.003065 ┆ -1.067488 │\n", + "│ 0.000138 ┆ 0.001222 ┆ true ┆ 1.0 ┆ 0.001222 ┆ 0.176707 ┆ -0.048651 ┆ -0.0006 ┆ 0.000622 ┆ -1.066866 │\n", + "│ 0.000009 ┆ 0.002989 ┆ true ┆ 1.0 ┆ 0.002989 ┆ 0.179696 ┆ -0.045661 ┆ -0.0006 ┆ 0.002389 ┆ -1.064477 │\n", + "│ 0.000041 ┆ 0.001742 ┆ true ┆ 1.0 ┆ 0.001742 ┆ 0.181438 ┆ -0.043919 ┆ -0.0006 ┆ 0.001142 ┆ -1.063335 │\n", + "│ -0.000004 ┆ -0.000331 ┆ true ┆ -1.0 ┆ 0.000331 ┆ 0.181769 ┆ -0.043589 ┆ -0.0006 ┆ -0.00027 ┆ -1.063605 │\n", + "└───────────┴───────────┴────────┴──────────┴──────────────────┴──────────────┴─────────────────────┴────────────┴──────────────────────┴──────────────────┘" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "maker_fee = 0.0001\n", + "taker_fee = 0.0003\n", + "\n", + "roundtrip_fee_log = np.log(1 - 2 * taker_fee)\n", + "\n", + "model_trades = model_trades.with_columns(pl.lit(roundtrip_fee_log).alias('tx_fee_log'))\n", + "model_trades = model_trades.with_columns((pl.col('trade_log_return') + pl.col('tx_fee_log')).alias('trade_log_return_net'))\n", + "model_trades = model_trades.with_columns(pl.col('trade_log_return_net').cum_sum().alias('equity_curve_net'))\n", + "\n", + "model_trades" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "2311a787", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.plot_column(model_trades, 'equity_curve_net')" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "79ce8e38", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.plot_column(model_trades, 'equity_curve')" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "0f2694af", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5214457831325301" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_trades['is_won'].mean()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "7023f988", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (2_075, 14)
y_predy_trueis_wonpositiontrade_log_returnequity_curvedrawdown_log_returntx_fee_logtrade_log_return_netequity_curve_nettrade_log_return_net_makertrade_log_return_net_takerequity_curve_net_makerequity_curve_net_taker
f32f32boolf32f32f32f32f64f64f64f64f64f64f64
0.000060.007435true1.00.0074350.0074350.0-0.00060.0068350.006835-9.202905-8.104293-9.202905-8.104293
0.000054-0.017844false1.0-0.017844-0.010409-0.017844-0.0006-0.018444-0.011609-9.228184-8.129572-18.431089-16.233865
-0.0001170.003558false-1.0-0.003558-0.013967-0.021402-0.0006-0.004158-0.015767-9.213898-8.115286-27.644988-24.349151
0.0005250.006874true1.00.006874-0.007092-0.014527-0.00060.006274-0.009493-9.203466-8.104854-36.848454-32.454005
-0.0000180.001873false-1.0-0.001873-0.008965-0.0164-0.0006-0.002473-0.011966-9.212213-8.113601-46.060667-40.567606
-0.0001730.002465false-1.0-0.0024650.175485-0.049873-0.0006-0.003065-1.067488-9.212805-8.114193-19074.439425-16799.213376
0.0001380.001222true1.00.0012220.176707-0.048651-0.00060.000622-1.066866-9.209119-8.110506-19083.648544-16807.323882
0.0000090.002989true1.00.0029890.179696-0.045661-0.00060.002389-1.064477-9.207351-8.108739-19092.855895-16815.432621
0.0000410.001742true1.00.0017420.181438-0.043919-0.00060.001142-1.063335-9.208598-8.109986-19102.064493-16823.542606
-0.000004-0.000331true-1.00.0003310.181769-0.043589-0.0006-0.00027-1.063605-9.21001-8.111397-19111.274503-16831.654004
" + ], + "text/plain": [ + "shape: (2_075, 14)\n", + "┌───────────┬───────────┬────────┬──────────┬───────────────┬──────────────┬───────────────┬────────────┬───────────────┬───────────────┬───────────────┬───────────────┬───────────────┬──────────────┐\n", + "│ y_pred ┆ y_true ┆ is_won ┆ position ┆ trade_log_ret ┆ equity_curve ┆ drawdown_log_ ┆ tx_fee_log ┆ trade_log_ret ┆ equity_curve_ ┆ trade_log_ret ┆ trade_log_ret ┆ equity_curve_ ┆ equity_curve │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ urn ┆ --- ┆ return ┆ --- ┆ urn_net ┆ net ┆ urn_net_maker ┆ urn_net_taker ┆ net_maker ┆ _net_taker │\n", + "│ f32 ┆ f32 ┆ bool ┆ f32 ┆ --- ┆ f32 ┆ --- ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ ┆ ┆ ┆ ┆ f32 ┆ ┆ f32 ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═══════════╪═══════════╪════════╪══════════╪═══════════════╪══════════════╪═══════════════╪════════════╪═══════════════╪═══════════════╪═══════════════╪═══════════════╪═══════════════╪══════════════╡\n", + "│ 0.00006 ┆ 0.007435 ┆ true ┆ 1.0 ┆ 0.007435 ┆ 0.007435 ┆ 0.0 ┆ -0.0006 ┆ 0.006835 ┆ 0.006835 ┆ -9.202905 ┆ -8.104293 ┆ -9.202905 ┆ -8.104293 │\n", + "│ 0.000054 ┆ -0.017844 ┆ false ┆ 1.0 ┆ -0.017844 ┆ -0.010409 ┆ -0.017844 ┆ -0.0006 ┆ -0.018444 ┆ -0.011609 ┆ -9.228184 ┆ -8.129572 ┆ -18.431089 ┆ -16.233865 │\n", + "│ -0.000117 ┆ 0.003558 ┆ false ┆ -1.0 ┆ -0.003558 ┆ -0.013967 ┆ -0.021402 ┆ -0.0006 ┆ -0.004158 ┆ -0.015767 ┆ -9.213898 ┆ -8.115286 ┆ -27.644988 ┆ -24.349151 │\n", + "│ 0.000525 ┆ 0.006874 ┆ true ┆ 1.0 ┆ 0.006874 ┆ -0.007092 ┆ -0.014527 ┆ -0.0006 ┆ 0.006274 ┆ -0.009493 ┆ -9.203466 ┆ -8.104854 ┆ -36.848454 ┆ -32.454005 │\n", + "│ -0.000018 ┆ 0.001873 ┆ false ┆ -1.0 ┆ -0.001873 ┆ -0.008965 ┆ -0.0164 ┆ -0.0006 ┆ -0.002473 ┆ -0.011966 ┆ -9.212213 ┆ -8.113601 ┆ -46.060667 ┆ -40.567606 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ -0.000173 ┆ 0.002465 ┆ false ┆ -1.0 ┆ -0.002465 ┆ 0.175485 ┆ -0.049873 ┆ -0.0006 ┆ -0.003065 ┆ -1.067488 ┆ -9.212805 ┆ -8.114193 ┆ -19074.439425 ┆ -16799.21337 │\n", + "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 6 │\n", + "│ 0.000138 ┆ 0.001222 ┆ true ┆ 1.0 ┆ 0.001222 ┆ 0.176707 ┆ -0.048651 ┆ -0.0006 ┆ 0.000622 ┆ -1.066866 ┆ -9.209119 ┆ -8.110506 ┆ -19083.648544 ┆ -16807.32388 │\n", + "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 2 │\n", + "│ 0.000009 ┆ 0.002989 ┆ true ┆ 1.0 ┆ 0.002989 ┆ 0.179696 ┆ -0.045661 ┆ -0.0006 ┆ 0.002389 ┆ -1.064477 ┆ -9.207351 ┆ -8.108739 ┆ -19092.855895 ┆ -16815.43262 │\n", + "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 1 │\n", + "│ 0.000041 ┆ 0.001742 ┆ true ┆ 1.0 ┆ 0.001742 ┆ 0.181438 ┆ -0.043919 ┆ -0.0006 ┆ 0.001142 ┆ -1.063335 ┆ -9.208598 ┆ -8.109986 ┆ -19102.064493 ┆ -16823.54260 │\n", + "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 6 │\n", + "│ -0.000004 ┆ -0.000331 ┆ true ┆ -1.0 ┆ 0.000331 ┆ 0.181769 ┆ -0.043589 ┆ -0.0006 ┆ -0.00027 ┆ -1.063605 ┆ -9.21001 ┆ -8.111397 ┆ -19111.274503 ┆ -16831.65400 │\n", + "│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 4 │\n", + "└───────────┴───────────┴────────┴──────────┴───────────────┴──────────────┴───────────────┴────────────┴───────────────┴───────────────┴───────────────┴───────────────┴───────────────┴──────────────┘" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_trades = research.add_tx_fees_log(model_trades, maker_fee, taker_fee)\n", + "model_trades" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "3ffdcf51", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Loading BTCUSDT: 100%|██████████| 346/346 [00:21<00:00, 16.24day/s]\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "shape: (1_384, 5)
datetimeopenhighlowclose
datetime[μs]f64f64f64f64
2024-10-29 00:00:0069939.971607.069733.071010.9
2024-10-29 06:00:0071010.871580.070803.071440.1
2024-10-29 12:00:0071440.072972.070900.072700.8
2024-10-29 18:00:0072700.873660.071871.172739.5
2024-10-30 00:00:0072739.572797.472018.072516.3
2025-10-08 18:00:00123985.5124169.2122739.7123237.5
2025-10-09 00:00:00123237.4123279.7121411.8122052.6
2025-10-09 06:00:00122052.6122777.0121081.5122672.9
2025-10-09 12:00:00122673.0123740.1119572.8120915.6
2025-10-09 18:00:00120915.5121712.4120319.0121579.3
" + ], + "text/plain": [ + "shape: (1_384, 5)\n", + "┌─────────────────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ datetime ┆ open ┆ high ┆ low ┆ close │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ datetime[μs] ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════════════════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ 2024-10-29 00:00:00 ┆ 69939.9 ┆ 71607.0 ┆ 69733.0 ┆ 71010.9 │\n", + "│ 2024-10-29 06:00:00 ┆ 71010.8 ┆ 71580.0 ┆ 70803.0 ┆ 71440.1 │\n", + "│ 2024-10-29 12:00:00 ┆ 71440.0 ┆ 72972.0 ┆ 70900.0 ┆ 72700.8 │\n", + "│ 2024-10-29 18:00:00 ┆ 72700.8 ┆ 73660.0 ┆ 71871.1 ┆ 72739.5 │\n", + "│ 2024-10-30 00:00:00 ┆ 72739.5 ┆ 72797.4 ┆ 72018.0 ┆ 72516.3 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 2025-10-08 18:00:00 ┆ 123985.5 ┆ 124169.2 ┆ 122739.7 ┆ 123237.5 │\n", + "│ 2025-10-09 00:00:00 ┆ 123237.4 ┆ 123279.7 ┆ 121411.8 ┆ 122052.6 │\n", + "│ 2025-10-09 06:00:00 ┆ 122052.6 ┆ 122777.0 ┆ 121081.5 ┆ 122672.9 │\n", + "│ 2025-10-09 12:00:00 ┆ 122673.0 ┆ 123740.1 ┆ 119572.8 ┆ 120915.6 │\n", + "│ 2025-10-09 18:00:00 ┆ 120915.5 ┆ 121712.4 ┆ 120319.0 ┆ 121579.3 │\n", + "└─────────────────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time_interval = '6h'\n", + "ts = research.load_ohlc_timeseries_range(sym, time_interval, start_date, end_date)\n", + "ts" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "94a1c470", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (1_384, 9)
datetimeopenhighlowcloseclose_log_returnclose_log_return_lag_1close_log_return_lag_2close_log_return_lag_3
datetime[μs]f64f64f64f64f64f64f64f64
2024-10-29 00:00:0069939.971607.069733.071010.9nullnullnullnull
2024-10-29 06:00:0071010.871580.070803.071440.10.006026nullnullnull
2024-10-29 12:00:0071440.072972.070900.072700.80.0174930.006026nullnull
2024-10-29 18:00:0072700.873660.071871.172739.50.0005320.0174930.006026null
2024-10-30 00:00:0072739.572797.472018.072516.3-0.0030730.0005320.0174930.006026
2025-10-08 18:00:00123985.5124169.2122739.7123237.5-0.0060510.0093980.0121860.000425
2025-10-09 00:00:00123237.4123279.7121411.8122052.6-0.009661-0.0060510.0093980.012186
2025-10-09 06:00:00122052.6122777.0121081.5122672.90.005069-0.009661-0.0060510.009398
2025-10-09 12:00:00122673.0123740.1119572.8120915.6-0.0144290.005069-0.009661-0.006051
2025-10-09 18:00:00120915.5121712.4120319.0121579.30.005474-0.0144290.005069-0.009661
" + ], + "text/plain": [ + "shape: (1_384, 9)\n", + "┌─────────────────────┬──────────┬──────────┬──────────┬──────────┬──────────────────┬────────────────────────┬────────────────────────┬────────────────────────┐\n", + "│ datetime ┆ open ┆ high ┆ low ┆ close ┆ close_log_return ┆ close_log_return_lag_1 ┆ close_log_return_lag_2 ┆ close_log_return_lag_3 │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ datetime[μs] ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════════════╪════════════════════════╪════════════════════════╪════════════════════════╡\n", + "│ 2024-10-29 00:00:00 ┆ 69939.9 ┆ 71607.0 ┆ 69733.0 ┆ 71010.9 ┆ null ┆ null ┆ null ┆ null │\n", + "│ 2024-10-29 06:00:00 ┆ 71010.8 ┆ 71580.0 ┆ 70803.0 ┆ 71440.1 ┆ 0.006026 ┆ null ┆ null ┆ null │\n", + "│ 2024-10-29 12:00:00 ┆ 71440.0 ┆ 72972.0 ┆ 70900.0 ┆ 72700.8 ┆ 0.017493 ┆ 0.006026 ┆ null ┆ null │\n", + "│ 2024-10-29 18:00:00 ┆ 72700.8 ┆ 73660.0 ┆ 71871.1 ┆ 72739.5 ┆ 0.000532 ┆ 0.017493 ┆ 0.006026 ┆ null │\n", + "│ 2024-10-30 00:00:00 ┆ 72739.5 ┆ 72797.4 ┆ 72018.0 ┆ 72516.3 ┆ -0.003073 ┆ 0.000532 ┆ 0.017493 ┆ 0.006026 │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 2025-10-08 18:00:00 ┆ 123985.5 ┆ 124169.2 ┆ 122739.7 ┆ 123237.5 ┆ -0.006051 ┆ 0.009398 ┆ 0.012186 ┆ 0.000425 │\n", + "│ 2025-10-09 00:00:00 ┆ 123237.4 ┆ 123279.7 ┆ 121411.8 ┆ 122052.6 ┆ -0.009661 ┆ -0.006051 ┆ 0.009398 ┆ 0.012186 │\n", + "│ 2025-10-09 06:00:00 ┆ 122052.6 ┆ 122777.0 ┆ 121081.5 ┆ 122672.9 ┆ 0.005069 ┆ -0.009661 ┆ -0.006051 ┆ 0.009398 │\n", + "│ 2025-10-09 12:00:00 ┆ 122673.0 ┆ 123740.1 ┆ 119572.8 ┆ 120915.6 ┆ -0.014429 ┆ 0.005069 ┆ -0.009661 ┆ -0.006051 │\n", + "│ 2025-10-09 18:00:00 ┆ 120915.5 ┆ 121712.4 ┆ 120319.0 ┆ 121579.3 ┆ 0.005474 ┆ -0.014429 ┆ 0.005069 ┆ -0.009661 │\n", + "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "no_lags = 3\n", + "ts = research.add_log_return_features(ts, 'close', forecast_horizon, max_no_lags=no_lags)\n", + "ts" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "5c789833", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (3, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_2""close_log_return"3450.5507250.005243-0.0058370.041011-0.0270850.0002650.0076780.0914061.095714-0.107804-0.0779020.1003613.229774"[-0.06635377]""0.0005011901957914233"
"close_log_return_lag_1""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00794159]""0.00047139523667283356"
"close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00370021]""0.00046539169852621853"
" + ], + "text/plain": [ + "shape: (3, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.550725 ┆ 0.005243 ┆ -0.00583 ┆ 0.041011 ┆ -0.02708 ┆ 0.000265 ┆ 0.007678 ┆ 0.091406 ┆ 1.095714 ┆ -0.10780 ┆ -0.07790 ┆ 0.100361 ┆ 3.229774 ┆ [-0.0663 ┆ 0.000501 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 7 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 4 ┆ 2 ┆ ┆ ┆ 5377] ┆ 19019579 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 14233 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0079 ┆ 0.000471 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 4159] ┆ 39523667 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 283356 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0037 ┆ 0.000465 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 0021] ┆ 39169852 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 621853 │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target = 'close_log_return'\n", + "feature_pool = [f'{target}_lag_{i}' for i in range(1, no_lags + 1)]\n", + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, loss=nn.HuberLoss())" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "7f7a7df4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (4, 4)
close_log_returnclose_log_return_lag_1close_log_return_lag_2close_log_return_lag_3
f64f64f64f64
1.0-0.009991-0.05972-0.009533
-0.0099911.0-0.009586-0.059841
-0.05972-0.0095861.0-0.00873
-0.009533-0.059841-0.008731.0
" + ], + "text/plain": [ + "shape: (4, 4)\n", + "┌──────────────────┬────────────────────────┬────────────────────────┬────────────────────────┐\n", + "│ close_log_return ┆ close_log_return_lag_1 ┆ close_log_return_lag_2 ┆ close_log_return_lag_3 │\n", + "│ --- ┆ --- ┆ --- ┆ --- │\n", + "│ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞══════════════════╪════════════════════════╪════════════════════════╪════════════════════════╡\n", + "│ 1.0 ┆ -0.009991 ┆ -0.05972 ┆ -0.009533 │\n", + "│ -0.009991 ┆ 1.0 ┆ -0.009586 ┆ -0.059841 │\n", + "│ -0.05972 ┆ -0.009586 ┆ 1.0 ┆ -0.00873 │\n", + "│ -0.009533 ┆ -0.059841 ┆ -0.00873 ┆ 1.0 │\n", + "└──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.auto_reg_corr_matrx(ts.drop_nulls(), target, no_lags)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "4d120076", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (3, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_2""close_log_return"3450.5507250.005243-0.0058370.041011-0.0270850.0002650.0076780.0914061.095714-0.107804-0.0779020.1003613.229774"[-0.06619783]""0.0004998851800337434"
"close_log_return_lag_1""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00758726]""0.00046671958989463747"
"close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00386026]""0.00046681109233759344"
" + ], + "text/plain": [ + "shape: (3, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.550725 ┆ 0.005243 ┆ -0.00583 ┆ 0.041011 ┆ -0.02708 ┆ 0.000265 ┆ 0.007678 ┆ 0.091406 ┆ 1.095714 ┆ -0.10780 ┆ -0.07790 ┆ 0.100361 ┆ 3.229774 ┆ [-0.0661 ┆ 0.000499 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 7 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 4 ┆ 2 ┆ ┆ ┆ 9783] ┆ 88518003 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 37434 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0075 ┆ 0.000466 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 8726] ┆ 71958989 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 463747 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0038 ┆ 0.000466 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 6026] ┆ 81109233 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 759344 │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, loss=nn.MSELoss())" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "de24ada0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (3, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_1""close_log_return"4150.5469880.005407-0.0053760.041011-0.0270850.0005220.0076780.2166661.241929-0.103148-0.0000110.2529876.364213"[-0.02600251]""0.00023229577345773578"
"close_log_return_lag_3""close_log_return"4150.532530.005503-0.0052670.041011-0.0270850.0004690.0076810.1944681.214664-0.13558-0.0102050.2501615.709613"[-0.05923362]""0.00044723410974256694"
"close_log_return_lag_2""close_log_return"4150.5493980.005155-0.0056820.028236-0.0410110.0002720.0076910.1128351.119448-0.16492-0.0324490.1371333.308776"[-0.08242929]""0.0004675340896937996"
" + ], + "text/plain": [ + "shape: (3, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 415 ┆ 0.546988 ┆ 0.005407 ┆ -0.00537 ┆ 0.041011 ┆ -0.02708 ┆ 0.000522 ┆ 0.007678 ┆ 0.216666 ┆ 1.241929 ┆ -0.10314 ┆ -0.00001 ┆ 0.252987 ┆ 6.364213 ┆ [-0.0260 ┆ 0.000232 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 6 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 8 ┆ 1 ┆ ┆ ┆ 0251] ┆ 29577345 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 773578 │\n", + "│ close_log ┆ close_lo ┆ 415 ┆ 0.53253 ┆ 0.005503 ┆ -0.00526 ┆ 0.041011 ┆ -0.02708 ┆ 0.000469 ┆ 0.007681 ┆ 0.194468 ┆ 1.214664 ┆ -0.13558 ┆ -0.01020 ┆ 0.250161 ┆ 5.709613 ┆ [-0.0592 ┆ 0.000447 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 7 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ ┆ 5 ┆ ┆ ┆ 3362] ┆ 23410974 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 256694 │\n", + "│ close_log ┆ close_lo ┆ 415 ┆ 0.549398 ┆ 0.005155 ┆ -0.00568 ┆ 0.028236 ┆ -0.04101 ┆ 0.000272 ┆ 0.007691 ┆ 0.112835 ┆ 1.119448 ┆ -0.16492 ┆ -0.03244 ┆ 0.137133 ┆ 3.308776 ┆ [-0.0824 ┆ 0.000467 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 2 ┆ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ 9 ┆ ┆ ┆ 2929] ┆ 53408969 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 37996 │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, loss=nn.L1Loss(), test_size=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "c6cba0dd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features = ['close_log_return_lag_1']\n", + "model = LinearModel(len(features))\n", + "model_trades = research.learn_model_trades(ts.drop_nulls(), features, target, model, loss=nn.L1Loss())\n", + "model_trades = research.add_tx_fees_log(model_trades, maker_fee, taker_fee)\n", + "research.plot_column(model_trades, 'equity_curve')" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "0a1df205", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.plot_column(model_trades, 'equity_curve_net_taker')" + ] + }, + { + "cell_type": "markdown", + "id": "c1dcea3d", + "metadata": {}, + "source": [ + "## Research 12 forecast horizon" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "7bd6eed2", + "metadata": {}, + "outputs": [], + "source": [ + "time_interval = '12h'" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "0fa44adb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (1_384, 10)
datetimeopenhighlowcloseclose_log_returnclose_log_return_lag_1close_log_return_lag_2close_log_return_lag_3close_log_return_lag_4
datetime[μs]f64f64f64f64f64f64f64f64f64
2024-10-29 00:00:0069939.971607.069733.071010.9nullnullnullnullnull
2024-10-29 06:00:0071010.871580.070803.071440.10.006026nullnullnullnull
2024-10-29 12:00:0071440.072972.070900.072700.80.0174930.006026nullnullnull
2024-10-29 18:00:0072700.873660.071871.172739.50.0005320.0174930.006026nullnull
2024-10-30 00:00:0072739.572797.472018.072516.3-0.0030730.0005320.0174930.006026null
2025-10-08 18:00:00123985.5124169.2122739.7123237.5-0.0060510.0093980.0121860.0004250.001761
2025-10-09 00:00:00123237.4123279.7121411.8122052.6-0.009661-0.0060510.0093980.0121860.000425
2025-10-09 06:00:00122052.6122777.0121081.5122672.90.005069-0.009661-0.0060510.0093980.012186
2025-10-09 12:00:00122673.0123740.1119572.8120915.6-0.0144290.005069-0.009661-0.0060510.009398
2025-10-09 18:00:00120915.5121712.4120319.0121579.30.005474-0.0144290.005069-0.009661-0.006051
" + ], + "text/plain": [ + "shape: (1_384, 10)\n", + "┌─────────────────────┬──────────┬──────────┬──────────┬──────────┬──────────────────┬────────────────────────┬────────────────────────┬────────────────────────┬────────────────────────┐\n", + "│ datetime ┆ open ┆ high ┆ low ┆ close ┆ close_log_return ┆ close_log_return_lag_1 ┆ close_log_return_lag_2 ┆ close_log_return_lag_3 ┆ close_log_return_lag_4 │\n", + "│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │\n", + "│ datetime[μs] ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", + "╞═════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════════════╪════════════════════════╪════════════════════════╪════════════════════════╪════════════════════════╡\n", + "│ 2024-10-29 00:00:00 ┆ 69939.9 ┆ 71607.0 ┆ 69733.0 ┆ 71010.9 ┆ null ┆ null ┆ null ┆ null ┆ null │\n", + "│ 2024-10-29 06:00:00 ┆ 71010.8 ┆ 71580.0 ┆ 70803.0 ┆ 71440.1 ┆ 0.006026 ┆ null ┆ null ┆ null ┆ null │\n", + "│ 2024-10-29 12:00:00 ┆ 71440.0 ┆ 72972.0 ┆ 70900.0 ┆ 72700.8 ┆ 0.017493 ┆ 0.006026 ┆ null ┆ null ┆ null │\n", + "│ 2024-10-29 18:00:00 ┆ 72700.8 ┆ 73660.0 ┆ 71871.1 ┆ 72739.5 ┆ 0.000532 ┆ 0.017493 ┆ 0.006026 ┆ null ┆ null │\n", + "│ 2024-10-30 00:00:00 ┆ 72739.5 ┆ 72797.4 ┆ 72018.0 ┆ 72516.3 ┆ -0.003073 ┆ 0.000532 ┆ 0.017493 ┆ 0.006026 ┆ null │\n", + "│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │\n", + "│ 2025-10-08 18:00:00 ┆ 123985.5 ┆ 124169.2 ┆ 122739.7 ┆ 123237.5 ┆ -0.006051 ┆ 0.009398 ┆ 0.012186 ┆ 0.000425 ┆ 0.001761 │\n", + "│ 2025-10-09 00:00:00 ┆ 123237.4 ┆ 123279.7 ┆ 121411.8 ┆ 122052.6 ┆ -0.009661 ┆ -0.006051 ┆ 0.009398 ┆ 0.012186 ┆ 0.000425 │\n", + "│ 2025-10-09 06:00:00 ┆ 122052.6 ┆ 122777.0 ┆ 121081.5 ┆ 122672.9 ┆ 0.005069 ┆ -0.009661 ┆ -0.006051 ┆ 0.009398 ┆ 0.012186 │\n", + "│ 2025-10-09 12:00:00 ┆ 122673.0 ┆ 123740.1 ┆ 119572.8 ┆ 120915.6 ┆ -0.014429 ┆ 0.005069 ┆ -0.009661 ┆ -0.006051 ┆ 0.009398 │\n", + "│ 2025-10-09 18:00:00 ┆ 120915.5 ┆ 121712.4 ┆ 120319.0 ┆ 121579.3 ┆ 0.005474 ┆ -0.014429 ┆ 0.005069 ┆ -0.009661 ┆ -0.006051 │\n", + "└─────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────────────┴────────────────────────┴────────────────────────┴────────────────────────┴────────────────────────┘" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "no_lags = 4\n", + "ts = research.add_log_return_features(ts, 'close', forecast_horizon, max_no_lags=no_lags)\n", + "ts" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "9d1f29cf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (7, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_1,close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5478260.00536-0.0056910.041011-0.0270850.0003630.0076740.1252681.133453-0.096249-0.0351140.1342234.428597"[-0.00581579 -0.06741703 -0.00502415]""0.0005049147875979543"
"close_log_return_lag_2""close_log_return"3450.5507250.005243-0.0058370.041011-0.0270850.0002650.0076780.0914061.095714-0.107804-0.0779020.1003613.229774"[-0.06550112]""0.000496380147524178"
"close_log_return_lag_1,close_log_return_lag_2""close_log_return"3450.5478260.00525-0.0058240.041011-0.0270850.0002430.0076790.0837981.08741-0.105424-0.0623880.0927532.960678"[-0.00751353 -0.06728575]""0.0004915986792184412"
"close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5420290.005291-0.0057680.041011-0.0270850.0002260.0076790.0780951.081226-0.105911-0.0760080.087052.759004"[-0.06648943 -0.00435295]""0.0004902316140942276"
"close_log_return_lag_1""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00710889]""0.0004693868104368448"
"close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00364273]""0.00046999729238450527"
"close_log_return_lag_1,close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00266274 -0.0098902 ]""0.0004638454702217132"
" + ], + "text/plain": [ + "shape: (7, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.547826 ┆ 0.00536 ┆ -0.00569 ┆ 0.041011 ┆ -0.02708 ┆ 0.000363 ┆ 0.007674 ┆ 0.125268 ┆ 1.133453 ┆ -0.09624 ┆ -0.03511 ┆ 0.134223 ┆ 4.428597 ┆ [-0.0058 ┆ 0.000504 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 1 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 9 ┆ 4 ┆ ┆ ┆ 1579 -0. ┆ 91478759 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 06741703 ┆ 79543 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ -0.00502 ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 415] ┆ │\n", + "│ ,close_lo ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ g_return_ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.550725 ┆ 0.005243 ┆ -0.00583 ┆ 0.041011 ┆ -0.02708 ┆ 0.000265 ┆ 0.007678 ┆ 0.091406 ┆ 1.095714 ┆ -0.10780 ┆ -0.07790 ┆ 0.100361 ┆ 3.229774 ┆ [-0.0655 ┆ 0.000496 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 7 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 4 ┆ 2 ┆ ┆ ┆ 0112] ┆ 38014752 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 4178 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.547826 ┆ 0.00525 ┆ -0.00582 ┆ 0.041011 ┆ -0.02708 ┆ 0.000243 ┆ 0.007679 ┆ 0.083798 ┆ 1.08741 ┆ -0.10542 ┆ -0.06238 ┆ 0.092753 ┆ 2.960678 ┆ [-0.0075 ┆ 0.000491 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 4 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 4 ┆ 8 ┆ ┆ ┆ 1353 -0. ┆ 59867921 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 06728575 ┆ 84412 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.542029 ┆ 0.005291 ┆ -0.00576 ┆ 0.041011 ┆ -0.02708 ┆ 0.000226 ┆ 0.007679 ┆ 0.078095 ┆ 1.081226 ┆ -0.10591 ┆ -0.07600 ┆ 0.08705 ┆ 2.759004 ┆ [-0.0664 ┆ 0.000490 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 1 ┆ 8 ┆ ┆ ┆ 8943 -0. ┆ 23161409 │\n", + "│ ag_2,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 00435295 ┆ 42276 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0071 ┆ 0.000469 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 0889] ┆ 38681043 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 68448 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0036 ┆ 0.000469 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 4273] ┆ 99729238 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 450527 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0026 ┆ 0.000463 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 6274 -0. ┆ 84547022 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 0098902 ┆ 17132 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, max_no_features=3, loss=nn.MSELoss())" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "9a9bb505", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (7, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_1,close_log_return_lag_2""close_log_return"3450.5536230.005308-0.0057590.041011-0.0270850.0003680.0076740.1270051.135423-0.096249-0.0621970.135964.490131"[-0.00749043 -0.06727468]""0.00050969491712749"
"close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5478260.005308-0.0057540.041011-0.0270850.0003060.0076760.1054331.111191-0.096249-0.0508190.1143873.72613"[-0.06637757 -0.00423164]""0.0005068189930170774"
"close_log_return_lag_1,close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5478260.005281-0.0057860.041011-0.0270850.0002770.0076770.095561.100275-0.096249-0.0351140.1045153.376731"[-0.00644368 -0.0665233  -0.00492272]""0.0004986331332474947"
"close_log_return_lag_2""close_log_return"3450.5420290.005203-0.0058720.041011-0.0270850.0001310.0076810.0452591.046299-0.107804-0.0854540.0542141.598471"[-0.06582797]""0.0005011773318983614"
"close_log_return_lag_1""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00789652]""0.0004744450270663947"
"close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00401071]""0.00047311908565461636"
"close_log_return_lag_1,close_log_return_lag_3""close_log_return"3450.539130.005203-0.0058680.041011-0.0270850.0001010.0076820.0348471.035461-0.134433-0.0853380.0644741.230666"[-0.00243226 -0.00978285]""0.00047918467316776514"
" + ], + "text/plain": [ + "shape: (7, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.553623 ┆ 0.005308 ┆ -0.00575 ┆ 0.041011 ┆ -0.02708 ┆ 0.000368 ┆ 0.007674 ┆ 0.127005 ┆ 1.135423 ┆ -0.09624 ┆ -0.06219 ┆ 0.13596 ┆ 4.490131 ┆ [-0.0074 ┆ 0.000509 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 9 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 9 ┆ 7 ┆ ┆ ┆ 9043 -0. ┆ 69491712 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 06727468 ┆ 749 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.547826 ┆ 0.005308 ┆ -0.00575 ┆ 0.041011 ┆ -0.02708 ┆ 0.000306 ┆ 0.007676 ┆ 0.105433 ┆ 1.111191 ┆ -0.09624 ┆ -0.05081 ┆ 0.114387 ┆ 3.72613 ┆ [-0.0663 ┆ 0.000506 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 4 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 9 ┆ 9 ┆ ┆ ┆ 7757 -0. ┆ 81899301 │\n", + "│ ag_2,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 00423164 ┆ 70774 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.547826 ┆ 0.005281 ┆ -0.00578 ┆ 0.041011 ┆ -0.02708 ┆ 0.000277 ┆ 0.007677 ┆ 0.09556 ┆ 1.100275 ┆ -0.09624 ┆ -0.03511 ┆ 0.104515 ┆ 3.376731 ┆ [-0.0064 ┆ 0.000498 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 6 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 9 ┆ 4 ┆ ┆ ┆ 4368 -0. ┆ 63313324 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 0665233 ┆ 74947 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ -0.00492 ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 272] ┆ │\n", + "│ ,close_lo ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ g_return_ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.542029 ┆ 0.005203 ┆ -0.00587 ┆ 0.041011 ┆ -0.02708 ┆ 0.000131 ┆ 0.007681 ┆ 0.045259 ┆ 1.046299 ┆ -0.10780 ┆ -0.08545 ┆ 0.054214 ┆ 1.598471 ┆ [-0.0658 ┆ 0.000501 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 2 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 4 ┆ 4 ┆ ┆ ┆ 2797] ┆ 17733189 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 83614 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0078 ┆ 0.000474 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 9652] ┆ 44502706 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 63947 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0040 ┆ 0.000473 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 1071] ┆ 11908565 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 461636 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005203 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000101 ┆ 0.007682 ┆ 0.034847 ┆ 1.035461 ┆ -0.13443 ┆ -0.08533 ┆ 0.064474 ┆ 1.230666 ┆ [-0.0024 ┆ 0.000479 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ 8 ┆ ┆ ┆ 3226 -0. ┆ 18467316 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 00978285 ┆ 776514 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, max_no_features=3, loss=nn.HuberLoss())" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "1ec2f8c9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "shape: (7, 18)
featurestargetno_tradeswin_rateavg_winavg_lossbest_tradeworst_tradeevstdtotal_log_returncompound_returnmax_drawdownequity_troughequity_peaksharpeweightsbiases
strstri64f64f64f64f64f64f64f64f64f64f64f64f64f64strstr
"close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5565220.005499-0.0055230.041011-0.0270850.0006110.0076580.2107131.234558-0.1360030.0027460.2196687.464673"[-0.06691922 -0.06402858]""0.0005984858726151288"
"close_log_return_lag_1,close_log_return_lag_2,close_log_return_lag_3""close_log_return"3450.5565220.005497-0.0055250.041011-0.0270850.0006090.0076580.2100371.233723-0.1183490.0027460.2189917.440546"[-0.01919235 -0.08718001 -0.05782047]""0.0005492932978086174"
"close_log_return_lag_1""close_log_return"3450.5565220.0054-0.0056480.041011-0.0270850.00050.0076660.1726271.188423-0.103148-0.0145060.2089486.109042"[-0.02602334]""0.0002293637371622026"
"close_log_return_lag_3""close_log_return"3450.539130.005429-0.0056040.041011-0.0270850.0003440.0076750.1185911.12591-0.113250.0027460.1446784.19206"[-0.05110731]""0.0004618673992808908"
"close_log_return_lag_1,close_log_return_lag_3""close_log_return"3450.5565220.005224-0.0058680.041011-0.0270850.0003050.0076760.1051971.110929-0.135555-0.0307040.1211453.717782"[-0.02358585 -0.05872364]""0.0005570196663029492"
"close_log_return_lag_1,close_log_return_lag_2""close_log_return"3450.5507250.005234-0.0058480.041011-0.0270850.0002550.0076780.0880121.092001-0.10402-0.0621970.0969663.109698"[-0.0225706  -0.08143345]""0.0005113176885060966"
"close_log_return_lag_2""close_log_return"3450.5536230.005128-0.0059830.023101-0.0410110.0001690.0076810.0581941.059921-0.16492-0.0824280.0824922.055534"[-0.08116959]""0.00046614231541752815"
" + ], + "text/plain": [ + "shape: (7, 18)\n", + "┌───────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐\n", + "│ features ┆ target ┆ no_trade ┆ win_rate ┆ avg_win ┆ avg_loss ┆ best_tra ┆ worst_tr ┆ ev ┆ std ┆ total_lo ┆ compound ┆ max_draw ┆ equity_t ┆ equity_p ┆ sharpe ┆ weights ┆ biases │\n", + "│ --- ┆ --- ┆ s ┆ --- ┆ --- ┆ --- ┆ de ┆ ade ┆ --- ┆ --- ┆ g_return ┆ _return ┆ down ┆ rough ┆ eak ┆ --- ┆ --- ┆ --- │\n", + "│ str ┆ str ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ f64 ┆ str ┆ str │\n", + "│ ┆ ┆ i64 ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ ┆ │\n", + "╞═══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.556522 ┆ 0.005499 ┆ -0.00552 ┆ 0.041011 ┆ -0.02708 ┆ 0.000611 ┆ 0.007658 ┆ 0.210713 ┆ 1.234558 ┆ -0.13600 ┆ 0.002746 ┆ 0.219668 ┆ 7.464673 ┆ [-0.0669 ┆ 0.000598 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 3 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 3 ┆ ┆ ┆ ┆ 1922 -0. ┆ 48587261 │\n", + "│ ag_2,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 06402858 ┆ 51288 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.556522 ┆ 0.005497 ┆ -0.00552 ┆ 0.041011 ┆ -0.02708 ┆ 0.000609 ┆ 0.007658 ┆ 0.210037 ┆ 1.233723 ┆ -0.11834 ┆ 0.002746 ┆ 0.218991 ┆ 7.440546 ┆ [-0.0191 ┆ 0.000549 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 5 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 9 ┆ ┆ ┆ ┆ 9235 -0. ┆ 29329780 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 08718001 ┆ 86174 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ -0.05782 ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 047] ┆ │\n", + "│ ,close_lo ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ g_return_ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.556522 ┆ 0.0054 ┆ -0.00564 ┆ 0.041011 ┆ -0.02708 ┆ 0.0005 ┆ 0.007666 ┆ 0.172627 ┆ 1.188423 ┆ -0.10314 ┆ -0.01450 ┆ 0.208948 ┆ 6.109042 ┆ [-0.0260 ┆ 0.000229 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 8 ┆ 6 ┆ ┆ ┆ 2334] ┆ 36373716 │\n", + "│ ag_1 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 22026 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.53913 ┆ 0.005429 ┆ -0.00560 ┆ 0.041011 ┆ -0.02708 ┆ 0.000344 ┆ 0.007675 ┆ 0.118591 ┆ 1.12591 ┆ -0.11325 ┆ 0.002746 ┆ 0.144678 ┆ 4.19206 ┆ [-0.0511 ┆ 0.000461 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 4 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 0731] ┆ 86739928 │\n", + "│ ag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 08908 │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.556522 ┆ 0.005224 ┆ -0.00586 ┆ 0.041011 ┆ -0.02708 ┆ 0.000305 ┆ 0.007676 ┆ 0.105197 ┆ 1.110929 ┆ -0.13555 ┆ -0.03070 ┆ 0.121145 ┆ 3.717782 ┆ [-0.0235 ┆ 0.000557 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ 5 ┆ 4 ┆ ┆ ┆ 8585 -0. ┆ 01966630 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 05872364 ┆ 29492 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_3 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.550725 ┆ 0.005234 ┆ -0.00584 ┆ 0.041011 ┆ -0.02708 ┆ 0.000255 ┆ 0.007678 ┆ 0.088012 ┆ 1.092001 ┆ -0.10402 ┆ -0.06219 ┆ 0.096966 ┆ 3.109698 ┆ [-0.0225 ┆ 0.000511 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 8 ┆ ┆ 5 ┆ ┆ ┆ ┆ ┆ ┆ 7 ┆ ┆ ┆ 706 -0. ┆ 31768850 │\n", + "│ ag_1,clos ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 08143345 ┆ 60966 │\n", + "│ e_log_ret ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ] ┆ │\n", + "│ urn_lag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", + "│ close_log ┆ close_lo ┆ 345 ┆ 0.553623 ┆ 0.005128 ┆ -0.00598 ┆ 0.023101 ┆ -0.04101 ┆ 0.000169 ┆ 0.007681 ┆ 0.058194 ┆ 1.059921 ┆ -0.16492 ┆ -0.08242 ┆ 0.082492 ┆ 2.055534 ┆ [-0.0811 ┆ 0.000466 │\n", + "│ _return_l ┆ g_return ┆ ┆ ┆ ┆ 3 ┆ ┆ 1 ┆ ┆ ┆ ┆ ┆ ┆ 8 ┆ ┆ ┆ 6959] ┆ 14231541 │\n", + "│ ag_2 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ 752815 │\n", + "└───────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "research.benchmark_linear_models(ts.drop_nulls(), target, feature_pool, annualized_rate, max_no_features=3, loss=nn.L1Loss(), test_size=0.25)" + ] + }, + { + "cell_type": "markdown", + "id": "0a87ae47", + "metadata": {}, + "source": [ + "### Save Best Model (Sharpe 10 Model)" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "c644a411", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "alt.Chart(...)" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features = ['close_log_return_lag_1','close_log_return_lag_2','close_log_return_lag_3']\n", + "model = LinearModel(len(features))\n", + "model_trades = research.learn_model_trades(ts.drop_nulls(), features, target, model, loss=nn.L1Loss())\n", + "model_trades = research.add_tx_fees_log(model_trades, maker_fee, taker_fee)\n", + "research.plot_column(model_trades, 'equity_curve')" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "8b9696da", + "metadata": {}, + "outputs": [], + "source": [ + "torch.save(model.state_dict(), 'model_weights.pth')" + ] } ], "metadata": {