Start with writing something¶

  • Input: BTC/USDC trading pair
  • Output: Buy/Sell Signal
  • Algo: Simple Moving Average (SMA)

Note:

  • trade once per day
  • use close price to calculate ma
  • fast-sma > slow-sma = buy btc
  • fast-sma < slow-sma = sell btc

Demo photo for moving average¶

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)
No description has been provided for this image
No description has been provided for this image

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
No description has been provided for this image
No description has been provided for this image

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