Overall Statistics |
Total Trades 18 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 $18.00 Estimated Strategy Capacity $0 Lowest Capacity Asset AAPL.EODDATA 2S |
from asyncio import FastChildWatcher from AlgorithmImports import * import numpy as np from dateutil.parser import parse class FormalRedChicken(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 10, 11) # Set Start Date self.SetEndDate(2013, 10, 11) self.SetCash(10000) # Set Strategy Cash self.symbol = self.AddData(EODDATA, "AAPL", Resolution.Minute).Symbol self.sum_p = 0 self.sum_n = 0 self.tick_list_p = [] self.tick_seq_p = [] self.tick_list_n = [] self.tick_seq_n = [] self.ts_p = int(self.GetParameter("tick_size_p")) self.ts_n = int(self.GetParameter("tick_size_n")) self.window_size_p = int(self.GetParameter("window_size_p")) self.window_size_n = int(self.GetParameter("window_size_n")) self.next_positive_prob = float(self.GetParameter("positive_p")) self.next_negative_prob = float(self.GetParameter("negative_p")) #Reality Modeling self.interests = self.AddData(DFFData, "INT", Resolution.Daily).Symbol #Benchmark self.SetBenchmark(self.AddEquity("SPY").Symbol) #IB Fee model self.Securities[self.symbol].SetFeeModel(CustomFeeModel()) #Set slippage model self.Securities[self.symbol].SetSlippageModel(ConstantSlippageModel(0.0002)) #Set Leverage interest model self.Securities[self.symbol].MarginModel = BuyingPowerModel(2.0, 0.05) self.cash_rate = 0.005 self.leverage_rate = .0075 self.short_rate = 0.0025 self.leverage_costs = 0 self.cash_interests = 0 self.short_costs = 0 self.max_leverage = 2 self.qt_factor = 1.5 #Schedule events self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(0,0), self.Cash_Rebalance) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(20,0), self.Leverage_Rebalance) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(20,0), self.Short_Rebalance) self.debug = True def OnData(self, data): if not data.ContainsKey(self.symbol): return if self.debug: self.Debug(f"Last price: {data[self.symbol].Value}") self.Debug(f"Last qty: {data[self.symbol].GetProperty('Volume')}") self.tick_list_p.append(data[self.symbol].Value) self.sum_p = self.sum_p + data[self.symbol].GetProperty('Volume') self.tick_list_n.append(data[self.symbol].Value) self.sum_n = self.sum_n + data[self.symbol].GetProperty('Volume') if self.sum_p >= self.ts_p: self.sum_p = 0 if self.tick_list_p[0] < self.tick_list_p[-1]: self.tick_seq_p.append(1) else: self.tick_seq_p.append(-1) self.tick_list_p.clear() if self.debug: self.Debug('New Tick! (pos)') self.Debug('Tick seq ' + str(self.tick_seq_p)) self.Debug('Sum ' + str(sum(self.tick_seq_p[-(self.window_size_p):]))) total_leverage = float(self.Portfolio.TotalPortfolioValue) * self.max_leverage qt = (total_leverage * (float(self.qt_factor)/self.max_leverage)) / data[self.symbol].Value if self.next_positive_prob > 0.6: if not self.Portfolio.Invested: if sum(self.tick_seq_p[-(self.window_size_p):]) == self.window_size_p: self.MarketOrder(self.symbol, qt) if self.debug: self.Debug('Bought ' +str(qt)+ ' stocks at ' + str(data[self.symbol].Value)) else: if self.Portfolio[self.symbol].IsLong: if self.tick_seq_p[-1]==-1: self.Liquidate() if self.debug: self.Debug('Liqudated') if self.sum_n >= self.ts_n: self.sum_n = 0 if self.tick_list_n[0] < self.tick_list_n[-1]: self.tick_seq_n.append(1) else: self.tick_seq_n.append(-1) self.tick_list_n.clear() if self.debug: self.Debug('New Tick! (neg)') self.Debug('Tick seq ' + str(self.tick_seq_n)) self.Debug('Sum ' + str(sum(self.tick_seq_n[-(self.window_size_n):]))) total_leverage = float(self.Portfolio.TotalPortfolioValue) * self.max_leverage qt = (total_leverage * (float(self.qt_factor)/self.max_leverage)) / data[self.symbol].Value if self.next_negative_prob > 0.6: if not self.Portfolio.Invested: if sum(self.tick_seq_n[-(self.window_size_n):]) == -self.window_size_n: self.MarketOrder(self.symbol, -qt) if self.debug: self.Debug('Shorted ' +str(qt)+ ' stocks at ' + str(data[self.symbol].Value)) else: if self.Portfolio[self.symbol].IsShort: if self.tick_seq_n[-1]==1: self.SetHoldings(self.symbol, 0) if self.debug: self.Debug('Stoped short') def OnEndOfAlgorithm(self): self.ExitPositions() def ExitPositions(self): self.Liquidate() self.Debug('TRADING FEES: ' + str(self.Portfolio[self.symbol].TotalFees)) self.Debug('LEVERAGE COSTS: ' + str(self.leverage_costs)) self.Debug('CASH INTERESTS: ' + str(self.cash_interests)) self.Debug('SHORT COSTS: ' + str(self.short_costs)) def Cash_Rebalance(self): if not self.Portfolio.Invested: data = self.Securities[self.interests].GetLastData() if data: cash = self.Portfolio.Cash interest_rate = (data.Value / 100 - self.cash_rate)/360 if interest_rate < 0: return else: self.Portfolio.CashBook["USD"].AddAmount(cash * interest_rate) self.cash_interests += cash * interest_rate if self.debug: self.Debug('Interest '+str(interest_rate)) self.Debug("Cash int " + str(cash * interest_rate)) def Leverage_Rebalance(self): if self.Portfolio.Invested: data = self.Securities[self.interests].GetLastData() if data: cash = self.Portfolio.Cash interest_rate = (data.Value / 100 + self.leverage_rate)/360 self.Portfolio.CashBook["USD"].AddAmount(cash * interest_rate) self.leverage_costs += cash * interest_rate if self.debug: self.Debug('Interest '+str(interest_rate)) self.Debug("Leverage int " + str(cash * interest_rate)) def Short_Rebalance(self): if self.Portfolio[self.symbol].IsShort: Last_order = self.Transactions.LastOrderId mkt_value = self.Transactions.GetOrderTicket(Last_order).AverageFillPrice * self.Transactions.GetOrderTicket(Last_order).QuantityFilled interest = self.short_rate / 360 self.short_costs += mkt_value * interest self.Portfolio.CashBook["USD"].AddAmount(mkt_value * interest) if self.debug: self.Debug('Portfolio is short') self.Debug('Short Interest ' + str(mkt_value * interest)) class CustomFeeModel: def GetOrderFee(self, parameters): if parameters.Order.Quantity > 0: fee = min(max(1, parameters.Order.AbsoluteQuantity * 0.005), parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.01) elif parameters.Order.Tag == 'Liquidated': fee = min(max(1, parameters.Order.AbsoluteQuantity * 0.005), parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.01) elif parameters.Order.Quantity < 0: fee = min(max(1, parameters.Order.AbsoluteQuantity * 0.005), parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.01) else: fee = 0 return OrderFee(CashAmount(fee, 'USD')) class DFFData(PythonData): def GetSource(self, config, date, isLiveMode): source = "https://www.dropbox.com/s/n4beqe9zlcv0y4t/DFF.csv?dl=1" return SubscriptionDataSource( source, SubscriptionTransportMedium.RemoteFile) #rest for live data def Reader(self, config, line, date, isLiveMode): if not (line.strip() and line[0].isdigit()): return None data = line.split(',') coin = DFFData() coin.Symbol = config.Symbol coin.Time = parse(data[0]) coin.Value = float(data[1]) return coin class EODDATA(PythonData): def GetSource(self, config, date, isLiveMode): source = "https://www.dropbox.com/s/lasp3l4ppgx97f3/AAPL_1m_2004-01-01_2022-03-01.csv?dl=1" return SubscriptionDataSource( source, SubscriptionTransportMedium.RemoteFile) def Reader(self, config, line, date, isLiveMode): if not (line.strip() and line[0].isdigit()): return None data = line.split(',') coin = EODDATA() coin.Symbol = config.Symbol coin.Time = parse(data[0]) coin.Value = float(data[4]) coin["Volume"] = float(data[5]) return coin