Custom Python code for calculating the Probability of Profit (POP) for options trading strategies using Monte Carlo Simulations.

Related tags

Miscellaneouspoptions
Overview

poptions

Custom Python code for calculating the Probability of Profit (POP) for options trading strategies using Monte Carlo Simulations. The Monte Carlo Simulation runs thousands of individual stock price simulations and uses the data from these simulations to average out a POP number.

Unlike other calculators, poptions lets you specify a target profit, such as a percentage of maximum profit or a multiple of the debit paid, that will trigger your position to close when it's reached in the simulation. Additionally, you will specify the 'closing days', which refers to the number of calendar days that will pass until you close the position (assuming the target profit wasn't reached to trigger the closing).

In simpler words: the estimated POP from poptions refers to the probability of hitting a specified target profit within a specified number of calendar days.

Poptions lets you add MULTIPLE combinations of target profits and closing days!

Poptions also outputs an Average Days To Close (ADTC) number. This is the estimated average number of calendar days you will have to wait until you reach your target profit, assuming that the POP ended up in your favor.

Poptions can also be used to evaluate existing trades (see below).

Disclaimer: poptions has not been vetted by any certified professional or expert. The calculations do not constitute investment advice. They are for educational purposes only. Calculations may contain mistakes and are made using models with inherent limitations that are highlighted below. Use this tool at your own risk.

How does it work?

A great video explaining the underlying logic is shown here: https://www.tastytrade.com/shows/the-skinny-on-options-modeling/episodes/probability-of-50-profit-12-17-2015

In short, thousands of stock price simulations are executed in which the price change per day is modeled according to Geometric Brownian Motion. The Black-Scholes Model is then used to estimate the price of an options contract (or multiple contracts depending on the strategy used) per day in each simulation. The number of simulations in which the selected profit criteria is met (e.g. 50% of maximum profit within 20 calendar days) is divided by the total number of simulations, giving you an estimate of the POP. A similar averaging is done to acquire the ADTC.

poptions makes the following assumptions for its simulations:

  • The stock price volatility is equal to the implied volatility and remains constant.
  • Geometric Brownian Motion is used to model the stock price.
  • Risk-free interest rates remain constant.
  • The Black-Scholes Model is used to price options contracts.
  • Dividend yield is not considered.
  • Commissions are not considered.
  • Assignment risks are not considered.
  • Earnings date and stock splits are not considered.

Of course, not all of these assumptions are true in real life and so there are limitations to this approach. For example, it's highly unlikely that the stock price volatility remains constant for several days. Thus, one should take these results with a grain of salt.

How to use poptions

The requirements.txt file lists all the python packages (and their versions) that need to be installed for poptions to work.

A working example of a Call Credit Spread strategy is located in the poptions_examples.py file, as shown:

underlying = 137.31     # Current underlying price
short_strike = 145      # Short strike price
short_price = 1.13      # Short call price
long_strike = 150
long_price = 0.4
rate = 0        # Annualized risk-free rate as a percentage
sigma = 26.8        # Implied Volatility as a percentage
days_to_expiration = 45     # Calendar days left till expiration
percentage_array = [20, 30, 40]  # Percentage of maximum profit that will trigger the position to close
closing_days_array = [21, 22, 23]       # Max calendar days passed until position is closed
trials = 2000       # Number of independent trials

print("Call Credit Spread: ", poptions.callCreditSpread(underlying, sigma, rate, trials, days_to_expiration,
                                                        closing_days_array, percentage_array, short_strike,
                                                        short_price, long_strike, long_price))

The comments in the code should be self-explanatory, but the percentage_array, closing_days_array, and trials variables require some extra clarification:

  • The first elements in percentage_array and closing_days_array are 20 and 21, respectively.
    This means that our target profit is 20% of maximum profit (0.2 * (short_price - long_price) = $ 0.146). The Monte Carlo Simulation will consider each individual simulation (renamed to trial here) a success if this target profit is achieved. If this target profit is not reached within 21 calendar days, it will be considered a failure.

  • You can add multiple combinations of target profits and closing days by simply adding extra elements to percentage_array and closing_days_array! In the above example, we tell the Simulation to also evaluate 30% and 40% of maximum profits for 22 and 23 calendar days, respectively.

  • Increasing the number of trials will improve the accuracy of your estimations at the cost of a slower simulation.

Some Extra Notes:

  • Running poptions.callCreditSpread() will not output consistent results. There will always be some variance from its previous runs. This is because a new simulation is started from scratch for every run. The amount of variance depends on how high trials is set: More trials -> higher accuracy (less variance).

  • For the Long Call and Long Put strategies, percentage_array is replaced with multiple_array. This means that the target profit is now defined as a multiple of the debit that you paid to open the position. For example, if you bought a call option for $1.00, a value of [2] in multiple_array means that your target profit is 2 * $ 1.00 = $ 2.00.

  • You can evaluate existing trades with poptions! Type the net credit received into ONE of the short price variables, and leave the rest of the price variables at 0. Fill out all other variables with present data. Example: Net credit received was $0.73 for a Call Credit Spread, so short_price is 0.73 and long_price is 0. All other variables are filled with present data. For strategies where a net debit is paid like Debit Spreads, the debit paid should be in ONE of the long price variables, and leave the rest of the price variables at 0.

Entering existing trades is NOT supported for Covered Calls unless the current underlying price is the same as it was when you opened the position! This is because the underlying variable refers to the purchase price of the stock when you opened the position.

Running poptions_examples.py gives you the following output:

Call Credit Spread:  {'pop': [61.3, 57.65, 52.55], 'pop_error': [2.81, 2.85, 2.88], 'avg_dtc': [8.87, 10.3, 11.41], 'avg_dtc_error': [0.39, 0.43, 0.45]}
  • pop is the probability of reaching the target profit within the closing days. The first element in pop corresponds to the first elements in percentage_array and closing_days_array.

  • pop_error is the error range for pop. In the above example, for the first element, there is a 99% chance that the 'true' value for pop is between 58.49 (61.3 - 2.81) and 64.11 (61.3 + 2.81). Of course, this error range gets smaller as trials is increased.

  • avg_dtc refers to the Average Days To Close (ADTC).

  • avg_dtc_error is the error range for avg_dtc.

If avg_dtc falls on a weekend/holiday when the markets are closed, then you can assume that the closing date is on the following business/trading day.

SPEED BOOST with Numba!

If you're looking to potentially speed up simulations by 100x, the Numba python package can help you out! Numba translates Python functions to optimized machine code at runtime using the industry-standard LLVM compiler library. Numba-compiled numerical algorithms in Python can approach the speeds of C or FORTRAN.

Using Numba is shockingly easy. It requires making very little modifications to our code. Follow these steps to speed up poptions.callCreditSpread() in poptions_examples.py with Numba:

Open the CallCreditSpread.py file. Add the following decorator to this function:

@jit(nopython=True, cache=True)
def bsm_debit(sim_price, strikes, rate, time_fraction, sigma):
    ...

Open the MonteCarlo.py file. Add the decorator to this function:

@jit(nopython=True, cache=True)
def monteCarlo(underlying, rate, sigma, days_to_expiration, closing_days_array, trials, initial_credit,
                   min_profit, strikes, bsm_func):
    ...

Open the BlackScholes.py file. Add the decorator to the functions:

@jit(nopython=True, cache=True)
def blackScholesPut(s, k, rr, tt, sd):
    ...
    
@jit(nopython=True, cache=True)
def blackScholesCall(s, k, rr, tt, sd):
    ...

You're good to go, but you MUST account for the following: The first time you call poptions.callCreditSpread() will be slow (around a few seconds) since it triggers a compilation step for Numba. The second poptions.callCreditSpread() call is where you'll see the performance gains. Here's a comparison of the speeds between calls:

First poptions.callCreditSpread() call WITH Numba Compilation: 1.756 seconds
Second poptions.callCreditSpread() call WITHOUT Numba Compilation: 0.0064 seconds

Donations

If you like the project and feel like donating some crypto to the author(s), you can do so here:

BTC: 16xbCyVZB3x3PNFs1qQEXGsNgtTd4BKE6z

LTC: Lg1d1VEd5DMQzycZTSSeDEc59yomwDwX8j

Thank you!

License

MIT License

A description of this license can be found in the LICENSE.txt file.

KeyBrowser: A program launches a browser and a keylogger at the same time, is used to retrieve a person's personal information

KeyBrowser: A program launches a browser and a keylogger at the same time, is used to retrieve a person's personal information

3 Oct 16, 2022
全局指针统一处理嵌套与非嵌套NER

GlobalPointer 全局指针统一处理嵌套与非嵌套NER。 介绍 博客:https://kexue.fm/archives/8373 效果 人民日报NER 验证集F1 测试集F1 训练速度 预测速度 CRF 96.39% 95.46% 1x 1x GlobalPointer (w/o RoPE

苏剑林(Jianlin Su) 183 Jan 06, 2023
Polypheny Connector for Python

Polypheny Connector for Python This enables Python programs to access Polypheny databases, using an API that is compliant with the Python Database API

Polypheny 3 Jan 03, 2022
Un script en python qui permet d'automatique bumpée (disboard.org) tout les 2h

auto-bumper Un script en python qui permet d'automatique bumpée (disboard.org) tout les 2h Pour la première utilisation, 1.Lancer Install.bat 2.(faire

!! 1 Jan 09, 2022
The code behind sqlfmt.com, a web UI for sqlfmt

The code behind sqlfmt.com, a web UI for sqlfmt

Ted Conbeer 2 Dec 14, 2022
Pokehandy - Data web app sobre Pokémon TCG que desarrollo durante transmisiones de Twitch, 2022

⚡️ Pokéhandy – Pokémon Hand Simulator [WIP 🚧 ] This application aims to simulat

Rodolfo Ferro 5 Feb 23, 2022
Parser for air tickets' price

Air-ticket-price-parser Parser for air tickets' price How to Install Firefox If geckodriver.exe is not compatible with your Firefox version, download

Situ Xuannn 1 Dec 13, 2021
💘 Write any Python with 9 Characters: e,x,c,h,r,(,+,1,)

💘 PyFuck exchr(+1) PyFuck is a strange playful code. It uses only nine different characters to write Python3 code. Inspired by aemkei/jsfuck Example

Satoki 10 Dec 25, 2022
Roman numeral conversion with python

Roman numeral conversion Discipline: Programming Languages Student: Paulo Henrique Diniz de Lima Alencar. Language: Python Description Responsible for

Paulo Alencar 1 Jul 11, 2022
Script to use SysWhispers2 direct system calls from Cobalt Strike BOFs

SysWhispers2BOF Script to use SysWhispers2 direct system calls from Cobalt Strike BOFs. Introduction This script was initially created to fix specific

FalconForce 101 Dec 20, 2022
GitHub Actions Version Updater Updates All GitHub Action Versions in a Repository and Creates a Pull Request with the Changes.

GitHub Actions Version Updater GitHub Actions Version Updater is GitHub Action that is used to update other GitHub Actions in a Repository and create

Maksudul Haque 42 Dec 22, 2022
Hopefully it'll become a very annoying desktop pet

AnnoyingPet Basic Tutorial: https://seebass22.github.io/python-desktop-pet-tutorial/ Handling Mouse Input: https://pythonhosted.org/pynput/mouse.html

1 Jun 08, 2022
Simple tools for the Horse Reality webgame

Realtools (Web Tools for Horse Reality) These tools were made on request from a close friend of mine who plays this game. A live instance can be found

shay 0 Sep 06, 2022
This Program Automates The Procces Of Adding Camos On Guns And Saving Them On Modern Warfare Guns

This Program Automates The Procces Of Adding Camos On Guns And Saving Them On Modern Warfare Guns

Flex Tools 6 May 26, 2022
Different steganography methods with examples and my own small image database

literally-the-most-useless-project [Different steganography methods with examples and my own small image database] This project currently contains thr

Kamyishka 1 Dec 09, 2022
Parametric Bottle in CADQuery

Parametric Bottle using CADQuery The proposed code makes it possible to generate different types and sizes of 3D bottles in order to train Pixel2mesh

Ayoub EL HOUDRI 1 May 22, 2022
This script is written with Python for selling steam community items automatically.

SteamCommunityItemAutoSell Description This script is written with Python for selling steam community items automatically. Install git clone https://g

14 Oct 26, 2022
Explore-bikeshare-data - GitHub project as part of the Programming for Data Science with Python Nanodegree from Udacity

Date created February 10, 2022 Project Title Explore US Bikeshare Data Descripti

Thárcyla 1 Feb 14, 2022
Sample python script for monitoring Rocketchat database and get statistics of users.

rocketchat-DB-monitoring Sample python script for monitoring Rocketchat database and get statistics of users. 1. Update python: yum check-update && yu

Mojtaba Taleghani 1 Apr 12, 2022
PSP (Python Starter Package) is meant for those who want to start coding in python but are new to the coding scene.

Python Starter Package PSP (Python Starter Package) is meant for those who want to start coding in python, but are new to the coding scene. We include

Giter/ 1 Nov 20, 2021