Overall Statistics |
Total Trades
2505
Average Win
0.73%
Average Loss
-0.64%
Compounding Annual Return
7.879%
Drawdown
30.800%
Expectancy
0.075
Net Profit
68.208%
Sharpe Ratio
0.476
Probabilistic Sharpe Ratio
4.191%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
1.14
Alpha
0.061
Beta
0.018
Annual Standard Deviation
0.132
Annual Variance
0.018
Information Ratio
-0.134
Tracking Error
0.203
Treynor Ratio
3.427
Total Fees
$5518.89
Estimated Strategy Capacity
$61000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
|
# https://quantpedia.com/strategies/synthetic-lending-rates-predict-subsequent-market-return/ # # The investment universe consists of SPY ETF. Synthetic shorting costs data are obtained from Borrow Intensity Indicators by the CBOE (and includes 4877 stocks/ETFs). # The paper utilizes the constant maturities of 45 days. Intraday SPY data are obtained from FirstRate Data. The aggregate (mean) borrow intensity is calculated as equally # weighted borrow intensity of each stock/ETF in the sample at day t. The shorting costs data are estimated at a timestamp of 15:57. Calculate the change in the aggregate # intensity at day t as the difference of aggregate borrowing intensity at day t and t-1. Buy the SPY ETF at 15:59 if the difference is positive and short the SPY if the # difference is negative. The positions are held for one day and are closed at 15:58 at next day. # # QC Implementation changes: # - Signal calculation and trade opening is done each day at 15:59. #region imports from AlgorithmImports import * #endregion class SyntheticLendingRatesPredictSubsequentMarketReturn(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 1, 1) self.SetCash(100000) self.spy_symbol:Symbol = self.AddEquity('SPY', Resolution.Minute).Symbol self.lending_data_symbol:Symbol = self.AddData( QuantpediaLendingRates, 'lending_rate', Resolution.Minute).Symbol self.last_lending_mean = None def OnData(self, data: Slice): curr_time:datetime.datetime = self.Time # liquidate at 15:58 if curr_time.hour == 15 and curr_time.minute == 58: self.Liquidate(self.spy_symbol) # lending rate data came in if self.lending_data_symbol in data and data[self.lending_data_symbol]: curr_lending_mean:float = data[self.lending_data_symbol].Value if self.last_lending_mean: # calculate daily change in lending rate diff:float = curr_lending_mean - self.last_lending_mean if diff > 0: self.SetHoldings(self.spy_symbol, 1) else: self.SetHoldings(self.spy_symbol, -1) self.last_lending_mean = curr_lending_mean # Quantpedia data. # NOTE: IMPORTANT: Data order must be ascending (datewise) class QuantpediaLendingRates(PythonData): def GetSource(self, config, date, isLiveMode): return SubscriptionDataSource("data.quantpedia.com/backtesting_data/options/lending_rates_day_close_matur_45_days.csv".format(config.Symbol.Value), SubscriptionTransportMedium.RemoteFile, FileFormat.Csv) def Reader(self, config, line, date, isLiveMode): data:QuantpediaLendingRates = QuantpediaLendingRates() data.Symbol = config.Symbol if not line[0].isdigit(): return None split:list = line.split(';') datetime_str:str = split[0] + ', 15:59' data.Time = datetime.strptime(datetime_str, "%Y-%m-%d, %H:%M") valid_values:list = list(filter(lambda value: value != '', split[1:])) valid_values:list = list(map(lambda str_value: float(str_value), valid_values)) data.Value = np.mean(valid_values) return data