Overall Statistics |
Total Trades 38 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 $603.56 Estimated Strategy Capacity $29000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
import numpy as np import datetime class GeekyFluorescentPinkFalcon(QCAlgorithm): def Initialize(self): # set up self.SetStartDate(2020, 1, 1) self.SetEndDate(2020, 1, 2) self.SetCash(1000000) self.SetBenchmark("SPY") # data equity = self.AddEquity("SPY", Resolution.Minute) self.symbol = equity.Symbol self.Consolidate(self.symbol, timedelta(hours=4), self.FourHourBarHandler) self.Consolidate(self.symbol, Calendar.Weekly, self.WeeklyBarHandler) # parameters self.high_low_ratio = 1/2 self.high_open_ratio = 0.1 # init self.high_open_distance = False self.cond_1 = False self.cond_2 = False self.cond_retracement = False self.low_minute = 0 self.open_minute = 0 self.high_minute = 0 self.open_low_mean = None self.open_high_mean = None # mean of Open - High difference on 4H bar, window 100 self.rolling_high = RollingWindow[float](100) self.rolling_low = RollingWindow[float](100) self.rolling_open = RollingWindow[float](100) # warm up history = self.History([self.symbol], 100 * 5, Resolution.Hour) for index, row in history.loc[self.symbol].iterrows(): self.rolling_high.Add(row.high) self.rolling_low.Add(row.low) self.rolling_open.Add(row.open) self.SetWarmup(100 * 4 * 60) # 4H Bar def FourHourBarHandler(self, consolidated): # reset self.low_minute = 0 self.open_minute == 0 self.high_minute == 0 self.cond_retracement = False self.cond_2 = False self.cond_1 = False # add data to rolling windows self.rolling_high.Add(consolidated.High) self.rolling_low.Add(consolidated.Low) self.rolling_open.Add(consolidated.Open) # check if not self.rolling_high.IsReady: return if not self.rolling_low.IsReady: return if not self.rolling_open.IsReady: return # mean of high - open diff high_open = np.array(list(self.rolling_high)) - np.array(list(self.rolling_open )) self.open_high_mean = np.mean(high_open) # mean of open - low diff open_low = np.array(list(self.rolling_open)) - np.array(list(self.rolling_low)) self.open_low_mean = np.mean(open_low) # PROSJEK na 4H # self.high_open_distance = (consolidated.High - consolidated.Open) < (high_open_mean * self.high_low_ratio) MINUTNOJ # condition 1 # self.high_open_distance = (consolidated.High - consolidated.Open) < (high_open_mean * self.high_low_ratio) # self.cond_2 = (consolidated.Open - consolidated.Low) > open_low_mean # self.Debug(f"time {self.Time}, high_open_distance {self.high_open_distance}, cond_2 {self.cond_2}") def OnOrderEvent(self, orderEvent): order = self.Transactions.GetOrderById(orderEvent.OrderId) if order.Status == OrderStatus.Filled: if order.Type == OrderType.Limit or order.Type == OrderType.StopMarket: # or order.Type == OrderType.MarketOnOpen: self.Transactions.CancelOpenOrders(order.Symbol) def WeeklyBarHandler(self, consolidated): pass # self.Debug(f"{consolidated.EndTime},>> WeeklyBarHandler >> {consolidated.Close}") # Miutni barovi def OnData(self, data): # # time restriction # if self.Time.date < datetime.date(2020, 1, 1): # return # check for data if not data.Bars.ContainsKey(self.symbol): return if not data.ContainsKey(self.symbol): return if data[self.symbol] is None: return # check if self.open_low_mean is None: return # set open 4H self.Debug(f"Open: {self.open_minute}") if self.open_minute == 0: self.open_minute = data[self.symbol].Open self.Debug(f"Open2: {self.open_minute}") self.Debug(f"Close: {data[self.symbol].Close}") # set low 4H if self.low_minute == 0: self.low_minute = data[self.symbol].Low elif data[self.symbol].Low < self.low_minute: self.low_minute = data[self.symbol].Low # set high 4H if self.high_minute == 0: self.high_minute = data[self.symbol].High elif data[self.symbol].High > self.high_minute: self.high_minute = data[self.symbol].High # condition 1: High - Open < mean(High - Open) * 0.01 # self.cond_1 = self.high_minute - self.open_minute < (self.open_high_mean * self.high_open_ratio) # old way self.cond_1 = self.high_minute < self.rolling_high[0] # cond 2 if self.cond_2 == False: self.cond_2 = (self.open_minute - self.low_minute) > self.open_low_mean # # 4H # self.rolling_high # # 1M # data[self.symbol].High # data[self.symbol].Low # # 1M with 4H reset # self.low_minute # self.high_minute # retracement if self.cond_retracement == False and self.cond_1 and self.cond_2: self.cond_retracement = (data[self.symbol].High - self.low_minute) > (self.open_minute - self.low_minute) * 0.4 # if self.cond_retracement: # self.Debug("Retracement") # order if not self.Portfolio[self.symbol].Invested and not self.Portfolio[self.symbol].IsLong: # DEBUG self.Debug(f"time {self.Time}, high_minute: {self.high_minute}, open_minute: {self.open_minute}") quantity = self.CalculateOrderQuantity(self.symbol, 1) self.MarketOrder(self.symbol, -quantity, tag = "Buy!") self.LimitOrder(self.symbol, quantity, self.low_minute) # Profit take (PT, TP) self.StopMarketOrder(self.symbol, quantity, self.high_minute) # Stop loss (SL) # 3 uvjeta: # 1) High - Open < mean(High - Open) * 0.01 # 2) (Open - Low)_t > (Open - Low) * 3/4 # 3) retrace: High - Low > 0.4 * (open - low), High_t > (Open - Low)_t