| Overall Statistics |
|
Total Orders
657
Average Win
2.09%
Average Loss
-2.08%
Compounding Annual Return
6.060%
Drawdown
20.800%
Expectancy
0.252
Start Equity
100000
End Equity
502477.01
Net Profit
402.477%
Sharpe Ratio
0.253
Sortino Ratio
0.169
Probabilistic Sharpe Ratio
0.071%
Loss Rate
38%
Win Rate
62%
Profit-Loss Ratio
1.00
Alpha
0
Beta
0
Annual Standard Deviation
0.091
Annual Variance
0.008
Information Ratio
0.505
Tracking Error
0.091
Treynor Ratio
0
Total Fees
$5089.32
Estimated Strategy Capacity
$150000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
6.54%
|
# https://quantpedia.com/strategies/turn-of-the-month-in-equity-indexes/
#
# Buy SPY ETF 1 day (some papers say 4 days) before the end of the month and sell the 3rd trading day of the new month at the close.
#
# Implementation changes:
# - Trade execution is done 5 minutes before day close.
#region imports
from AlgorithmImports import *
from dateutil.relativedelta import relativedelta
#endregion
class TurnoftheMonthinEquityIndexes(QCAlgorithm):
_ticker: str = 'SPY'
_before_tom_offset: int = 5
_after_tom_offset: int = 3
_before_close_min_offset: int = 5
def initialize(self) -> None:
self.set_start_date(1998, 1, 1)
self.set_cash(100_000)
self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE, AccountType.MARGIN)
self.settings.minimum_order_margin_portfolio_percentage = 0
self.settings.daily_precise_end_time = True
self._market: Symbol = self.add_equity(self._ticker, Resolution.MINUTE).symbol
self.schedule.on(
self.date_rules.month_end(self._market, self._before_tom_offset - 1),
self.time_rules.before_market_close(self._market, self._before_close_min_offset),
self._open_trade
)
self.schedule.on(
self.date_rules.month_start(self._market, self._after_tom_offset - 1),
self.time_rules.before_market_close(self._market, self._before_close_min_offset),
self._close_trade
)
def _open_trade(self) -> None:
if not self.portfolio[self._market].invested:
self.set_holdings(self._market, 1.)
def _close_trade(self) -> None:
self.liquidate(self._market)
def on_data(self, slice: Slice) -> None:
pass