In [30]:
import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# CoinAPI details
API_KEY = '55144C52-5186-494D-8846-941B30A2CAAA'
BASE_URL = 'https://rest.coinapi.io/v1/'
# Trading parameters
symbol = 'BTC/USDC'
fast_window = 10 # Short-term moving average
slow_window = 50 # Long-term moving average
def get_historical_data(symbol, start_date, end_date):
headers = {'X-CoinAPI-Key': API_KEY}
url = f"{BASE_URL}ohlcv/BINANCE_SPOT_{symbol.replace('/', '_')}/history?period_id=1DAY&time_start={start_date}&time_end={end_date}"
response = requests.get(url, headers=headers)
data = response.json()
if response.status_code == 200:
return pd.DataFrame(data)
else:
print(f"Error: {response.status_code} - {response.text}")
return None
In [35]:
start_date = '2023-01-01'
end_date = '2024-01-01'
input_data = get_historical_data(symbol, start_date, end_date)
df = input_data
print(df.head())
time_period_start time_period_end \
0 2023-03-12T00:00:00.0000000Z 2023-03-13T00:00:00.0000000Z
1 2023-03-13T00:00:00.0000000Z 2023-03-14T00:00:00.0000000Z
2 2023-03-14T00:00:00.0000000Z 2023-03-15T00:00:00.0000000Z
3 2023-03-15T00:00:00.0000000Z 2023-03-16T00:00:00.0000000Z
4 2023-03-16T00:00:00.0000000Z 2023-03-17T00:00:00.0000000Z
time_open time_close price_open \
0 2023-03-12T06:30:00.0000000Z 2023-03-12T23:59:59.6710000Z 20632.41
1 2023-03-13T00:00:00.0320000Z 2023-03-13T23:59:42.8610000Z 22333.49
2 2023-03-14T00:00:06.3330000Z 2023-03-14T23:59:03.5060000Z 24242.34
3 2023-03-15T00:00:04.9890000Z 2023-03-15T23:59:55.1770000Z 24768.91
4 2023-03-16T00:00:00.2020000Z 2023-03-16T23:59:53.3150000Z 24374.81
price_high price_low price_close volume_traded trades_count
0 50000.00 20632.41 22333.49 4318.34950 130167
1 24714.04 21801.00 24241.32 1805.95550 57919
2 26517.33 24104.27 24786.18 1857.43532 71238
3 25298.33 23950.00 24374.81 803.24485 43019
4 25230.04 24205.71 25063.01 1371.40674 46140
In [17]:
def preprocess_data(df):
df['time_period_start'] = pd.to_datetime(df['time_period_start'])
df.set_index('time_period_start', inplace=True)
df['price_close'] = df['price_close'].astype(float)
return df
def backtest_strategy(df):
# Calculate the SMAs
df['fast_sma'] = df['price_close'].rolling(window=fast_window, min_periods=1).mean() # 10 days short-term
df['slow_sma'] = df['price_close'].rolling(window=slow_window, min_periods=1).mean() # 50 days long-term
# Generate signals: 1 for buy, -1 for sell
df['position'] = 0 # hold
df['position'] = np.where(df['fast_sma'] > df['slow_sma'], 1, 0) # buy btc sell usdc
df['position'] = np.where(df['fast_sma'] < df['slow_sma'], -1, df['position']) # sell btc buy usdc
# Shift position column to align with future returns
df['position'] = df['position'].shift(1).fillna(0)
# Calculate returns
df['returns'] = df['price_close'].pct_change()
df['strategy_returns'] = df['position'] * df['returns']
df['cumulative_returns'] = (1 + df['strategy_returns']).cumprod()
return df
In [18]:
print(df.head)
df = preprocess_data(df)
print(df)
df = backtest_strategy(df)
print(df)
<bound method NDFrame.head of time_period_start time_period_end \
0 2023-03-12T00:00:00.0000000Z 2023-03-13T00:00:00.0000000Z
1 2023-03-13T00:00:00.0000000Z 2023-03-14T00:00:00.0000000Z
2 2023-03-14T00:00:00.0000000Z 2023-03-15T00:00:00.0000000Z
3 2023-03-15T00:00:00.0000000Z 2023-03-16T00:00:00.0000000Z
4 2023-03-16T00:00:00.0000000Z 2023-03-17T00:00:00.0000000Z
5 2023-03-17T00:00:00.0000000Z 2023-03-18T00:00:00.0000000Z
6 2023-03-18T00:00:00.0000000Z 2023-03-19T00:00:00.0000000Z
7 2023-03-19T00:00:00.0000000Z 2023-03-20T00:00:00.0000000Z
8 2023-03-20T00:00:00.0000000Z 2023-03-21T00:00:00.0000000Z
9 2023-03-21T00:00:00.0000000Z 2023-03-22T00:00:00.0000000Z
10 2023-03-22T00:00:00.0000000Z 2023-03-23T00:00:00.0000000Z
11 2023-03-23T00:00:00.0000000Z 2023-03-24T00:00:00.0000000Z
12 2023-03-24T00:00:00.0000000Z 2023-03-25T00:00:00.0000000Z
13 2023-03-25T00:00:00.0000000Z 2023-03-26T00:00:00.0000000Z
14 2023-03-26T00:00:00.0000000Z 2023-03-27T00:00:00.0000000Z
15 2023-03-27T00:00:00.0000000Z 2023-03-28T00:00:00.0000000Z
16 2023-03-28T00:00:00.0000000Z 2023-03-29T00:00:00.0000000Z
17 2023-03-29T00:00:00.0000000Z 2023-03-30T00:00:00.0000000Z
18 2023-03-30T00:00:00.0000000Z 2023-03-31T00:00:00.0000000Z
19 2023-03-31T00:00:00.0000000Z 2023-04-01T00:00:00.0000000Z
20 2023-04-01T00:00:00.0000000Z 2023-04-02T00:00:00.0000000Z
21 2023-04-02T00:00:00.0000000Z 2023-04-03T00:00:00.0000000Z
22 2023-04-03T00:00:00.0000000Z 2023-04-04T00:00:00.0000000Z
23 2023-04-04T00:00:00.0000000Z 2023-04-05T00:00:00.0000000Z
24 2023-04-05T00:00:00.0000000Z 2023-04-06T00:00:00.0000000Z
25 2023-04-06T00:00:00.0000000Z 2023-04-07T00:00:00.0000000Z
26 2023-04-07T00:00:00.0000000Z 2023-04-08T00:00:00.0000000Z
27 2023-04-08T00:00:00.0000000Z 2023-04-09T00:00:00.0000000Z
28 2023-04-09T00:00:00.0000000Z 2023-04-10T00:00:00.0000000Z
29 2023-04-10T00:00:00.0000000Z 2023-04-11T00:00:00.0000000Z
30 2023-04-11T00:00:00.0000000Z 2023-04-12T00:00:00.0000000Z
time_open time_close price_open \
0 2023-03-12T06:30:00.0000000Z 2023-03-12T23:59:59.6710000Z 20632.41
1 2023-03-13T00:00:00.0320000Z 2023-03-13T23:59:42.8610000Z 22333.49
2 2023-03-14T00:00:06.3330000Z 2023-03-14T23:59:03.5060000Z 24242.34
3 2023-03-15T00:00:04.9890000Z 2023-03-15T23:59:55.1770000Z 24768.91
4 2023-03-16T00:00:00.2020000Z 2023-03-16T23:59:53.3150000Z 24374.81
5 2023-03-17T00:00:08.1960000Z 2023-03-17T23:59:54.8770000Z 25059.84
6 2023-03-18T00:00:03.6600000Z 2023-03-18T23:59:59.4430000Z 27454.26
7 2023-03-19T00:00:15.7380000Z 2023-03-19T23:59:59.7770000Z 26998.84
8 2023-03-20T00:00:07.7510000Z 2023-03-20T23:59:38.0890000Z 28059.66
9 2023-03-21T00:00:07.2410000Z 2023-03-21T23:59:48.0000000Z 27826.88
10 2023-03-22T00:00:06.7430000Z 2023-03-22T23:59:33.4620000Z 28189.05
11 2023-03-23T00:01:06.3950000Z 2023-03-23T23:59:17.9110000Z 27317.68
12 2023-03-24T00:00:59.8000000Z 2023-03-24T23:59:57.8500000Z 28365.28
13 2023-03-25T00:00:08.1510000Z 2023-03-25T23:59:17.4090000Z 27491.99
14 2023-03-26T00:01:13.1400000Z 2023-03-26T23:59:56.9530000Z 27487.31
15 2023-03-27T00:01:14.1970000Z 2023-03-27T23:59:55.3110000Z 27978.05
16 2023-03-28T00:00:00.2840000Z 2023-03-28T23:59:06.1670000Z 27140.17
17 2023-03-29T00:00:48.4570000Z 2023-03-29T23:59:58.3480000Z 27281.05
18 2023-03-30T00:01:05.0010000Z 2023-03-30T23:59:50.5800000Z 28359.05
19 2023-03-31T00:01:01.5960000Z 2023-03-31T23:59:59.9410000Z 28035.37
20 2023-04-01T00:00:00.5280000Z 2023-04-01T23:59:12.3380000Z 28472.49
21 2023-04-02T00:01:21.3490000Z 2023-04-02T23:59:48.5890000Z 28466.67
22 2023-04-03T00:00:08.5880000Z 2023-04-03T23:59:28.9370000Z 28182.28
23 2023-04-04T00:00:07.8470000Z 2023-04-04T23:59:55.9010000Z 27813.05
24 2023-04-05T00:00:47.3440000Z 2023-04-05T23:59:39.8990000Z 28177.50
25 2023-04-06T00:01:00.2600000Z 2023-04-06T23:59:44.0880000Z 28183.88
26 2023-04-07T00:01:11.7600000Z 2023-04-07T23:59:50.8230000Z 28050.36
27 2023-04-08T00:00:58.6360000Z 2023-04-08T23:59:22.4870000Z 27926.84
28 2023-04-09T00:01:12.7850000Z 2023-04-09T23:58:42.2020000Z 27951.67
29 2023-04-10T00:00:05.4290000Z 2023-04-10T23:59:58.4440000Z 28338.15
30 2023-04-11T00:00:05.9150000Z 2023-04-11T23:59:41.2660000Z 29657.76
price_high price_low price_close volume_traded trades_count
0 50000.00 20632.41 22333.49 4318.34950 130167
1 24714.04 21801.00 24241.32 1805.95550 57919
2 26517.33 24104.27 24786.18 1857.43532 71238
3 25298.33 23950.00 24374.81 803.24485 43019
4 25230.04 24205.71 25063.01 1371.40674 46140
5 27818.52 24945.75 27451.93 1059.97009 64899
6 27772.84 26643.96 26982.34 633.36447 41394
7 28468.94 26909.47 28054.40 761.85567 39622
8 28563.18 27226.66 27835.62 1238.34558 59921
9 28580.94 27420.68 28191.52 1203.83838 53225
10 28947.00 26695.43 27324.27 1733.31922 42039
11 28826.85 27190.78 28350.74 1042.59023 30186
12 28433.22 27029.88 27486.49 816.50287 24490
13 27813.59 27190.79 27502.06 271.56665 13957
14 28200.00 27443.56 27996.95 269.37438 12299
15 28046.87 26531.00 27140.82 553.79497 18983
16 27500.42 26641.22 27273.97 506.00492 18711
17 28645.13 27243.52 28357.71 633.95321 18332
18 29185.45 27695.32 28030.43 952.16462 24844
19 28658.90 27545.37 28472.49 541.94933 16316
20 28823.62 28241.05 28466.23 213.00768 7076
21 28535.51 27879.54 28177.74 199.36751 9893
22 28515.99 27233.32 27818.22 617.39556 21083
23 28440.92 27675.53 28183.42 481.80366 13376
24 28776.70 27800.01 28175.81 354.12609 12278
25 28194.34 27732.22 28047.53 681.87010 15848
26 28117.07 27788.94 27928.36 191.35023 6687
27 28170.09 27882.14 27956.26 167.75125 5982
28 28545.07 27809.01 28338.15 310.76101 9535
29 29800.00 28185.43 29657.37 724.45678 17293
30 30591.90 29620.80 30236.61 849.70928 21946 >
time_period_end \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-13T00:00:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-14T00:00:00.0000000Z
2023-03-14 00:00:00+00:00 2023-03-15T00:00:00.0000000Z
2023-03-15 00:00:00+00:00 2023-03-16T00:00:00.0000000Z
2023-03-16 00:00:00+00:00 2023-03-17T00:00:00.0000000Z
2023-03-17 00:00:00+00:00 2023-03-18T00:00:00.0000000Z
2023-03-18 00:00:00+00:00 2023-03-19T00:00:00.0000000Z
2023-03-19 00:00:00+00:00 2023-03-20T00:00:00.0000000Z
2023-03-20 00:00:00+00:00 2023-03-21T00:00:00.0000000Z
2023-03-21 00:00:00+00:00 2023-03-22T00:00:00.0000000Z
2023-03-22 00:00:00+00:00 2023-03-23T00:00:00.0000000Z
2023-03-23 00:00:00+00:00 2023-03-24T00:00:00.0000000Z
2023-03-24 00:00:00+00:00 2023-03-25T00:00:00.0000000Z
2023-03-25 00:00:00+00:00 2023-03-26T00:00:00.0000000Z
2023-03-26 00:00:00+00:00 2023-03-27T00:00:00.0000000Z
2023-03-27 00:00:00+00:00 2023-03-28T00:00:00.0000000Z
2023-03-28 00:00:00+00:00 2023-03-29T00:00:00.0000000Z
2023-03-29 00:00:00+00:00 2023-03-30T00:00:00.0000000Z
2023-03-30 00:00:00+00:00 2023-03-31T00:00:00.0000000Z
2023-03-31 00:00:00+00:00 2023-04-01T00:00:00.0000000Z
2023-04-01 00:00:00+00:00 2023-04-02T00:00:00.0000000Z
2023-04-02 00:00:00+00:00 2023-04-03T00:00:00.0000000Z
2023-04-03 00:00:00+00:00 2023-04-04T00:00:00.0000000Z
2023-04-04 00:00:00+00:00 2023-04-05T00:00:00.0000000Z
2023-04-05 00:00:00+00:00 2023-04-06T00:00:00.0000000Z
2023-04-06 00:00:00+00:00 2023-04-07T00:00:00.0000000Z
2023-04-07 00:00:00+00:00 2023-04-08T00:00:00.0000000Z
2023-04-08 00:00:00+00:00 2023-04-09T00:00:00.0000000Z
2023-04-09 00:00:00+00:00 2023-04-10T00:00:00.0000000Z
2023-04-10 00:00:00+00:00 2023-04-11T00:00:00.0000000Z
2023-04-11 00:00:00+00:00 2023-04-12T00:00:00.0000000Z
time_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T06:30:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-13T00:00:00.0320000Z
2023-03-14 00:00:00+00:00 2023-03-14T00:00:06.3330000Z
2023-03-15 00:00:00+00:00 2023-03-15T00:00:04.9890000Z
2023-03-16 00:00:00+00:00 2023-03-16T00:00:00.2020000Z
2023-03-17 00:00:00+00:00 2023-03-17T00:00:08.1960000Z
2023-03-18 00:00:00+00:00 2023-03-18T00:00:03.6600000Z
2023-03-19 00:00:00+00:00 2023-03-19T00:00:15.7380000Z
2023-03-20 00:00:00+00:00 2023-03-20T00:00:07.7510000Z
2023-03-21 00:00:00+00:00 2023-03-21T00:00:07.2410000Z
2023-03-22 00:00:00+00:00 2023-03-22T00:00:06.7430000Z
2023-03-23 00:00:00+00:00 2023-03-23T00:01:06.3950000Z
2023-03-24 00:00:00+00:00 2023-03-24T00:00:59.8000000Z
2023-03-25 00:00:00+00:00 2023-03-25T00:00:08.1510000Z
2023-03-26 00:00:00+00:00 2023-03-26T00:01:13.1400000Z
2023-03-27 00:00:00+00:00 2023-03-27T00:01:14.1970000Z
2023-03-28 00:00:00+00:00 2023-03-28T00:00:00.2840000Z
2023-03-29 00:00:00+00:00 2023-03-29T00:00:48.4570000Z
2023-03-30 00:00:00+00:00 2023-03-30T00:01:05.0010000Z
2023-03-31 00:00:00+00:00 2023-03-31T00:01:01.5960000Z
2023-04-01 00:00:00+00:00 2023-04-01T00:00:00.5280000Z
2023-04-02 00:00:00+00:00 2023-04-02T00:01:21.3490000Z
2023-04-03 00:00:00+00:00 2023-04-03T00:00:08.5880000Z
2023-04-04 00:00:00+00:00 2023-04-04T00:00:07.8470000Z
2023-04-05 00:00:00+00:00 2023-04-05T00:00:47.3440000Z
2023-04-06 00:00:00+00:00 2023-04-06T00:01:00.2600000Z
2023-04-07 00:00:00+00:00 2023-04-07T00:01:11.7600000Z
2023-04-08 00:00:00+00:00 2023-04-08T00:00:58.6360000Z
2023-04-09 00:00:00+00:00 2023-04-09T00:01:12.7850000Z
2023-04-10 00:00:00+00:00 2023-04-10T00:00:05.4290000Z
2023-04-11 00:00:00+00:00 2023-04-11T00:00:05.9150000Z
time_close price_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T23:59:59.6710000Z 20632.41
2023-03-13 00:00:00+00:00 2023-03-13T23:59:42.8610000Z 22333.49
2023-03-14 00:00:00+00:00 2023-03-14T23:59:03.5060000Z 24242.34
2023-03-15 00:00:00+00:00 2023-03-15T23:59:55.1770000Z 24768.91
2023-03-16 00:00:00+00:00 2023-03-16T23:59:53.3150000Z 24374.81
2023-03-17 00:00:00+00:00 2023-03-17T23:59:54.8770000Z 25059.84
2023-03-18 00:00:00+00:00 2023-03-18T23:59:59.4430000Z 27454.26
2023-03-19 00:00:00+00:00 2023-03-19T23:59:59.7770000Z 26998.84
2023-03-20 00:00:00+00:00 2023-03-20T23:59:38.0890000Z 28059.66
2023-03-21 00:00:00+00:00 2023-03-21T23:59:48.0000000Z 27826.88
2023-03-22 00:00:00+00:00 2023-03-22T23:59:33.4620000Z 28189.05
2023-03-23 00:00:00+00:00 2023-03-23T23:59:17.9110000Z 27317.68
2023-03-24 00:00:00+00:00 2023-03-24T23:59:57.8500000Z 28365.28
2023-03-25 00:00:00+00:00 2023-03-25T23:59:17.4090000Z 27491.99
2023-03-26 00:00:00+00:00 2023-03-26T23:59:56.9530000Z 27487.31
2023-03-27 00:00:00+00:00 2023-03-27T23:59:55.3110000Z 27978.05
2023-03-28 00:00:00+00:00 2023-03-28T23:59:06.1670000Z 27140.17
2023-03-29 00:00:00+00:00 2023-03-29T23:59:58.3480000Z 27281.05
2023-03-30 00:00:00+00:00 2023-03-30T23:59:50.5800000Z 28359.05
2023-03-31 00:00:00+00:00 2023-03-31T23:59:59.9410000Z 28035.37
2023-04-01 00:00:00+00:00 2023-04-01T23:59:12.3380000Z 28472.49
2023-04-02 00:00:00+00:00 2023-04-02T23:59:48.5890000Z 28466.67
2023-04-03 00:00:00+00:00 2023-04-03T23:59:28.9370000Z 28182.28
2023-04-04 00:00:00+00:00 2023-04-04T23:59:55.9010000Z 27813.05
2023-04-05 00:00:00+00:00 2023-04-05T23:59:39.8990000Z 28177.50
2023-04-06 00:00:00+00:00 2023-04-06T23:59:44.0880000Z 28183.88
2023-04-07 00:00:00+00:00 2023-04-07T23:59:50.8230000Z 28050.36
2023-04-08 00:00:00+00:00 2023-04-08T23:59:22.4870000Z 27926.84
2023-04-09 00:00:00+00:00 2023-04-09T23:58:42.2020000Z 27951.67
2023-04-10 00:00:00+00:00 2023-04-10T23:59:58.4440000Z 28338.15
2023-04-11 00:00:00+00:00 2023-04-11T23:59:41.2660000Z 29657.76
price_high price_low price_close volume_traded \
time_period_start
2023-03-12 00:00:00+00:00 50000.00 20632.41 22333.49 4318.34950
2023-03-13 00:00:00+00:00 24714.04 21801.00 24241.32 1805.95550
2023-03-14 00:00:00+00:00 26517.33 24104.27 24786.18 1857.43532
2023-03-15 00:00:00+00:00 25298.33 23950.00 24374.81 803.24485
2023-03-16 00:00:00+00:00 25230.04 24205.71 25063.01 1371.40674
2023-03-17 00:00:00+00:00 27818.52 24945.75 27451.93 1059.97009
2023-03-18 00:00:00+00:00 27772.84 26643.96 26982.34 633.36447
2023-03-19 00:00:00+00:00 28468.94 26909.47 28054.40 761.85567
2023-03-20 00:00:00+00:00 28563.18 27226.66 27835.62 1238.34558
2023-03-21 00:00:00+00:00 28580.94 27420.68 28191.52 1203.83838
2023-03-22 00:00:00+00:00 28947.00 26695.43 27324.27 1733.31922
2023-03-23 00:00:00+00:00 28826.85 27190.78 28350.74 1042.59023
2023-03-24 00:00:00+00:00 28433.22 27029.88 27486.49 816.50287
2023-03-25 00:00:00+00:00 27813.59 27190.79 27502.06 271.56665
2023-03-26 00:00:00+00:00 28200.00 27443.56 27996.95 269.37438
2023-03-27 00:00:00+00:00 28046.87 26531.00 27140.82 553.79497
2023-03-28 00:00:00+00:00 27500.42 26641.22 27273.97 506.00492
2023-03-29 00:00:00+00:00 28645.13 27243.52 28357.71 633.95321
2023-03-30 00:00:00+00:00 29185.45 27695.32 28030.43 952.16462
2023-03-31 00:00:00+00:00 28658.90 27545.37 28472.49 541.94933
2023-04-01 00:00:00+00:00 28823.62 28241.05 28466.23 213.00768
2023-04-02 00:00:00+00:00 28535.51 27879.54 28177.74 199.36751
2023-04-03 00:00:00+00:00 28515.99 27233.32 27818.22 617.39556
2023-04-04 00:00:00+00:00 28440.92 27675.53 28183.42 481.80366
2023-04-05 00:00:00+00:00 28776.70 27800.01 28175.81 354.12609
2023-04-06 00:00:00+00:00 28194.34 27732.22 28047.53 681.87010
2023-04-07 00:00:00+00:00 28117.07 27788.94 27928.36 191.35023
2023-04-08 00:00:00+00:00 28170.09 27882.14 27956.26 167.75125
2023-04-09 00:00:00+00:00 28545.07 27809.01 28338.15 310.76101
2023-04-10 00:00:00+00:00 29800.00 28185.43 29657.37 724.45678
2023-04-11 00:00:00+00:00 30591.90 29620.80 30236.61 849.70928
trades_count
time_period_start
2023-03-12 00:00:00+00:00 130167
2023-03-13 00:00:00+00:00 57919
2023-03-14 00:00:00+00:00 71238
2023-03-15 00:00:00+00:00 43019
2023-03-16 00:00:00+00:00 46140
2023-03-17 00:00:00+00:00 64899
2023-03-18 00:00:00+00:00 41394
2023-03-19 00:00:00+00:00 39622
2023-03-20 00:00:00+00:00 59921
2023-03-21 00:00:00+00:00 53225
2023-03-22 00:00:00+00:00 42039
2023-03-23 00:00:00+00:00 30186
2023-03-24 00:00:00+00:00 24490
2023-03-25 00:00:00+00:00 13957
2023-03-26 00:00:00+00:00 12299
2023-03-27 00:00:00+00:00 18983
2023-03-28 00:00:00+00:00 18711
2023-03-29 00:00:00+00:00 18332
2023-03-30 00:00:00+00:00 24844
2023-03-31 00:00:00+00:00 16316
2023-04-01 00:00:00+00:00 7076
2023-04-02 00:00:00+00:00 9893
2023-04-03 00:00:00+00:00 21083
2023-04-04 00:00:00+00:00 13376
2023-04-05 00:00:00+00:00 12278
2023-04-06 00:00:00+00:00 15848
2023-04-07 00:00:00+00:00 6687
2023-04-08 00:00:00+00:00 5982
2023-04-09 00:00:00+00:00 9535
2023-04-10 00:00:00+00:00 17293
2023-04-11 00:00:00+00:00 21946
time_period_end \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-13T00:00:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-14T00:00:00.0000000Z
2023-03-14 00:00:00+00:00 2023-03-15T00:00:00.0000000Z
2023-03-15 00:00:00+00:00 2023-03-16T00:00:00.0000000Z
2023-03-16 00:00:00+00:00 2023-03-17T00:00:00.0000000Z
2023-03-17 00:00:00+00:00 2023-03-18T00:00:00.0000000Z
2023-03-18 00:00:00+00:00 2023-03-19T00:00:00.0000000Z
2023-03-19 00:00:00+00:00 2023-03-20T00:00:00.0000000Z
2023-03-20 00:00:00+00:00 2023-03-21T00:00:00.0000000Z
2023-03-21 00:00:00+00:00 2023-03-22T00:00:00.0000000Z
2023-03-22 00:00:00+00:00 2023-03-23T00:00:00.0000000Z
2023-03-23 00:00:00+00:00 2023-03-24T00:00:00.0000000Z
2023-03-24 00:00:00+00:00 2023-03-25T00:00:00.0000000Z
2023-03-25 00:00:00+00:00 2023-03-26T00:00:00.0000000Z
2023-03-26 00:00:00+00:00 2023-03-27T00:00:00.0000000Z
2023-03-27 00:00:00+00:00 2023-03-28T00:00:00.0000000Z
2023-03-28 00:00:00+00:00 2023-03-29T00:00:00.0000000Z
2023-03-29 00:00:00+00:00 2023-03-30T00:00:00.0000000Z
2023-03-30 00:00:00+00:00 2023-03-31T00:00:00.0000000Z
2023-03-31 00:00:00+00:00 2023-04-01T00:00:00.0000000Z
2023-04-01 00:00:00+00:00 2023-04-02T00:00:00.0000000Z
2023-04-02 00:00:00+00:00 2023-04-03T00:00:00.0000000Z
2023-04-03 00:00:00+00:00 2023-04-04T00:00:00.0000000Z
2023-04-04 00:00:00+00:00 2023-04-05T00:00:00.0000000Z
2023-04-05 00:00:00+00:00 2023-04-06T00:00:00.0000000Z
2023-04-06 00:00:00+00:00 2023-04-07T00:00:00.0000000Z
2023-04-07 00:00:00+00:00 2023-04-08T00:00:00.0000000Z
2023-04-08 00:00:00+00:00 2023-04-09T00:00:00.0000000Z
2023-04-09 00:00:00+00:00 2023-04-10T00:00:00.0000000Z
2023-04-10 00:00:00+00:00 2023-04-11T00:00:00.0000000Z
2023-04-11 00:00:00+00:00 2023-04-12T00:00:00.0000000Z
time_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T06:30:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-13T00:00:00.0320000Z
2023-03-14 00:00:00+00:00 2023-03-14T00:00:06.3330000Z
2023-03-15 00:00:00+00:00 2023-03-15T00:00:04.9890000Z
2023-03-16 00:00:00+00:00 2023-03-16T00:00:00.2020000Z
2023-03-17 00:00:00+00:00 2023-03-17T00:00:08.1960000Z
2023-03-18 00:00:00+00:00 2023-03-18T00:00:03.6600000Z
2023-03-19 00:00:00+00:00 2023-03-19T00:00:15.7380000Z
2023-03-20 00:00:00+00:00 2023-03-20T00:00:07.7510000Z
2023-03-21 00:00:00+00:00 2023-03-21T00:00:07.2410000Z
2023-03-22 00:00:00+00:00 2023-03-22T00:00:06.7430000Z
2023-03-23 00:00:00+00:00 2023-03-23T00:01:06.3950000Z
2023-03-24 00:00:00+00:00 2023-03-24T00:00:59.8000000Z
2023-03-25 00:00:00+00:00 2023-03-25T00:00:08.1510000Z
2023-03-26 00:00:00+00:00 2023-03-26T00:01:13.1400000Z
2023-03-27 00:00:00+00:00 2023-03-27T00:01:14.1970000Z
2023-03-28 00:00:00+00:00 2023-03-28T00:00:00.2840000Z
2023-03-29 00:00:00+00:00 2023-03-29T00:00:48.4570000Z
2023-03-30 00:00:00+00:00 2023-03-30T00:01:05.0010000Z
2023-03-31 00:00:00+00:00 2023-03-31T00:01:01.5960000Z
2023-04-01 00:00:00+00:00 2023-04-01T00:00:00.5280000Z
2023-04-02 00:00:00+00:00 2023-04-02T00:01:21.3490000Z
2023-04-03 00:00:00+00:00 2023-04-03T00:00:08.5880000Z
2023-04-04 00:00:00+00:00 2023-04-04T00:00:07.8470000Z
2023-04-05 00:00:00+00:00 2023-04-05T00:00:47.3440000Z
2023-04-06 00:00:00+00:00 2023-04-06T00:01:00.2600000Z
2023-04-07 00:00:00+00:00 2023-04-07T00:01:11.7600000Z
2023-04-08 00:00:00+00:00 2023-04-08T00:00:58.6360000Z
2023-04-09 00:00:00+00:00 2023-04-09T00:01:12.7850000Z
2023-04-10 00:00:00+00:00 2023-04-10T00:00:05.4290000Z
2023-04-11 00:00:00+00:00 2023-04-11T00:00:05.9150000Z
time_close price_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T23:59:59.6710000Z 20632.41
2023-03-13 00:00:00+00:00 2023-03-13T23:59:42.8610000Z 22333.49
2023-03-14 00:00:00+00:00 2023-03-14T23:59:03.5060000Z 24242.34
2023-03-15 00:00:00+00:00 2023-03-15T23:59:55.1770000Z 24768.91
2023-03-16 00:00:00+00:00 2023-03-16T23:59:53.3150000Z 24374.81
2023-03-17 00:00:00+00:00 2023-03-17T23:59:54.8770000Z 25059.84
2023-03-18 00:00:00+00:00 2023-03-18T23:59:59.4430000Z 27454.26
2023-03-19 00:00:00+00:00 2023-03-19T23:59:59.7770000Z 26998.84
2023-03-20 00:00:00+00:00 2023-03-20T23:59:38.0890000Z 28059.66
2023-03-21 00:00:00+00:00 2023-03-21T23:59:48.0000000Z 27826.88
2023-03-22 00:00:00+00:00 2023-03-22T23:59:33.4620000Z 28189.05
2023-03-23 00:00:00+00:00 2023-03-23T23:59:17.9110000Z 27317.68
2023-03-24 00:00:00+00:00 2023-03-24T23:59:57.8500000Z 28365.28
2023-03-25 00:00:00+00:00 2023-03-25T23:59:17.4090000Z 27491.99
2023-03-26 00:00:00+00:00 2023-03-26T23:59:56.9530000Z 27487.31
2023-03-27 00:00:00+00:00 2023-03-27T23:59:55.3110000Z 27978.05
2023-03-28 00:00:00+00:00 2023-03-28T23:59:06.1670000Z 27140.17
2023-03-29 00:00:00+00:00 2023-03-29T23:59:58.3480000Z 27281.05
2023-03-30 00:00:00+00:00 2023-03-30T23:59:50.5800000Z 28359.05
2023-03-31 00:00:00+00:00 2023-03-31T23:59:59.9410000Z 28035.37
2023-04-01 00:00:00+00:00 2023-04-01T23:59:12.3380000Z 28472.49
2023-04-02 00:00:00+00:00 2023-04-02T23:59:48.5890000Z 28466.67
2023-04-03 00:00:00+00:00 2023-04-03T23:59:28.9370000Z 28182.28
2023-04-04 00:00:00+00:00 2023-04-04T23:59:55.9010000Z 27813.05
2023-04-05 00:00:00+00:00 2023-04-05T23:59:39.8990000Z 28177.50
2023-04-06 00:00:00+00:00 2023-04-06T23:59:44.0880000Z 28183.88
2023-04-07 00:00:00+00:00 2023-04-07T23:59:50.8230000Z 28050.36
2023-04-08 00:00:00+00:00 2023-04-08T23:59:22.4870000Z 27926.84
2023-04-09 00:00:00+00:00 2023-04-09T23:58:42.2020000Z 27951.67
2023-04-10 00:00:00+00:00 2023-04-10T23:59:58.4440000Z 28338.15
2023-04-11 00:00:00+00:00 2023-04-11T23:59:41.2660000Z 29657.76
price_high price_low price_close volume_traded \
time_period_start
2023-03-12 00:00:00+00:00 50000.00 20632.41 22333.49 4318.34950
2023-03-13 00:00:00+00:00 24714.04 21801.00 24241.32 1805.95550
2023-03-14 00:00:00+00:00 26517.33 24104.27 24786.18 1857.43532
2023-03-15 00:00:00+00:00 25298.33 23950.00 24374.81 803.24485
2023-03-16 00:00:00+00:00 25230.04 24205.71 25063.01 1371.40674
2023-03-17 00:00:00+00:00 27818.52 24945.75 27451.93 1059.97009
2023-03-18 00:00:00+00:00 27772.84 26643.96 26982.34 633.36447
2023-03-19 00:00:00+00:00 28468.94 26909.47 28054.40 761.85567
2023-03-20 00:00:00+00:00 28563.18 27226.66 27835.62 1238.34558
2023-03-21 00:00:00+00:00 28580.94 27420.68 28191.52 1203.83838
2023-03-22 00:00:00+00:00 28947.00 26695.43 27324.27 1733.31922
2023-03-23 00:00:00+00:00 28826.85 27190.78 28350.74 1042.59023
2023-03-24 00:00:00+00:00 28433.22 27029.88 27486.49 816.50287
2023-03-25 00:00:00+00:00 27813.59 27190.79 27502.06 271.56665
2023-03-26 00:00:00+00:00 28200.00 27443.56 27996.95 269.37438
2023-03-27 00:00:00+00:00 28046.87 26531.00 27140.82 553.79497
2023-03-28 00:00:00+00:00 27500.42 26641.22 27273.97 506.00492
2023-03-29 00:00:00+00:00 28645.13 27243.52 28357.71 633.95321
2023-03-30 00:00:00+00:00 29185.45 27695.32 28030.43 952.16462
2023-03-31 00:00:00+00:00 28658.90 27545.37 28472.49 541.94933
2023-04-01 00:00:00+00:00 28823.62 28241.05 28466.23 213.00768
2023-04-02 00:00:00+00:00 28535.51 27879.54 28177.74 199.36751
2023-04-03 00:00:00+00:00 28515.99 27233.32 27818.22 617.39556
2023-04-04 00:00:00+00:00 28440.92 27675.53 28183.42 481.80366
2023-04-05 00:00:00+00:00 28776.70 27800.01 28175.81 354.12609
2023-04-06 00:00:00+00:00 28194.34 27732.22 28047.53 681.87010
2023-04-07 00:00:00+00:00 28117.07 27788.94 27928.36 191.35023
2023-04-08 00:00:00+00:00 28170.09 27882.14 27956.26 167.75125
2023-04-09 00:00:00+00:00 28545.07 27809.01 28338.15 310.76101
2023-04-10 00:00:00+00:00 29800.00 28185.43 29657.37 724.45678
2023-04-11 00:00:00+00:00 30591.90 29620.80 30236.61 849.70928
trades_count fast_sma slow_sma position \
time_period_start
2023-03-12 00:00:00+00:00 130167 22333.490000 22333.490000 0.0
2023-03-13 00:00:00+00:00 57919 23287.405000 23287.405000 0.0
2023-03-14 00:00:00+00:00 71238 23786.996667 23786.996667 0.0
2023-03-15 00:00:00+00:00 43019 23933.950000 23933.950000 0.0
2023-03-16 00:00:00+00:00 46140 24159.762000 24159.762000 0.0
2023-03-17 00:00:00+00:00 64899 24708.456667 24708.456667 0.0
2023-03-18 00:00:00+00:00 41394 25033.297143 25033.297143 0.0
2023-03-19 00:00:00+00:00 39622 25410.935000 25410.935000 0.0
2023-03-20 00:00:00+00:00 59921 25680.344444 25680.344444 0.0
2023-03-21 00:00:00+00:00 53225 25931.462000 25931.462000 0.0
2023-03-22 00:00:00+00:00 42039 26430.540000 26058.080909 0.0
2023-03-23 00:00:00+00:00 30186 26841.482000 26249.135833 1.0
2023-03-24 00:00:00+00:00 24490 27111.513000 26344.316923 1.0
2023-03-25 00:00:00+00:00 13957 27424.238000 26427.012857 1.0
2023-03-26 00:00:00+00:00 12299 27717.632000 26531.675333 1.0
2023-03-27 00:00:00+00:00 18983 27686.521000 26569.746875 1.0
2023-03-28 00:00:00+00:00 18711 27715.684000 26611.171765 1.0
2023-03-29 00:00:00+00:00 18332 27746.015000 26708.201667 1.0
2023-03-30 00:00:00+00:00 24844 27765.496000 26777.792632 1.0
2023-03-31 00:00:00+00:00 16316 27793.593000 26862.527500 1.0
2023-04-01 00:00:00+00:00 7076 27907.789000 26938.894286 1.0
2023-04-02 00:00:00+00:00 9893 27890.489000 26995.205455 1.0
2023-04-03 00:00:00+00:00 21083 27923.662000 27030.988696 1.0
2023-04-04 00:00:00+00:00 13376 27991.798000 27079.006667 1.0
2023-04-05 00:00:00+00:00 12278 28009.684000 27122.878800 1.0
2023-04-06 00:00:00+00:00 15848 28100.355000 27158.442308 1.0
2023-04-07 00:00:00+00:00 6687 28165.794000 27186.957778 1.0
2023-04-08 00:00:00+00:00 5982 28125.649000 27214.432857 1.0
2023-04-09 00:00:00+00:00 9535 28156.421000 27253.181724 1.0
2023-04-10 00:00:00+00:00 17293 28274.909000 27333.321333 1.0
2023-04-11 00:00:00+00:00 21946 28451.947000 27426.975806 1.0
returns strategy_returns cumulative_returns
time_period_start
2023-03-12 00:00:00+00:00 NaN NaN NaN
2023-03-13 00:00:00+00:00 0.085425 0.000000 1.000000
2023-03-14 00:00:00+00:00 0.022476 0.000000 1.000000
2023-03-15 00:00:00+00:00 -0.016597 -0.000000 1.000000
2023-03-16 00:00:00+00:00 0.028234 0.000000 1.000000
2023-03-17 00:00:00+00:00 0.095317 0.000000 1.000000
2023-03-18 00:00:00+00:00 -0.017106 -0.000000 1.000000
2023-03-19 00:00:00+00:00 0.039732 0.000000 1.000000
2023-03-20 00:00:00+00:00 -0.007798 -0.000000 1.000000
2023-03-21 00:00:00+00:00 0.012786 0.000000 1.000000
2023-03-22 00:00:00+00:00 -0.030763 -0.000000 1.000000
2023-03-23 00:00:00+00:00 0.037566 0.037566 1.037566
2023-03-24 00:00:00+00:00 -0.030484 -0.030484 1.005937
2023-03-25 00:00:00+00:00 0.000566 0.000566 1.006507
2023-03-26 00:00:00+00:00 0.017995 0.017995 1.024618
2023-03-27 00:00:00+00:00 -0.030579 -0.030579 0.993286
2023-03-28 00:00:00+00:00 0.004906 0.004906 0.998159
2023-03-29 00:00:00+00:00 0.039735 0.039735 1.037821
2023-03-30 00:00:00+00:00 -0.011541 -0.011541 1.025844
2023-03-31 00:00:00+00:00 0.015771 0.015771 1.042022
2023-04-01 00:00:00+00:00 -0.000220 -0.000220 1.041793
2023-04-02 00:00:00+00:00 -0.010134 -0.010134 1.031235
2023-04-03 00:00:00+00:00 -0.012759 -0.012759 1.018077
2023-04-04 00:00:00+00:00 0.013128 0.013128 1.031443
2023-04-05 00:00:00+00:00 -0.000270 -0.000270 1.031164
2023-04-06 00:00:00+00:00 -0.004553 -0.004553 1.026470
2023-04-07 00:00:00+00:00 -0.004249 -0.004249 1.022108
2023-04-08 00:00:00+00:00 0.000999 0.000999 1.023129
2023-04-09 00:00:00+00:00 0.013660 0.013660 1.037105
2023-04-10 00:00:00+00:00 0.046553 0.046553 1.085386
2023-04-11 00:00:00+00:00 0.019531 0.019531 1.106584
In [19]:
def plot_results(df):
plt.figure(figsize=(10, 6))
plt.plot(df['price_close'], label='BTC/USDC Price')
plt.plot(df['fast_sma'], label=f'{fast_window}-Day SMA', linestyle='--')
plt.plot(df['slow_sma'], label=f'{slow_window}-Day SMA', linestyle='--')
plt.title('BTC/USDC Price and SMA Strategy')
plt.xlabel('Date')
plt.ylabel('Price (USDC)')
plt.legend()
plt.show()
plt.figure(figsize=(10, 6))
plt.plot(df['cumulative_returns'], label='Cumulative Returns')
plt.title('Strategy Cumulative Returns')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.show()
In [20]:
plot_results(df)
What about AI¶
Can we apply AI to the problem?
So the input and output can stay the same, while we use deep learning to find some signals
- Input: BTC/USDC trading pair
- Output: Buy/Sell Signal
- Algo: A supervised learning CNN networks
Note:
- trade once per day
In [23]:
print(input_data.head())
time_period_end \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-13T00:00:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-14T00:00:00.0000000Z
2023-03-14 00:00:00+00:00 2023-03-15T00:00:00.0000000Z
2023-03-15 00:00:00+00:00 2023-03-16T00:00:00.0000000Z
2023-03-16 00:00:00+00:00 2023-03-17T00:00:00.0000000Z
time_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T06:30:00.0000000Z
2023-03-13 00:00:00+00:00 2023-03-13T00:00:00.0320000Z
2023-03-14 00:00:00+00:00 2023-03-14T00:00:06.3330000Z
2023-03-15 00:00:00+00:00 2023-03-15T00:00:04.9890000Z
2023-03-16 00:00:00+00:00 2023-03-16T00:00:00.2020000Z
time_close price_open \
time_period_start
2023-03-12 00:00:00+00:00 2023-03-12T23:59:59.6710000Z 20632.41
2023-03-13 00:00:00+00:00 2023-03-13T23:59:42.8610000Z 22333.49
2023-03-14 00:00:00+00:00 2023-03-14T23:59:03.5060000Z 24242.34
2023-03-15 00:00:00+00:00 2023-03-15T23:59:55.1770000Z 24768.91
2023-03-16 00:00:00+00:00 2023-03-16T23:59:53.3150000Z 24374.81
price_high price_low price_close volume_traded \
time_period_start
2023-03-12 00:00:00+00:00 50000.00 20632.41 22333.49 4318.34950
2023-03-13 00:00:00+00:00 24714.04 21801.00 24241.32 1805.95550
2023-03-14 00:00:00+00:00 26517.33 24104.27 24786.18 1857.43532
2023-03-15 00:00:00+00:00 25298.33 23950.00 24374.81 803.24485
2023-03-16 00:00:00+00:00 25230.04 24205.71 25063.01 1371.40674
trades_count fast_sma slow_sma position \
time_period_start
2023-03-12 00:00:00+00:00 130167 22333.490000 22333.490000 0.0
2023-03-13 00:00:00+00:00 57919 23287.405000 23287.405000 0.0
2023-03-14 00:00:00+00:00 71238 23786.996667 23786.996667 0.0
2023-03-15 00:00:00+00:00 43019 23933.950000 23933.950000 0.0
2023-03-16 00:00:00+00:00 46140 24159.762000 24159.762000 0.0
returns strategy_returns cumulative_returns
time_period_start
2023-03-12 00:00:00+00:00 NaN NaN NaN
2023-03-13 00:00:00+00:00 0.085425 0.0 1.0
2023-03-14 00:00:00+00:00 0.022476 0.0 1.0
2023-03-15 00:00:00+00:00 -0.016597 -0.0 1.0
2023-03-16 00:00:00+00:00 0.028234 0.0 1.0
In [53]:
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
# Define the CNN model
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv1d(in_channels=3, out_channels=16, kernel_size=3)
self.relu = nn.ReLU()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(16 * 3, 16) # Adjust based on sequence length
self.fc2 = nn.Linear(16, 2) # Output layer with 2 neurons for BTC and USDC
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.flatten(x)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return nn.functional.softmax(x, dim=1) # Softmax activation to get portfolio weights
# Preprocess the data
def preprocess_data(df):
df['time_period_start'] = pd.to_datetime(df['time_period_start'])
df.set_index('time_period_start', inplace=True)
df = df[['price_close', 'price_high', 'price_low']].astype(float)
# Normalize prices by the last closing price
last_close = df['price_close'].iloc[-1]
df['price_close'] /= last_close
df['price_high'] /= last_close
df['price_low'] /= last_close
return df
# Convert the DataFrame to sequences suitable for the model
def create_sequences(df, seq_length):
sequences = []
if len(df) < seq_length:
print("Not enough data to create sequences. Reduce the sequence length or get more data.")
return np.array(sequences) # Return an empty array if not enough data
for i in range(len(df) - seq_length):
seq = df.iloc[i:i+seq_length].values.T # Transpose for PyTorch (channels, sequence length)
sequences.append(seq)
return np.array(sequences)
In [51]:
# Function to generate weights for each step using the trained model
def generate_weights_for_each_step(df, model, seq_length):
btc_weights = []
usdc_weights = []
# Iterate over the data using a sliding window
for i in range(seq_length, len(df)):
# Create the input tensor for the current window
current_sequence = torch.tensor(df[['price_high', 'price_low', 'price_close']].iloc[i-seq_length:i].values.T, dtype=torch.float32).unsqueeze(0) # Shape: (1, 3, seq_length)
# Get the predicted weights
btc_weight, usdc_weight = generate_signal(current_sequence)
btc_weights.append(btc_weight)
usdc_weights.append(usdc_weight)
# Create a DataFrame to store the weights with the corresponding dates
weights_df = pd.DataFrame({
'btc_weight': btc_weights,
'usdc_weight': usdc_weights
}, index=df.index[seq_length:])
return weights_df
# Function to generate the portfolio weights using the model
def generate_signal(current_price_tensor):
model.eval()
with torch.no_grad():
predicted_weights = model(current_price_tensor).squeeze(0).numpy()
btc_weight = predicted_weights[0]
usdc_weight = predicted_weights[1]
return btc_weight, usdc_weight
In [54]:
input_data = get_historical_data(symbol, start_date, end_date)
df = preprocess_data(input_data)
print(df.head())
# Create sequences for the model
seq_length = 5 # Number of periods for each sequence
sequences = create_sequences(df, seq_length)
# Convert sequences to PyTorch tensors
X_train = torch.tensor(sequences, dtype=torch.float32)
# For simplicity, let's create random target weights as an example
y_train = torch.rand((X_train.shape[0], 2), dtype=torch.float32) # Random weights for BTC and USDC
# Instantiate the model, loss function, and optimizer
model = SimpleCNN()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Training loop
epochs = 20
for epoch in range(epochs):
model.train()
optimizer.zero_grad()
output = model(X_train)
loss = criterion(output, y_train)
loss.backward()
optimizer.step()
print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}")
# Generate portfolio weights for each time step
weights_df = generate_weights_for_each_step(df, model, seq_length)
# Print the weights for verification
print(weights_df.head())
price_close price_high price_low
time_period_start
2023-03-12 00:00:00+00:00 0.738624 1.653625 0.682365
2023-03-13 00:00:00+00:00 0.801721 0.817355 0.721013
2023-03-14 00:00:00+00:00 0.819741 0.876994 0.797188
2023-03-15 00:00:00+00:00 0.806136 0.836679 0.792086
2023-03-16 00:00:00+00:00 0.828896 0.834420 0.800543
Epoch [1/20], Loss: 0.0844
Epoch [2/20], Loss: 0.0842
Epoch [3/20], Loss: 0.0841
Epoch [4/20], Loss: 0.0839
Epoch [5/20], Loss: 0.0838
Epoch [6/20], Loss: 0.0837
Epoch [7/20], Loss: 0.0836
Epoch [8/20], Loss: 0.0835
Epoch [9/20], Loss: 0.0834
Epoch [10/20], Loss: 0.0834
Epoch [11/20], Loss: 0.0834
Epoch [12/20], Loss: 0.0834
Epoch [13/20], Loss: 0.0834
Epoch [14/20], Loss: 0.0834
Epoch [15/20], Loss: 0.0834
Epoch [16/20], Loss: 0.0834
Epoch [17/20], Loss: 0.0834
Epoch [18/20], Loss: 0.0833
Epoch [19/20], Loss: 0.0833
Epoch [20/20], Loss: 0.0833
btc_weight usdc_weight
time_period_start
2023-03-17 00:00:00+00:00 0.523079 0.476921
2023-03-18 00:00:00+00:00 0.523683 0.476317
2023-03-19 00:00:00+00:00 0.522301 0.477699
2023-03-20 00:00:00+00:00 0.523792 0.476208
2023-03-21 00:00:00+00:00 0.523353 0.476647
In [55]:
# Function to calculate portfolio returns based on model predictions
def calculate_returns(df, model, seq_length):
btc_weights = []
usdc_weights = []
for i in range(seq_length, len(df)):
current_sequence = torch.tensor(df.iloc[i-seq_length:i].values.T, dtype=torch.float32).unsqueeze(0) # Shape: (1, 3, seq_length)
btc_weight, usdc_weight = generate_signal(current_sequence)
btc_weights.append(btc_weight)
usdc_weights.append(usdc_weight)
# Convert weights to a DataFrame
weights_df = pd.DataFrame({'btc_weight': btc_weights, 'usdc_weight': usdc_weights}, index=df.index[seq_length:])
# Calculate daily returns based on BTC weights
df['returns'] = df['price_close'].pct_change()
weights_df['strategy_returns'] = weights_df['btc_weight'].shift(1) * df['returns'].iloc[seq_length:]
# Initialize cumulative returns starting at 1
weights_df['cumulative_returns'] = (1 + weights_df['strategy_returns']).cumprod()
weights_df['cumulative_returns'].iloc[0] = 1 # Set the first value to 1 explicitly
return weights_df
# Plotting function
def plot_strategy_results(df, weights_df):
plt.figure(figsize=(10, 6))
plt.plot(df['price_close'], label='BTC/USDC Price')
plt.title('BTC/USDC Price')
plt.xlabel('Date')
plt.ylabel('Price (USDC)')
plt.legend()
plt.show()
plt.figure(figsize=(10, 6))
plt.plot(weights_df['cumulative_returns'], label='Strategy Cumulative Returns')
plt.title('Strategy Cumulative Returns')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.show()
# Calculate the returns and cumulative returns using the trained model
weights_df = calculate_returns(df, model, seq_length)
# Plot the results
plot_strategy_results(df, weights_df)
<ipython-input-55-1de3d449d5ec>:21: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0! You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy. A typical example is when you are setting values in a column of a DataFrame, like: df["col"][row_indexer] = value Use `df.loc[row_indexer, "col"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`. See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy weights_df['cumulative_returns'].iloc[0] = 1 # Set the first value to 1 explicitly <ipython-input-55-1de3d449d5ec>:21: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy weights_df['cumulative_returns'].iloc[0] = 1 # Set the first value to 1 explicitly
Risk Management¶
In [56]:
def calculate_performance_metrics(weights_df):
# Assuming daily returns are already calculated in 'strategy_returns'
returns = weights_df['strategy_returns'].dropna()
# Sharpe Ratio Calculation
risk_free_rate = 0.0 # Assuming a risk-free rate of 0 for simplicity
sharpe_ratio = (returns.mean() - risk_free_rate) / returns.std()
# Sortino Ratio Calculation
downside_returns = returns[returns < 0]
sortino_ratio = (returns.mean() - risk_free_rate) / downside_returns.std()
# Max Drawdown Calculation
cumulative_returns = (1 + returns).cumprod()
peak = cumulative_returns.cummax()
drawdown = (cumulative_returns - peak) / peak
max_drawdown = drawdown.min()
return sharpe_ratio, sortino_ratio, max_drawdown
# Calculate the metrics
sharpe_ratio, sortino_ratio, max_drawdown = calculate_performance_metrics(weights_df)
# Print the results
print(f"Sharpe Ratio: {sharpe_ratio:.4f}")
print(f"Sortino Ratio: {sortino_ratio:.4f}")
print(f"Max Drawdown: {max_drawdown:.4%}")
Sharpe Ratio: 0.1889 Sortino Ratio: 0.3585 Max Drawdown: -2.2170%
In [ ]:
