Overall Statistics |
Total Trades 17 Average Win 1.89% Average Loss -1.15% Compounding Annual Return 3.878% Drawdown 23.200% Expectancy 0.978 Net Profit 4.998% Sharpe Ratio 0.257 Probabilistic Sharpe Ratio 15.398% Loss Rate 25% Win Rate 75% Profit-Loss Ratio 1.64 Alpha 0.009 Beta 0.267 Annual Standard Deviation 0.147 Annual Variance 0.022 Information Ratio -0.411 Tracking Error 0.17 Treynor Ratio 0.142 Total Fees $0.00 Estimated Strategy Capacity $1600000.00 Lowest Capacity Asset EOSUSD E3 |
#region imports from AlgorithmImports import * #endregion class TrailingStopLoss(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) self.SetEndDate(2022, 8, 3) self.SetCash(100000) universe = ['BTCUSD', 'ETHUSD', 'XRPUSD', 'EOSUSD', 'LTCUSD'] self.pairs = [ Pair(self, ticker) for ticker in universe] self.entryTicket = None self.stopMarketTicket = None self.highestPrice = 0 def OnData(self, data): for pair in self.pairs: # is rsi ready if not pair.sma.IsReady and not pair.rsi.IsReady: return price = data[pair.symbol].Price rsi = pair.rsi.Current.Value sma = pair.sma.Current.Value # send entry limit order if rsi<25 and sma > price and not self.Portfolio[pair.symbol].Invested: self.Debug("rsi is less than 25 and sma is greater than price") quantity = self.CalculateOrderQuantity(pair.symbol, 0.2) self.entryTicket = self.LimitOrder(pair.symbol, quantity, price, "Entry Order") #trailing stop loss if self.stopMarketTicket is not None and self.Portfolio[pair.symbol].Invested: # move up trailing stop price if price > self.highestPrice: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price * 0.96 self.stopMarketTicket.Update(updateFields) #self.Debug(updateFields.StopPrice) def OnOrderEvent(self, orderEvent): for pair in self.pairs: if orderEvent.Status != OrderStatus.Filled: return # send stop loss order if entry limit order is filled if self.entryTicket is not None and self.entryTicket.OrderId == orderEvent.OrderId: self.stopMarketTicket = self.StopMarketOrder(pair.symbol, -self.entryTicket.QuantityFilled, 0.96 * self.entryTicket.AverageFillPrice) # save fill time of stop loss order (and reset highestPrice) if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: self.highestPrice = 0 class Pair: def __init__(self, algorithm, ticker): self.symbol = algorithm.AddCrypto(ticker,Resolution.Daily,Market.Bitfinex).Symbol self.rsi = algorithm.RSI(self.symbol,14,MovingAverageType.Simple, Resolution.Daily) self.sma = algorithm.SMA(self.symbol,50,Resolution.Daily) def OnEndOfDay(self): self.Plot("Indicators","RSI", pair.rsi.Current.Value) self.Plot("Indicators","SMA", pair.sma.Current.Value)