Implementing a Cross-Sectional Momentum Strategy in Moonshot
Summary
This tutorial section explains how to implement a cross-sectional momentum strategy, commonly called Up Minus Down, in Moonshot, an open-source vectorized backtester that uses pandas. The example ranks securities by returns over a 252-day momentum window while skipping the most recent 22 days, selects the top 50 percent, and rebalances monthly. It introduces a strategy class whose methods turn prices into signals and whose class attributes hold parameters.
A demo subclass inherits the strategy logic while specifying a US stock database, a universe, and a commission model for a sample backtest. The discussion illustrates how inheritance allows a strategy's settings to be adapted without rewriting its core logic. This is an implementation walkthrough rather than a report of results: it gives no performance statistics, transaction-cost analysis, or discussion of survivorship and other data biases. The stated parameters and sample database define the demonstration, so they should not be assumed to suit other universes or trading conditions.
Key ideas
- Up Minus Down is a cross-sectional momentum approach that buys recent winners and sells recent losers.
- The example uses a 252-day ranking window, skips the latest 22 days, selects the top half, and rebalances monthly.
- Moonshot uses vectorized pandas operations to process a date range in a backtest.
- A subclass can override database, universe, and commission settings while inheriting the core strategy logic.
- The tutorial provides implementation guidance but no backtest results or bias analysis.
Tags
Full text
# Moonshot Strategy Code
<a href="https://www.quantrocket.com"><img alt="QuantRocket logo" src="https://www.quantrocket.com/assets/img/notebook-header-logo.png"></a><br>
<a href="https://www.quantrocket.com/disclaimer/">Disclaimer</a>
***
[Moonshot Intro](Introduction.ipynb) › Part 4: Moonshot Code
***
# Moonshot Strategy Code
Next we'll use Moonshot to backtest the momentum factor we explored in the previous notebook.
## What is Moonshot?
Moonshot is an open-source, vectorized backtester created by QuantRocket. A vectorized backtester is one which uses vectorized operations to backtest an entire date range at once, in contrast to event-driven backtesters like Zipline which process one event at a time. Moonshot uses pandas to perform vectorized operations. You can learn more about Moonshot in the [usage guide](https://www.quantrocket.com/docs/#moonshot).
## Install UMD strategy file
Cross-sectional momentum strategies which buy recent winners and sell recent losers commonly go by the name of UMD, or "Up Minus Down." An implementation of UMD for Moonshot is available in [umd.py](umd.py).
To "install" the strategy, execute the following cell to move the strategy file to the `/codeload/moonshot` directory, where Moonshot looks:
> The ! sytax below lets us execute terminal commands from inside the notebook.
```python
# make directory if doesn't exist
!mkdir -p /codeload/moonshot
!mv umd.py /codeload/moonshot/
```
## How a Moonshot backtest works
The usage guide describes in detail how a Moonshot backtest works, but here we'll just cover a few highlights. Near the top of the file, you'll see the `UpMinusDown` class, which inherits from the `Moonshot` class.
```python
class UpMinusDown(Moonshot):
CODE = "umd"
MOMENTUM_WINDOW = 252
RANKING_PERIOD_GAP = 22
LOOKBACK_WINDOW = MOMENTUM_WINDOW
TOP_N_PCT = 50
REBALANCE_INTERVAL = "M"
def prices_to_signals(self, prices: pd.DataFrame):
closes = prices.loc["Close"]
returns = closes.shift(self.RANKING_PERIOD_GAP)/closes.shift(self.MOMENTUM_WINDOW) - 1
...
```
Strategy logic is implemented in class methods (for example, `prices_to_signals`), and parameters are stored as class attributes (for example, `REBALANCE_INTERVAL`).
Now find the `UpMinusDownDemo` class further down in the file:
```python
class UpMinusDownDemo(UpMinusDown):
CODE = "umd-demo"
DB = "usstock-free-1d"
UNIVERSES = "usstock-free"
TOP_N_PCT = 50
COMMISSION_CLASS = USStockCommission
```
This class is a subclass of `UpMinusDown` and thus inherits its functionality while overriding a few of its parameters. This is the actual strategy we will run in our backtest. Note the `DB` parameter: it tells the strategy to use the history database we created in an earlier tutorial. The optional `UNIVERSES` parameter indicates which subset of securities in the database to query. (Since the securities in our sample universe are the only securities in our history database, the `UNIVERSES` parameter could be omitted in this case.) The `CODE` parameter gives us an easy way to reference the strategy via the QuantRocket API.
***
## *Next Up*
Part 5: [Moonshot Backtest](Part5-Moonshot-Backtest.ipynb)Shown in full with attribution under the source's licence. Licence: Apache-2.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.