| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
#region imports from AlgorithmImports import * #endregion # Your New Python File
#region imports
from AlgorithmImports import *
#endregion
# Totally degenerate strategy which uses moving averages to trade momentum
class MaMomentumAlphaModel(AlphaModel):
def __init__(self,
resolution = Resolution.Daily):
self.resolution = resolution;
self.symbolDataBySymbol = {}
self.allowed_tickers = ["BTCUSD"]
def Update(self, algorithm: QCAlgorithm, data: Slice) -> List[Insight]:
insights = []
for symbol, symbolData in self.symbolDataBySymbol.items():
if symbol.Value in self.allowed_tickers and symbolData.CheckReady():
long_signal_count = 0;
for selected_sma in symbolData.SmaList:
if data[symbol] > selected_sma:
long_signal_count += 1;
if long_signal_count > 0:
insights.append(Insight.Price(symbolData.Symbol, timedelta(days=1), InsightDirection.Up, confidence=long_signal_count))
return insights;
def OnSecuritiesChanged(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for added in changes.AddedSecurities:
symbolData = self.symbolDataBySymbol.get(added.Symbol)
if symbolData is None:
symbolData = SymbolData(added, algorithm, self.resolution)
self.symbolDataBySymbol[added.Symbol] = symbolData
else:
# a security that was already initialized was re-added, reset the indicators
symbolData.ResetAll()
for removed in changes.RemovedSecurities:
data = self.symbolDataBySymbol.pop(removed.Symbol, None)
if data is not None:
# clean up our consolidators
data.RemoveConsolidators()
class SymbolData:
'''Contains data specific to a symbol required by this model'''
def __init__(self, security, algorithm, resolution):
self.Security = security
self.Symbol = security.Symbol
self.algorithm = algorithm
self.SmaList = []
self.AllConsolidators = []
period_list = [1, 2, 4, 10, 20];
for period in period_list:
self.AllConsolidators.append(algorithm.ResolveConsolidator(security.Symbol, resolution))
for selected_consolidator in self.AllConsolidators:
algorithm.SubscriptionManager.AddConsolidator(security.Symbol, selected_consolidator)
for period in period_list:
self.SmaList.append(SimpleMovingAverage(security.Symbol, period))
for selected_sma, selected_consolidator in zip(self.SmaList, self.AllConsolidators):
algorithm.RegisterIndicator(security.Symbol, selected_sma, selected_consolidator);
for selected_sma in self.SmaList:
algorithm.WarmUpIndicator(security.Symbol, selected_sma, resolution);
#self.LongSignalCount = 0;
def RemoveConsolidators(self):
for selected_consolidator in self.AllConsolidators:
self.algorithm.SubscriptionManager.RemoveConsolidator(self.Security.Symbol, selected_consolidator)
def ResetAll(self):
for selected_sma in self.SmaList:
selected_sma.Reset();
def CheckReady(self):
for selected_sma in self.SmaList:
if not selected_sma.IsReady:
return False;
return True;
#region imports
from AlgorithmImports import *
import numpy as np
import pandas as pd
from datetime import timedelta
#endregion
# Buy and HODL for last 3 days of the month
class TurnOfMonthAlphaModel(AlphaModel):
def __init__(self,
resolution = Resolution.Daily):
self.securities = []
self.resolution = resolution;
self.allowed_tickers = ["BTCUSD"]
month_list = [];
for year in ["2018", "2019", "2020","2021","2022","2023","2024"]:
for i in range(12):
if i >= 9:
month_list.append(f"{year}{i+1}")
else:
month_list.append(f"{year}0{i+1}")
df_eom = pd.DataFrame({'Date': month_list})
df_eom['EndOfMonth'] = pd.to_datetime(df_eom['Date'], format="%Y%m") + pd.tseries.offsets.MonthEnd(0)
self.date_store = df_eom.EndOfMonth.dt.date.tolist()
def Update(self, algorithm: QCAlgorithm, data: Slice) -> List[Insight]:
insights = []
if algorithm.Time.date() + timedelta(days=3) in self.date_store:
for security in self.securities:
# security price could be zero until we get the first data point. e.g. this could happen
# when adding both forex and equities, we will first get a forex data point
if security.Price != 0 and security.Symbol.Value in self.allowed_tickers:
insights.append(Insight(security.Symbol, timedelta(days=3), InsightType.Price, InsightDirection.Up))
elif algorithm.Time.date() + timedelta(days=2) in self.date_store:
for security in self.securities:
# security price could be zero until we get the first data point. e.g. this could happen
# when adding both forex and equities, we will first get a forex data point
if security.Price != 0 and security.Symbol.Value in self.allowed_tickers:
insights.append(Insight(security.Symbol, timedelta(days=2), InsightType.Price, InsightDirection.Up))
elif algorithm.Time.date() + timedelta(days=1) in self.date_store:
for security in self.securities:
# security price could be zero until we get the first data point. e.g. this could happen
# when adding both forex and equities, we will first get a forex data point
if security.Price != 0 and security.Symbol.Value in self.allowed_tickers:
insights.append(Insight(security.Symbol, timedelta(days=1), InsightType.Price, InsightDirection.Up))
elif algorithm.Time.date() in self.date_store:
for security in self.securities:
# security price could be zero until we get the first data point. e.g. this could happen
# when adding both forex and equities, we will first get a forex data point
if security.Price != 0 and security.Symbol.Value in self.allowed_tickers:
insights.append(Insight(security.Symbol, timedelta(days=1), InsightType.Price, InsightDirection.Flat))
return insights
def OnSecuritiesChanged(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for added in changes.AddedSecurities:
self.securities.append(added)
for removed in changes.RemovedSecurities:
if removed in self.securities:
self.securities.remove(removed)
# region imports
from AlgorithmImports import *
from MeatLayers.TurnOfMonthAlphaModel import TurnOfMonthAlphaModel;
from MeatLayers.MaMomentumAlphaModel import MaMomentumAlphaModel;
# endregion
class MeatMonster(QCAlgorithmFramework):
def Initialize(self):
self.SetStartDate(2020, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
tickers = ['BTCUSD', 'ETHUSD', 'ETCUSD', 'XMRUSD', 'ZECUSD', 'XRPUSD', 'LTCUSD']
for i in range(len(tickers)):
self.crypto = self.AddCrypto(tickers[i], Resolution.Daily, Market.Bitfinex)
self.crypto.SetLeverage(1)
self.crypto.SetFeeModel(CustomFeeModel())
self.crypto = self.crypto.Symbol
self.AddAlpha(MaMomentumAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(NullRiskManagementModel())
class CustomFeeModel(FeeModel):
def GetOrderFee(self, parameters):
fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.0003
return OrderFee(CashAmount(fee, "USD"))