Understanding how markets react post-election can be a powerful tool for traders.
In this tutorial, I’ll walk you through creating a simple yet effective post-election backtester in ThinkOrSwim (TOS). This tutorial covers how to code the backtester, input election data, and interpret the results.
Whether you’re curious about volatility trends or exploring the viability of an election-based strategy, I think you’ll find that this thinkScript tutorial will open you up to a world of possibilities.
What Does the Post-Election Backtester Do?
This backtester is designed to analyze price movement after U.S. presidential elections. It uses historical election dates to test a strategy of holding a position for a set number of days after election results. Key metrics include:
- Profit/Loss: Measures the performance of holding positions post-election.
- Success Rate: Tracks how often the strategy yields positive results.
- Timeframe Flexibility: Tests different holding periods (30, 60, or 90 days).
By comparing results across multiple elections, you’ll gain insights into whether this approach has a repeatable edge or is just market noise.
Step 1: Input Historical Election Dates
First, we need to define the election dates to use as reference points for the backtester. The code below lists U.S. presidential election dates from 2000 to 2020:
def election1 = 20201103;
def election2 = 20161108;
def election3 = 20121106;
def election4 = 20081104;
def election5 = 20041102;
def election6 = 20001107;
Why This Format?
The ThinkOrSwim function getYYYYMMDD() retrieves the date of each bar in the format YYYYMMDD. By storing election dates in this format, we can easily compare them to the current date and trigger actions in the backtester.
Step 2: Create a Variable for Election Days
Next, we need to identify if a particular bar matches any of our defined election dates. Here’s how:
def electionDay = getYYYYMMDD() == election1 or getYYYYMMDD() == election2
or getYYYYMMDD() == election3 or getYYYYMMDD() == election4
or getYYYYMMDD() == election5 or getYYYYMMDD() == election6;
How It Works
getYYYYMMDD(): Fetches the date for each bar in the chart.- Logical comparison: Checks if the date matches any of the six defined election dates.
- Output: Returns
trueif the bar corresponds to an election date, otherwisefalse.
This variable serves as the foundation for triggering buy or sell orders in the strategy.
Step 3: Set the Holding Period
We’ll now create an input variable to define how many days to hold a position post-election:
input postElectionDays = 30;
Why Use an Input Variable?
The input keyword allows you to modify the holding period directly from the strategy settings, making the backtester flexible for testing different timeframes. While the default is set to 30 days, you can adjust it to 60 or 90 days based on your analysis goals.
Step 4: Add Buy and Sell Orders
With the election dates and holding period defined, we can now set up buy and sell orders:
AddOrder(OrderType.Buy_To_Open, electionDay[1], open);
AddOrder(OrderType.Sell_To_Close, electionDay[postElectionDays], close);
Breaking Down the Code
- Buy Order: Executes on the bar after the election date (
electionDay[1]), using the open price of that bar. - Sell Order: Closes the position after the specified holding period (
postElectionDays), using the closing price of that bar.
This logic ensures that the strategy simulates buying immediately after election results and exiting after the desired holding period.
Step 5: Test and Analyze Results
Once the code is implemented, run the backtester on historical data. You’ll see a report summarizing the strategy’s performance for each election cycle. Key points to note:
- Profitability: Compare the total P&L for each holding period (30, 60, and 90 days).
- Bear Market Years: Notice how elections during 2000 and 2008 (bear market years) yielded poor results, highlighting the importance of market context.
- Instrument Variability: Test the strategy across different instruments (e.g., SPY, QQQ, or Dow futures) to identify patterns.
Example Insights
In SPY, the 2020 election contributed significantly to positive P&L, but earlier elections showed mixed results. Extending the holding period to 60 or 90 days didn’t consistently improve profitability, suggesting that post-election volatility may not always follow a predictable pattern.
Tips for Optimizing the Backtester
Here are some ways to enhance and adapt the backtester for deeper analysis:
- Market Context: Incorporate additional variables like pre-election market trends or volatility levels.
- Party Analysis: Examine results based on which party won the election to identify potential biases.
- Additional Instruments: Test leveraged ETFs (e.g., TQQQ) or sector-specific indices for more granular insights.
- Holding Periods: Experiment with custom holding periods to find optimal timeframes for specific market conditions.
Conclusion
The Post-Election Backtester offers a straightforward way to analyze market behavior following U.S. presidential elections. While this tutorial provides a foundational strategy, you can expand it further to account for market context, instrument specificity, and alternative holding periods. Use this as a starting point to explore post-election volatility and refine your trading strategies. Good luck, and happy backtesting!
## Input Variables
input postElectionDays = 30;
## Election Dates Going Back to 2000
## Demoractic Party = 1; Republican Party = 2;
def election1 = 20201103;
// ... 27 more lines ...Here are some resources that you may find useful: