| Overall Statistics |
|
Total Trades 692 Average Win 6.61% Average Loss -4.88% Compounding Annual Return 82.279% Drawdown 62.700% Expectancy 0.363 Net Profit 9080.716% Sharpe Ratio 1.484 Probabilistic Sharpe Ratio 67.452% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.35 Alpha 0.65 Beta 0.279 Annual Standard Deviation 0.457 Annual Variance 0.209 Information Ratio 1.235 Tracking Error 0.468 Treynor Ratio 2.433 Total Fees $0.00 Estimated Strategy Capacity $7900000.00 Lowest Capacity Asset BTCUSD XJ Portfolio Turnover 23.67% |
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data.Market import TradeBar
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn import svm
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn import metrics
import pandas as pd
import numpy as np
from datetime import datetime
from QuantConnect.Indicators import RelativeStrengthIndex, MovingAverageConvergenceDivergence, BollingerBands
class CryptoPredictionAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2016, 1, 1)
self.SetCash(100000)
self.crypto = self.AddCrypto("BTCUSD", Resolution.Daily).Symbol
self.lookback = 30
self.Schedule.On(self.DateRules.EveryDay(self.crypto), self.TimeRules.At(0, 0), self.TrainModels)
self.models = []
self.scalers = []
self.slice = None
# Debugging elements
self.Debug("Algorithm initialized")
self.Debug("Symbol: " + str(self.crypto))
self.Debug("Lookback period: " + str(self.lookback) + " days")
self.rsi = RelativeStrengthIndex(14)
self.macd = MovingAverageConvergenceDivergence(12, 26, 9)
self.bb = BollingerBands(20, 2)
def TrainModels(self):
# Get historical data
history = self.History(self.crypto, self.lookback, Resolution.Daily)
# Ensure we have enough data
if len(history) < self.lookback:
self.Debug("Not enough data to train models")
return
# Debugging element
self.Debug("Training models")
# Create dataframe and calculate features
df = history.loc[self.crypto].copy()
df['Return'] = df['close'].pct_change()
df.dropna(inplace=True)
# Insert your feature calculation here
for i in range(len(df)):
end_time = df.index[i]
price = df.loc[end_time, "close"]
self.rsi.Update(end_time, price)
self.macd.Update(end_time, price)
self.bb.Update(end_time, price)
df.loc[end_time, 'RSI'] = self.rsi.Current.Value
df.loc[end_time, 'MACD'] = self.macd.Current.Value
df.loc[end_time, 'BB_Upper'] = self.bb.UpperBand.Current.Value
df.loc[end_time, 'BB_Middle'] = self.bb.MiddleBand.Current.Value
df.loc[end_time, 'BB_Lower'] = self.bb.LowerBand.Current.Value
df.dropna(inplace=True)
# Create models and scalers
self.models = []
self.scalers = []
# Train models and scalers
for model in [KNeighborsClassifier(n_neighbors=3), svm.SVC(kernel='poly'), RandomForestClassifier(n_estimators=150), GradientBoostingClassifier(n_estimators=150)]:
scaler = preprocessing.StandardScaler()
features = scaler.fit_transform(df[['RSI', 'MACD', 'BB_Upper', 'BB_Middle', 'BB_Lower']])
model.fit(features, np.sign(df['Return']))
self.models.append(model)
self.scalers.append(scaler)
# Debugging element
self.Debug("Models trained")
def OnData(self, data):
self.slice = data
if not self.models or not self.slice.ContainsKey(self.crypto):
return
# Update the indicators with the latest price
price = self.slice[self.crypto].Close
self.rsi.Update(self.Time, price)
self.macd.Update(self.Time, price)
self.bb.Update(self.Time, price)
# Create a DataFrame for the latest data
df = pd.DataFrame({
'RSI': [self.rsi.Current.Value],
'MACD': [self.macd.Current.Value],
'BB_Upper': [self.bb.UpperBand.Current.Value],
'BB_Middle': [self.bb.MiddleBand.Current.Value],
'BB_Lower': [self.bb.LowerBand.Current.Value]
})
# Use each model to make a prediction
predictions = []
for model, scaler in zip(self.models, self.scalers):
features_scaled = scaler.transform(df)
prediction = model.predict(features_scaled)
predictions.append(prediction)
# Decide whether to buy or sell based on the predictions
if all(prediction == 1 for prediction in predictions):
self.SetHoldings(self.crypto, 1.0)
elif all(prediction == -1 for prediction in predictions):
self.Liquidate(self.crypto)
# Debugging element
self.Debug("Prediction: " + str(predictions))