- GuruFinance Insights
- Posts
- Options Backtesting in Python: An Introductory Walkthrough
Options Backtesting in Python: An Introductory Walkthrough
This Stock is Up 220% and Primed for the Next Breakout
Bank of America analysts predict gold will hit $3,000 by 2025 — and this hidden gold stock is set to benefit.
With gold's post-election dip, now could be a good opportunity to consider adding to your portfolio. Savvy investors understand the value of holding gold and gold stocks.
This stock has made impressive gains in recent years, and with insiders continuing to buy, it's one to keep on your watchlist.
P.S. The last gold stock we highlighted in this newsletter saw a strong rally, climbing over 60% just days after our feature. Be sure to keep this one on your watchlist!
Disclaimer: This advertisement is paid content created on behalf of Four Nines Gold Inc. It contains forward-looking statements, which are based on the current beliefs and expectations of Four Nines Gold's management team. These statements involve inherent risks, uncertainties, and other factors that may cause actual results or events to differ significantly from those anticipated. This is not financial advice; we encourage you to conduct your own due diligence. For more details, please refer to SEDAR+ or full disclaimer: https://shorturl.at/cvDsf
Exciting News: Paid Subscriptions Have Launched! 🚀
On September 1, we officially rolled out our new paid subscription plans at GuruFinance Insights, offering you the chance to take your investing journey to the next level! Whether you're just starting or are a seasoned trader, these plans are packed with exclusive trading strategies, in-depth research paper analysis, ad-free content, monthly AMAsessions, coding tutorials for automating trading strategies, and much more.
Our three tailored plans—Starter Investor, Pro Trader, and Elite Investor—provide a range of valuable tools and personalized support to suit different needs and goals. Don’t miss this opportunity to get real-time trade alerts, access to masterclasses, one-on-one strategy consultations, and be part of our private community group. Click here to explore the plans and see how becoming a premium member can elevate your investment strategy!
Trading strategies refer to systematic approaches for buying and selling securities, aimed at generating profits. However, the inherent challenge lies in the fact that, being strategies, they are not foolproof and may not always yield success. This is particularly evident in the case of potentially volatile securities such as options, where an ill-suited strategy can result in significant financial losses at a rapid pace.
The name itself highlights the strategic nature of these approaches, and their outcomes are not guaranteed. While there is no foolproof way to ensure the success of a strategy, a prudent step before implementation is backtesting. Although it’s commonly stated that past performance doesn’t guarantee future returns, historical data serves as a valuable reference point.
This article will guide you on initiating options backtesting in Python. It will begin with a brief overview of options, explore the reasons why Python is a suitable choice, and then delve into using one of the most effective libraries for backtesting.
Receive daily stock trade alerts sent directly to your phone and email.
Stay informed with timely market insights and expert analysis.
Join a community of 150,000+ subscribers benefiting from these alerts
Stay ahead of market trends and capitalize on emerging opportunities.
What are Options?
Options are financial instruments that give investors the right (but not the obligation) to buy or sell an underlying asset at a predetermined price before or at the expiration date. The underlying asset can be stocks, bonds, commodities, or other financial instruments. There are two types of options: call options and put options.
Call Options:
A call option provides the holder (buyer) the right to buy the underlying asset at a specified price, known as the strike price.
The buyer of a call option expects the price of the underlying asset to rise before the option expires. If the asset’s price exceeds the strike price, the buyer can exercise the option and buy the asset at the lower agreed-upon price.
2. Put Options:
A put option gives the holder the right to sell the underlying asset at a predetermined price within a specified time frame.
Put options are typically purchased by investors who anticipate that the price of the underlying asset will decrease. If the asset’s price falls below the strike price, the put option holder can exercise the option and sell the asset at the higher agreed-upon price.
Key Terms:
Strike Price: The price at which the option holder can buy (for call options) or sell (for put options) the underlying asset.
Expiration Date: The date when the option contract expires. After this date, the option is no longer valid.
Premium: The price paid by the option buyer to the option seller for the right to buy or sell the underlying asset. It represents the cost of holding the option.
How Options Work:
Buyer and Seller: In every options trade, there is a buyer and a seller. The buyer pays a premium to the seller for the right to exercise the option if they choose to.
Profit and Loss: The potential profit for the option buyer is unlimited (for call options) or limited to the strike price minus the premium (for put options). The potential loss for the buyer is limited to the premium paid.
Exercise or Expiration: Options can be exercised before or at expiration. If the option is not exercised, it expires worthless.
Covered and Naked Options:
Covered Options: When the seller owns the underlying asset, it is a covered option. This limits the risk for the seller.
Naked Options: If the seller does not own the underlying asset, it is a naked option, which involves higher risk for the seller.
Options provide flexibility for investors and can be used for speculation, hedging, or income generation. However, due to their complexity and the potential for rapid gains or losses, they require a good understanding of the market and careful consideration of associated risks. It’s recommended to seek professional financial advice before engaging in options trading.
Why Use Python?
Python stands out as a favored tool for backtesting trading strategies for several key reasons.
The availability of widely used Python libraries such as NumPy and Pandas simplifies the processing of financial data, particularly when dealing with extensive datasets spanning multiple years.
The use of Jupyter Notebook provides a user-friendly environment for writing and testing code dynamically, offering a visual interface for efficient coding.
Python facilitates the integration of C and C++ code into a Python program, enabling the incorporation of external algorithms seamlessly.
Python’s straightforward syntax and ease of learning make it a popular choice among traders. Its simplicity allows traders to quickly grasp the language, enabling them to express complex trading algorithms with just a few lines of code while learning on the job.
A Basic Backtesting Setup
We’re going to use OptionSuite below. It’s a modular library that makes it easy to add custom strategies, and comes with just enough test data that we can run a quick tutorial. OptionSuite comes with a basic backtesting example. Let’s try it out.
First, you need a Python environment with the Pandas library to run your code. Rather than install Pandas and its many dependencies in your system’s default environment, a virtual environment is considered a best practice.
There are many tools for managing virtual environments. Here is how you can prepare one using the standard venv
tools on Linux. Ensure they're installed on your system before proceeding.
You can use an IDE like PyCharm to create the environment, but here’s a command line example.
mkdir backtesting
cd backtesting/
python3 -m venv ./.venv
source .venv/bin/activate
pip install pandas
First, we create a directory for our project. Next, we create a virtual environment and activate it. Following this, we install pandas in this environment.
Get OptionSuite
git clone https://github.com/sirnfs/OptionSuite.git
Small Configuration Changes
The example provided by OptionSuite is incorporated in the backtester.py file, implementing a basic strangle strategy. However, some adjustments are required before running it.
To prepare the script, it’s necessary to configure it with sample data. While the README provides guidelines for utilizing purchased data, these instructions can be adapted to utilize the test data that comes with the source code.
The data is in marketData/iVolatility/SPX/SPX_2011_2017/RawIV_5day_sample_updated.csv
Use this path, appended to the directory to where you checked out the code in, on line #11 of backtester.py
:
# Create CsvData class object.
dataProvider = 'iVolatility'
filename = '/home/egoebelbecker/src/OptionSuite/marketData/iVolatility/SPX/SPX_2011_2017/RawIV_5day_sample_updated.csv'
So, the code will load the sample data.
Finally, the data stamps in this data don’t agree with the format specified in the data handler configuration, which gives us a chance to see how OptionSuite manages historical market data.
Open datahandler/dataProviders.json
:
{"iVolatility": {
"number_columns": 25,
"column_names": {
"dateTime": "date",
"underlyingTicker": "symbol",
"exchangeCode": "exchange",
"optionSymbol": "option_symbol",
"optionType": "call/put",
"strikePrice": "strike",
"underlyingPrice": "stock_price_close",
"askPrice": "ask",
"bidPrice": "bid",
"tradePrice": "",
"impliedVol": "iv",
"volume": "volume",
"openInterest": "open_interest",
"delta": "delta",
"theta": "theta",
"vega": "vega",
"gamma": "gamma",
"rho": "rho",
"expirationDateTime": "option_expiration",
"exercisePrice": "",
"assignPrice": "",
"openCost": "",
"closeCost": ""
},
"call_symbol_abbreviation": "C",
"put_symbol_abbreviation": "P",
"date_time_format": "%m/%d/%y",
"data_source_type": "options"
}}
This file establishes the correlation between the columns in your CSV market data and the field names in OptionSuite. It enables the utilization of any data source that furnishes the necessary data for your trading strategy.
The data_time_format
setting on line #31 doesn't match the sample data. Change it to "%m/%d/%y"
You’ll find information on how these date fields work here.
Finally, we need to adjust the strategy parameters so there’s enough capital to make some trades.
They start on line #34.
# Parameters for strangle strategy - TODO: move params to file.
optCallDelta = 0.16
maxCallDelta = 0.30
optPutDelta = -0.16
maxPutDelta = -0.30
startDateTime = None
buyOrSell = optionPrimitive.TransactionType.SELL
underlyingTicker = 'SPX'
orderQuantity = 1
expCycle = strategy.ExpirationTypes.MONTHLY
optimalDTE = 45
minimumDTE = 35
maxBidAsk = 15 # A general rule of thumb is to take 0.001*underlyingPrice. Set to 15 to ignore field.
startingCapital = decimal.Decimal(500000)
self.maxCapitalToUse = 0.5 # Up to 50% of net liq can be used in trades.
maxCapitalToUsePerTrade = 0.20 # 10% max capital to use per trade / strategy.
# Set up strategy (strangle strategy) and risk management preference.
riskManagement = strangleRiskManagement.StrangleRiskManagement(
strangleRiskManagement.StrangleManagementStrategyTypes.CLOSE_AT_50_PERCENT) # strangleRiskManagement.StrangleManagementStrategyTypes.HOLD_TO_EXPIRATION)
First, raise the amount of startingCapital to 500000 on line #47.
Then, double the amount of capital per trade to 0.20.
Run a Backtest
Finally, we run a test.
Here is a command session in PyCharm:
/home/ayratmurtazin/Projects/OptionSuite/venv/bin/python /home/ayratmurtazin/Projects/OptionSuite/backTester.py
Process finished with exit code 0
The backtester creates two log files. positions_strangle_XXXXX.log
has messages from the Python classes. positions_strangle_XXXXX.csv
has trading information and results:
Date,UnderlyingPrice,NetLiq,RealizedCapital,NumPositions,TotNumContracts,BuyingPower,TotalDelta
2011-01-04 00:00:00,1270.2,500370.3719000000000001193712,499995.3719000000000001193712,1,3,78705.000,-0.019998000000000016
2011-01-05 00:00:00,1276.56,500485.7438000000000002387424,499990.7438000000000002387424,2,6,162720.0000,0.21605400000000008
2011-01-06 00:00:00,1273.85,500436.1157000000000003581136,499986.1157000000000003581136,3,9,239066.2500,0.0736200000000001
2011-01-07 00:00:00,1271.5,501516.1157000000000003581136,499986.1157000000000003581136,3,9,235387.500,-0.16323300000000004
So, we can see that the strategy lost money with a strike price of 1270.2 and 1271.5, but made a small profit at 1276.56 and 1273.85.
Reply