Используйте Python и chatGPT для создания инновационных торговых стратегий
Мы хотим использовать машинное обучение для извлечения информации о будущем движении цены Биткойна из данных о финансировании и различных данных, основанных на объемах, и разработать прибыльную торговую стратегию.
Для этого мы будем использовать Python, tensorflow и chatGPT. Код доступен на моем github.
Начнем с импорта всех соответствующих модулей.
import pandas as pd import matplotlib.pyplot as plt import plotly.graph_objects as go import plotly.io as pio import numpy as np from plotly.subplots import make_subplots from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense
Мы импортируем данные о цене, объеме и финансировании из CSV-файла и в дополнение к этому вычисляем дельту объема и процентную доходность.
df = pd.read_csv('merged_df.csv') def _compute_vd_helper(volume: float, taker_buy_volume: float) -> float: vd = 2*taker_buy_volume - volume return vd df['volume_delta_base_asset'] = df.apply(lambda x: _compute_vd_helper(x.volume, x.taker_buy_base_asset_volume), axis=1) df['returns'] = (df.close - df.open)/df.open df['algo_funding'] = 100 * df['fundingRate'] df['gain'] = pd.Series([1 if val > 0 else 0 for val in df.returns])
Мы подготавливаем наборы данных и нормализуем признаки. Для этой цели мы выбираем несколько наборов данных на основе объема, данных о ставке финансирования и цене в качестве нашей матрицы признаков и сохраняем их во фрейме данных с именем X.Наша целевая переменная равна 1, если текущий период времени дал положительный результат и 0 в противном случае.Мы применяем к нашим данным разделение обучения/тестирования 50/50.Этот код и код в следующем абзаце были адаптированы из chatGPT сгенерированный код с подсказкой:
"Как эта модель дерева решений будет выглядеть как модель lstm?
[код]”
Код метода дерева решений в подсказке был показан в предыдущей статье, и ему также помогло использование chatGPT.
# Set the percentage of training data train_data_percentage = 0.5 # Prepare your feature matrix and target variable X = df[['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume', 'number of trades', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'fundingRate', 'volume_delta_base_asset', 'algo_funding']].shift(periods=-1) X = X.drop(X.index[-1]) X = X.drop(X.index[0]) X = X.values # X = df[['volume', 'algo_funding', 'volume_delta_base_asset']].values y = df['gain'] y = y.drop(y.index[-1]) y = y.drop(y.index[0]) y = y.values # Normalize the features X = (X - X.mean()) / X.std() # Split the data into training and testing sets # Calculate the number of samples for training based on the percentage num_train_samples = int(train_data_percentage * len(X)) # Split the data into training and testing sets X_train = X[:num_train_samples] X_test = X[num_train_samples:] y_train = y[:num_train_samples] y_test = y[num_train_samples:] # Reshape the input data to match LSTM input shape (samples, timesteps, features) X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1]) X_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])
Подготавливаем модель со слоями и т.д.
Мы используем библиотеку tensorflow для применения метода машинного обучения с долговременной кратковременной памятью (LSTM).
# Build the LSTM model model = Sequential() model.add(LSTM(32, input_shape=(1, X_train.shape[2]))) # 32 is the number of LSTM units model.add(Dense(64, activation='relu')) # Additional dense layer model.add(Dense(128, activation='relu')) # Additional dense layer model.add(Dense(256, activation='relu')) # Additional dense layer model.add(Dense(512, activation='relu')) # Additional dense layer model.add(Dense(1024, activation='relu')) # Additional dense layer model.add(Dense(512, activation='relu')) # Additional dense layer model.add(Dense(256, activation='relu')) # Additional dense layer model.add(Dense(128, activation='relu')) # Additional dense layer model.add(Dense(64, activation='relu')) # Additional dense layer model.add(Dense(1, activation='sigmoid')) # Compile the model model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) # Train the model model.fit(X_train, y_train, epochs=100, batch_size=32) # Make predictions on the test data y_pred = model.predict(X_test) # Convert the probabilities to class labels y_pred_classes = np.round(y_pred).flatten() # Compare the predicted classes with the true labels accuracy = np.mean(y_pred_classes == y_test) print("Test Accuracy:", accuracy) # Save the trained model model.save('lstm_model.h5')
Мы добавляем новый столбец в кадр данных, содержащий прогнозы модели LSTM. В этом случае столбец содержит значения 1 и 0, где 1 означает покупку, а 0 означает отсутствие покупки на текущей свече. Мы предполагаем, что будем держать позицию ровно одну свечу, поэтому доход по одной сделке будет равен цене открытия минус цена закрытия свечи, на которой возникает сигнал. Мы отображаем данные ohlc на графике свечей с помощью plotly и обозначаем сигналы покупки синими стрелками на графике.
df = df[-len(X_test):] df = df.reset_index(drop=True) # create subplots with two y-axes fig = make_subplots(specs=[[{"secondary_y": True}]]) df['weak_buy'] = y_pred_classes # df.apply(weak_buy, axis=1).shift(1) fig.add_trace(go.Candlestick( x=pd.to_datetime(df['open time'], unit='ms'), open=df.open, high=df.high, low=df.low, close=df.close, increasing=dict(line=dict(color='green')), decreasing=dict(line=dict(color='red')), name='Price') ) fig.add_trace(go.Scatter( x=pd.to_datetime(df['open time'][df.weak_buy > 0], unit='ms'), y=-3000+df.low[df.weak_buy > 0], name='weak buy', mode='markers', marker=dict( symbol='triangle-up', size=10, color='blue', line=dict(width=1, color='blue'), ) )) pio.write_image(fig, 'trade_entries_chart.jpeg', format='png') pyo.plot(fig, filename='plot.html', auto_open=True)
Мы вычисляем кривую капитала нашей стратегии, суммируя доходность всех свечей, где наш алгоритм дал сигнал на покупку. Этот код был адаптирован из сгенерированного кода chatGPT с подсказкой:
«Если у меня есть фрейм данных со столбцом, содержащим сигналы покупки для торговой стратегии, где 1 означает покупку, а 0 означает ничего не делать, а второй столбец содержит процентную доходность за этот период. Как я могу рассчитать кривую капитала этой торговой стратегии в третьем столбце».
# Create a new column for the equity curve df['equity_curve'] = 1.0 # Initial value of 1.0 # Iterate through the DataFrame rows for i in range(1, len(df)): # Compute equity curve based on buy signals and percentage returns if df.weak_buy.iloc[i] == 1: df.equity_curve.at[i] = df.equity_curve.iloc[i-1] * (1 + df.returns.iloc[i]) else: df.equity_curve.at[i] = df.equity_curve.iloc[i-1] # Create a larger figure plt.figure(figsize=(18, 7)) # Set the width to 8 inches and height to 6 inches plt.grid(True) plt.plot(pd.to_datetime(df['open time'], unit='ms'), df.equity_curve*df.close.iloc[0], linewidth=2.5) plt.plot(pd.to_datetime(df['open time'], unit='ms'), df.close, linewidth=2.5) plt.savefig('equity_curve_lstm.png')
Стратегия вернула бы 42% за указанный период времени тестовых данных. Мы сравниваем доходность нашей модели по сравнению с простой стратегией «купи и держи».
Чтобы получить лучшее сравнение между нашей стратегией с помощью машинного обучения и простой стратегией «купи и держи», мы можем вычислить и сравнить показатели эффективности стратегии «купи и держи».
Buy and Hold Mean: 0.02% Standard Deviation: 3.27% Max Drawdown: -76.70% Sharpe Ratio: 0.71 Sortino Ratio: 1.01 Omega Ratio: 1.02
с соответствующими показателями модели LSTM,
LSTM Model Mean: 0.09% Standard Deviation: 2.69% Max Drawdown: -52.20% Sharpe Ratio: 3.07 Sortino Ratio: 4.63 Omega Ratio: 1.10
Хотя максимальная просадка более -52% может показаться большой, это вовсе не редкость на криптовалютных рынках и все же значительно меньше -76,7%, понесенных стратегией «купи и держи».
Коэффициенты Шарпа и Сортино с 3,07 и 4,63, несомненно, выдающиеся, а также значительно лучше, чем коэффициенты 0,71 и 1,01 стратегии «купи и держи».
Поскольку модель не является детерминированной, обучение модели заново с помощью предоставленного кода приведет к другому результату. Поэтому вы можете найти точную модель из этой статьи на моем гитхабе вместе с кодом. Чтобы загрузить модель, вы можете использовать этот фрагмент кода:
from tensorflow.keras.models import load_model # Load the saved model loaded_model = load_model('lstm_model.h5') # Use the loaded model for prediction or evaluation predictions = loaded_model.predict(X_test)
Не забудьте получить код с моего github и удачной торговли.
Если вам нравится читать мои истории и вы хотите поддержать меня, зарегистрируйтесь, чтобы стать Medium Member. Это 5 долларов в месяц, что дает вам неограниченный доступ к тысячам статей только для членов о Python, науке о данных, искусственном интеллекте, машинном обучении, торговле, криптографии и многом другом. Если вы зарегистрируетесь по моей ссылке, я получу небольшую комиссию без каких-либо дополнительных затрат для вас.