Backtest how often the markets rally after each U.S. election, to find common patterns post 30 days, 60 days, and 90 days.
Download BacktesterUnderstanding 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.
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:
By comparing results across multiple elections, you’ll gain insights into whether this approach has a repeatable edge or is just market noise.
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;
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.
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;
getYYYYMMDD(): Fetches the date for each bar in the chart.true if the bar corresponds to an election date, otherwise false.This variable serves as the foundation for triggering buy or sell orders in the strategy.
We’ll now create an input variable to define how many days to hold a position post-election:
input postElectionDays = 30;
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.
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);
electionDay[1]), using the open price of that bar.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.
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:
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.
Here are some ways to enhance and adapt the backtester for deeper analysis:
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;
def party1 = 1;
def election2 = 20161108;
def party2 = 2;
def election3 = 20121106;
def party3 = 1;
def election4 = 20081104;
def party4 = 1;
def election5 = 20041102;
def party5 = 2;
def election6 = 20001107;
def party6 = 2;
def electionDay = getYYYYMMDD() == election1 or getYYYYMMDD() == election2 or getYYYYMMDD() == election3 or getYYYYMMDD() == election4 or getYYYYMMDD() == election5 or getYYYYMMDD() == election6;
AddOrder(OrderType.Buy_To_Open, electionDay[1], open);
AddOrder(OrderType.Sell_To_Close, electionDay[postElectionDays], close);Want the .ts file and the one-click import? Both come with a free account.
Here are some resources that you may find useful:
Join 40,000+ traders using institutional-grade tools for ThinkOrSwim.
Get the Bundle