This notebook investigates a practical investing question: if you save a fixed amount every month, is it better to invest on a fixed schedule (classic DCA), or to wait and invest only when the market is “close to a recent low” (i.e., after a drop)?
The analysis simulates monthly contributions invested in SPY (S&P 500 ETF) and compares outcomes when you:
- Always invest the monthly contribution (pure DCA), versus
- Invest the contribution only if the current price is within X% of the rolling low over the last Y years (a simple buy-the-dip rule).
- Data: daily Close prices for SPY loaded from ./data/SPY.csv.
- Contributions: one unit added every ~21 trading days (approx. monthly).
- Decision rule per day (after a warm-up period):
- Compute the low over the last Y years (rolling window of Y × 12 × 21 trading days).
- If today’s price is within X% of that period low, invest the current contribution balance; otherwise, keep it in cash.
- Accounting assumptions:
- Uninvested cash earns 0% (cash drag is explicit).
- No trading costs, taxes, or slippage.
Parameters explored in the notebook:
- Y (look-back window in years): 1, 2, 3, 5
- X (proximity to period low): 0% to 100%
Outputs produced:
- graph_dca.png: returns vs. threshold X for multiple Y values.
- Additional charts showing when investments were actually made for selected (Y, X) pairs.
While exact figures depend on your SPY data file, the patterns over 2010–2023 are consistent with the following:
- Staying in cash waiting for sizable dips typically hurts outcomes. The foregone compounding during long uptrends outweighs the benefit of occasionally catching lower prices.
- Only very loose thresholds (i.e., investing almost all the time) come close to standard DCA performance. As the threshold becomes stricter (e.g., waiting for prices to be within 10–30% of a multi‑year low), the strategy often underinvests for long periods and lags DCA.
- Extreme-dip tactics (waiting to be very close to multi‑year lows) rarely trigger in strong bull markets, leaving large cash balances uninvested and dragging returns.
- There are windows where a modest threshold can match or slightly beat DCA (particularly around prolonged drawdowns), but these are not persistent enough to offset the long periods where cash sits idle.
Bottom line for this simple rule set and period: plain DCA is hard to beat; timing requires long waiting and typically underperforms due to cash drag.
- Ensure you have the requirements installed:
- numpy, pandas, matplotlib
- Example: pip install numpy pandas matplotlib
- Place SPY daily price data at ./data/SPY.csv (must include a Close column).
- Open and run dca_analysis.ipynb in your notebook environment (e.g., Jupyter, VS Code, PyCharm).
- The notebook will display charts and save figures (e.g., graph_dca.png) in the project root.
- Single asset: results are for SPY only. Different assets/markets can behave differently.
- Cash return assumed 0%: if idle cash earns interest, timing strategies may improve, but so does DCA’s opportunity cost benchmark.
- No taxes, fees, or slippage: real-world frictions can change outcomes.
- Look-back definition: “within X% of the period low” is a simple rule, not an optimal market-timing model.
- Sample dependence: 2010–2023 was generally bullish; other periods may yield different rankings.
- Add cash yield to account for interest on uninvested capital.
- Test different assets or diversified portfolios.
- Explore alternative triggers (e.g., valuation, trend, volatility) rather than price proximity to lows.