| 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.978 Tracking Error 0.275 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import *
class PriceActionAlpha(AlphaModel):
def __init__(self, algorithm, symbol):
self.algorithm = algorithm
self.btc = symbol
self.hour = -1
self.selltrig = None
self.buytrig = None
self.currentopen = None
self.consolidator = TradeBarConsolidator(timedelta(1))
self.consolidator.DataConsolidated += self.OnConsolidated
self.window = RollingWindow[TradeBar](4)
history = algorithm.History[TradeBar](self.btc, 4*24*60, Resolution.Minute)
for bar in history:
self.consolidator.Update(bar)
algorithm.SubscriptionManager.AddConsolidator(self.btc, self.consolidator)
def OnConsolidated(self, sender, bar):
self.window.Add(bar)
self.currentopen = bar.Open
if not self.window.IsReady: return
df = self.algorithm.PandasConverter.GetDataFrame[TradeBar](self.window)
k1 = 0.5
k2 = 0.5
HH, HC, LC, LL = max(df['high']), max(df['close']), min(df['close']), min(df['low'])
if (HH - LC) >= (HC - LL):
signalrange = HH - LC
else:
signalrange = HC - LL
self.selltrig = self.currentopen - k2 * signalrange
self.buytrig = self.currentopen + k1 * signalrange
def Update(self, algorithm, data):
# We only use hourly signals
if not data.ContainsKey(self.btc) or not self.window.IsReady:
return []
if self.hour == algorithm.Time.hour:
return []
self.hour = algorithm.Time.hour
price = data[self.btc].Price
if algorithm.LiveMode:
algorithm.Log(f'Buy Trigger {self.buytrig} > Price {price} > {self.selltrig}')
if price >= self.buytrig:
return [Insight(self.btc, timedelta(days=365), InsightType.Price, InsightDirection.Up)]
elif price < self.selltrig:
algorithm.Insights.Cancel([self.btc])
return []from AlgorithmImports import *
from alpha import PriceActionAlpha
# BTCUSD Long Only Dual Thrust Algorithm
# Originated by Michael Vitucci
class DualThrustAlgorithm(QCAlgorithm):
def UniverseSelectionFilter(self, crypto_coarse: List[CryptoCoarseFundamental]) -> List[Symbol]:
for cf in crypto_coarse: print(cf)
pool=[cf.Symbol for cf in crypto_coarse if str(cf.Symbol).endswith('BUSD') and cf.Volume >= 100 and cf.VolumeInUsd > 10000 ]
return pool
def Initialize(self):
self.SetStartDate(2023, 1, 1)
self.SetEndDate(2023, 10, 1)
self.SetCash(10000)
self.SetBrokerageModel(BrokerageName.Binance, AccountType.Cash)
self.AddUniverse(CryptoCoarseFundamentalUniverse(Market.Binance, self.UniverseSettings, self.UniverseSelectionFilter))
def OnData(self, data):
if not self.Portfolio.Invested:
for symbol in self.ActiveSecurities.Keys:
print(symbol)
self.SetHoldings(symbol, 1 / len(self.ActiveSecurities.Keys))
def FineSelectionFunction(self, fine):
# Calculate the 5-day momentum
momentum = {}
for i in fine:
history = self.History([i.Symbol], timedelta(days=5), Resolution.Daily)
if not history.empty:
close = history.loc[str(i.Symbol)]['close']
i.momentum = (close[0]-close[-1])/close[-1]
momentum[i.Symbol] = i.momentum
# Sort by momentum and take the top 10
sorted_by_momentum = sorted(momentum.items(), key=lambda x: x[1], reverse=True)
self.long = [i[0] for i in sorted_by_momentum[:10]]
return self.long