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 [ ]: