Overall Statistics |
Total Trades 14 Average Win 5.01% Average Loss 0% Compounding Annual Return 41.264% Drawdown 4.000% Expectancy 0 Net Profit 41.398% Sharpe Ratio 3.14 Probabilistic Sharpe Ratio 98.906% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.255 Beta 0.122 Annual Standard Deviation 0.088 Annual Variance 0.008 Information Ratio 0.417 Tracking Error 0.257 Treynor Ratio 2.262 Total Fees $14.00 Estimated Strategy Capacity $480000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 3.83% |
# region imports from AlgorithmImports import * # endregion class WellDressedLightBrownDolphin(QCAlgorithm): def Initialize(self): # self referenced the QCAlgorithm class self.SetStartDate(2020, 1, 1) # Set Start Date for back test self.SetEndDate(2021, 1, 1) # Set End Date for back test otherwise most recent date is chosen self.SetCash(25000) # Set Strategy Cash # Resolution is the timeframe for this ticker equity = self.AddEquity("SPY", Resolution.Daily, ) equity.SetDataNormalizationMode(DataNormalizationMode.Raw) # self.spy is an instance variable due to 'self' self.spy = equity.Symbol self.SetBenchmark("SPY") # Cash accounts no leverage, Margin allows leverage self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # helper variables to track entry price self.entryPrice = 0 # timedelta (from datetime library) object represents a duration, the difference between two dates or times. self.period = timedelta(days = 31) self.nextEntryTime = self.Time # current time frontier QCA def OnData(self, data: Slice): # check if there is data in the Slice object dictionary for the symbol if not self.spy in data: return # below multiple ways to get the price based on the dictionaries of various classes in data Slice object # price = data.Bars[self.spy].Close # price = self.Securities[self.spy].Close price = data[self.spy].Close self.Debug("{0} Close is: {1}".format(self.spy ,price)) if not self.Portfolio.Invested: # check if nextEntryTime smaller dan current time frontier # if true means the current time has passed the nextEntryTime, the algo may buy if self.nextEntryTime <= self.Time: # self.MarketOrder(self.spy, int(self.PortfolioCash / price)) # SetHoldings beter way, because of auto calculation. 1 = 100% buy, -1=100% sell self.SetHoldings(symbol=self.spy, percentage=1) self.Log(f"BUY SPY @{price}") # save entryPrice to know when to exit self.entryPrice = price # if 10% profit or -10% loss then exit by liquidating elif self.entryPrice * 1.05 < price or self.entryPrice * 0.9 > price: #self.Liquidate(self.spy) # liquidates all positions in your portfolio self.Liquidate() self.Log(f"SELL SPY @{price}") # bot can trade again after 31 days self.nextEntryTime = self.Time + self.period