Code Monkey home page Code Monkey logo

optopsy's Introduction

Downloads Black

Optopsy

Optopsy is a nimble backtesting and statistics library for option strategies, it is designed to answer questions like "How do straddles perform on the SPX?" or "Which strikes and/or expiration dates should I choose to make the most potential profit?"

Use cases for Optopsy:

  • Generate option strategies from raw option chain datasets for your own analysis
  • Discover performance statistics on percentage change for various options strategies on a given stock

Supported Option Strategies

  • Calls/Puts
  • Straddles/Strangles
  • Vertical Call/Put Spreads

Documentation

Please see the wiki for API reference.

Usage

Use Your Data

  • Use data from any source, just provide a Pandas dataframe with the required columns when calling optopsy functions.

Dependencies

You will need Python 3.6 or newer and Pandas 0.23.1 or newer and Numpy 1.14.3 or newer.

Installation

pip install optopsy==2.0.1

Example

Let's see how long calls perform on the SPX on a small demo dataset on the SPX: Download the following data sample from DeltaNeutral: http://www.deltaneutral.com/files/Sample_SPX_20151001_to_20151030.csv

This dataset is for the month of October in 2015, lets load it into Optopsy. First create a small helper function that returns a file path to our file. We will store it under a folder named 'data', in the same directory as the working python file.

def filepath():
    curr_file = os.path.abspath(os.path.dirname(__file__))
    return os.path.join(curr_file, "./data/Sample_SPX_20151001_to_20151030.csv")

Next lets use this function to pass in the file path string into Optopsy's csv_data() function, we will map the column indices using the defined function parameters. We are omitting the start_date and end_date parameters in this call because we want to include the entire dataset. The numeric values represent the column number as found in the sample file, the numbers are 0-indexed:

import optopsy as op

spx_data = op.csv_data(
    filepath(),
    underlying_symbol=0,
    underlying_price=1,
    option_type=5,
    expiration=6,
    quote_date=7,
    strike=8,
    bid=10,
    ask=11,
)

The csv_data() function is a convenience function. Under the hood it uses Panda's read_csv() function to do the import. There are other parameters that can help with loading the csv data, consult the code/future documentation to see how to use them.

Optopsy is a small simple library that offloads the heavy work of backtesting option strategies, the API is designed to be simple and easy to implement into your regular Panda's data analysis workflow. As such, we just need to call the long_calls() function to have Optopsy generate all combinations of a simple long call strategy for the specified time period and return a DataFrame. Here we also use Panda's round() function afterwards to return statistics within two decimal places.

long_calls_spx_pct_chgs = op.long_calls(spx_data).round(2)

The function will returned a Pandas DataFrame containing the statistics on the percentange changes of running long calls in all valid combinations on the SPX:

dte_range otm_pct_range count mean std min 25% 50% 75% max
0 (0, 7] (-0.5, -0.45] 155 0.03 0.02 -0.02 0.01 0.02 0.04 0.11
1 (0, 7] (-0.45, -0.4] 201 0.04 0.03 -0.02 0.01 0.03 0.06 0.12
2 (0, 7] (-0.4, -0.35] 247 0.04 0.03 -0.02 0.02 0.04 0.07 0.13
3 (0, 7] (-0.35, -0.3] 296 0.05 0.04 -0.02 0.02 0.04 0.08 0.15
4 (0, 7] (-0.3, -0.25] 329 0.05 0.05 -0.03 0.02 0.05 0.09 0.17
5 (0, 7] (-0.25, -0.2] 352 0.06 0.05 -0.03 0.02 0.05 0.1 0.2
6 (0, 7] (-0.2, -0.15] 383 0.08 0.07 -0.04 0.03 0.07 0.13 0.26
7 (0, 7] (-0.15, -0.1] 417 0.11 0.09 -0.06 0.04 0.09 0.17 0.37
8 (0, 7] (-0.1, -0.05] 461 0.18 0.16 -0.12 0.07 0.15 0.28 0.69
9 (0, 7] (-0.05, -0.0] 505 0.64 1.03 -1 0.14 0.37 0.87 7.62
10 (0, 7] (-0.0, 0.05] 269 2.34 8.65 -1 -1 -0.89 1.16 68
11 (0, 7] (0.05, 0.1] 2 -1 0 -1 -1 -1 -1 -1
12 (7, 14] (-0.5, -0.45] 70 0.06 0.03 0.02 0.03 0.07 0.08 0.12
13 (7, 14] (-0.45, -0.4] 165 0.09 0.04 0.02 0.06 0.08 0.1 0.17
14 (7, 14] (-0.4, -0.35] 197 0.09 0.04 0.02 0.07 0.09 0.12 0.19
15 (7, 14] (-0.35, -0.3] 235 0.11 0.04 0.02 0.09 0.1 0.13 0.21
16 (7, 14] (-0.3, -0.25] 265 0.13 0.05 0.03 0.1 0.12 0.15 0.25
17 (7, 14] (-0.25, -0.2] 280 0.15 0.06 0.03 0.11 0.14 0.18 0.3
18 (7, 14] (-0.2, -0.15] 307 0.18 0.08 0.04 0.14 0.18 0.23 0.38
19 (7, 14] (-0.15, -0.1] 332 0.25 0.11 0.05 0.18 0.24 0.31 0.54
20 (7, 14] (-0.1, -0.05] 370 0.4 0.18 0.07 0.29 0.39 0.52 0.97
21 (7, 14] (-0.05, -0.0] 404 1.02 0.68 -0.46 0.58 0.86 1.32 4.4
22 (7, 14] (-0.0, 0.05] 388 1.52 4.45 -1 -0.99 -0.73 2.65 32
23 (7, 14] (0.05, 0.1] 36 -0.93 0.06 -1 -1 -0.94 -0.87 -0.83
24 (14, 21] (-0.5, -0.45] 6 0.1 0.01 0.09 0.09 0.1 0.1 0.1
25 (14, 21] (-0.45, -0.4] 66 0.14 0.04 0.09 0.11 0.14 0.17 0.23
26 (14, 21] (-0.4, -0.35] 91 0.16 0.04 0.1 0.12 0.16 0.2 0.25
27 (14, 21] (-0.35, -0.3] 135 0.18 0.05 0.11 0.13 0.17 0.21 0.28
28 (14, 21] (-0.3, -0.25] 149 0.2 0.05 0.12 0.15 0.2 0.25 0.33
29 (14, 21] (-0.25, -0.2] 160 0.24 0.06 0.14 0.18 0.23 0.29 0.4
30 (14, 21] (-0.2, -0.15] 174 0.3 0.08 0.17 0.23 0.29 0.35 0.51
31 (14, 21] (-0.15, -0.1] 187 0.4 0.11 0.22 0.3 0.38 0.48 0.7
32 (14, 21] (-0.1, -0.05] 211 0.63 0.19 0.32 0.47 0.6 0.75 1.16
33 (14, 21] (-0.05, -0.0] 229 1.39 0.53 0.58 1 1.3 1.73 3.1
34 (14, 21] (-0.0, 0.05] 252 2.58 2.92 -1 -1 2.72 4.56 10.1
35 (14, 21] (0.05, 0.1] 93 -0.82 0.92 -1 -1 -1 -1 6.39
36 (21, 28] (-0.5, -0.45] 1 0.11 nan 0.11 0.11 0.11 0.11 0.11
37 (21, 28] (-0.45, -0.4] 21 0.15 0.03 0.11 0.12 0.15 0.17 0.23
38 (21, 28] (-0.4, -0.35] 39 0.2 0.06 0.12 0.16 0.18 0.24 0.32
39 (21, 28] (-0.35, -0.3] 61 0.21 0.06 0.13 0.17 0.2 0.26 0.35
40 (21, 28] (-0.3, -0.25] 75 0.25 0.08 0.14 0.2 0.24 0.31 0.41
41 (21, 28] (-0.25, -0.2] 79 0.3 0.09 0.17 0.23 0.27 0.37 0.49
42 (21, 28] (-0.2, -0.15] 87 0.37 0.11 0.2 0.29 0.34 0.45 0.62
43 (21, 28] (-0.15, -0.1] 93 0.48 0.15 0.26 0.37 0.46 0.58 0.85
44 (21, 28] (-0.1, -0.05] 105 0.74 0.24 0.36 0.56 0.71 0.89 1.39
45 (21, 28] (-0.05, -0.0] 114 1.45 0.54 0.62 1.05 1.34 1.73 3.28
46 (21, 28] (-0.0, 0.05] 125 2.97 3.38 -1 1.29 2.58 4.21 17.15
47 (21, 28] (0.05, 0.1] 85 0.82 5.3 -1 -1 -1 -1 19.5
48 (28, 35] (-0.4, -0.35] 5 0.31 0.01 0.3 0.3 0.31 0.32 0.32
49 (28, 35] (-0.35, -0.3] 7 0.34 0.01 0.32 0.33 0.35 0.35 0.36
50 (28, 35] (-0.3, -0.25] 12 0.39 0.02 0.36 0.37 0.39 0.4 0.42
51 (28, 35] (-0.25, -0.2] 13 0.46 0.02 0.42 0.44 0.45 0.47 0.49
52 (28, 35] (-0.2, -0.15] 14 0.55 0.04 0.5 0.53 0.55 0.58 0.62
53 (28, 35] (-0.15, -0.1] 15 0.73 0.07 0.63 0.67 0.72 0.77 0.84
54 (28, 35] (-0.1, -0.05] 17 1.06 0.14 0.86 0.94 1.05 1.17 1.32
55 (28, 35] (-0.05, -0.0] 19 1.95 0.44 1.36 1.58 1.87 2.26 2.79
56 (28, 35] (-0.0, 0.05] 20 5.72 2.23 2.94 3.85 5.23 7.33 9.97
57 (28, 35] (0.05, 0.1] 21 3.53 5.47 -1 -1 -1 10.38 11.32

There are more customization options for Optopsy's strategy functions, consult the codebase/future documentation to see how it can be used to adjust the results, such as increasing/decreasing the intervals and other data to be returned.

optopsy's People

Contributors

codacy-badger avatar michaelchu avatar moue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

optopsy's Issues

running strategies/sample_spx_strategy.py sample failed issue

Hi Michael

after clone the code and run the test sample_spx_strategy.py failed, said that DO not get /data/SPX_2014_2018.pk file, where can we download the file

And I notice in the csv file, we've calculated the delta/gamma so on, but the downloaded data does't include that value, does it means we have to cal them from the org csv file to a new one like data.csv or data_full.csv ?

thanks

Planned work as mentioned in the README

Fantastic repo and currently the only repo that backtests stock derivatives.

Just a quick question, do you have any plans to work on the 3rd bullet point in the README under "Use cases for Optopsy": Run backtests on option strategies based on entry conditions generated from Optopsy (Planned)?

If not, what did you have in mind for that bullet point? I would imagine it includes being able to generate graphs and charts similar to that of other backtesting libraries to measure things like Annual return, sharpe and sortino ratio, max drawdown, etc.

Improvement idea

Hi Michael,

I've been testing your module for some time and came up with an improvement idea. Most of my actual strategies are tied to additional external data like VIX, stocks' earnings, etc.

Adding the ability to consider exogenous variables to the strategy will dramatically increase the efficiency and the value of your system.

It could be done by allowing custom columns in the initial dataframe:

 Column Name        Status
 ---------------------------
 option_symbol      Optional
 underlying_symbol  Required
  .....
 vega               Required
 rho                Optional 
 <custom column 1>  Optional 
 <custom column 2>  Optional
  .....
 <custom column n>  Optional

And initial filters to be like for example:

filters = {
        "start_date": datetime(2018, 1, 1),
        "end_date": datetime(2018, 12, 31),
        "entry_dte": (40, 47, 50),
        "leg1_delta": 0.30,
        "contract_size": 1,
        "expr_type": "SPXW",
		"custom column 1" : (20, 30, 40)
		"custom column 2" :  10
		.....
		"custom column n" :  <some conditions>
    }

If it could be implemented, then your module could be used to find patterns not only in historical option prices but also across a variety of financial instruments.

Additional entry/exit conditions

Great library and very well programmed!

To evaluate some strategies, especially selling spreads, it would be useful to have additional entry & exit conditions:

entry:

  • IV or IV/HV ratio: only enter when above a limit
  • use min/max limits on delta to choose short strike, instead of percent_otm (this would take volatility into account in setting the strike)

exit:

  • profit taker & stop loss percentages of option premium to exit: if spread decreased eg by X % vs received premium, then exit the position (take profit) or if spread increased by Y % vs received premium, then exit the position (stop loss)

Anything planned on including this?

argument issue in sample_spx_strategy.py issue

Hi Michael

Another issue I'm quite curious how to run the final strategies, It's ok to run all test in tests/integration, but when running the strategies/, for example sample_spx_strategy.py. I've downloaded the data and format them well

But the long_call can NOT run well, short call neither, said that

Traceback (most recent call last):
File "sample_spx_strategy.py", line 62, in
run_strategy()
File "sample_spx_strategy.py", line 57, in run_strategy
spreads = op.long_call(data, filters)
TypeError: long_call() takes 1 positional argument but 2 were given

Have checked all in option_strategies.py all have no dataframe as input, but actually we need it

So this part need a update ?

unable to import optopsy

@michaelchu unable to import optopsy
runfile('G:/Projects/python/options/opto/strategies/sample_strategy.py', wdir='G:/Projects/python/options/opto/strategies')
Traceback (most recent call last):

File "", line 1, in
runfile('G:/Projects/python/options/opto/strategies/sample_strategy.py', wdir='G:/Projects/python/options/opto/strategies')

File "C:\Users\kaushik\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 668, in runfile
execfile(filename, namespace)

File "C:\Users\kaushik\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "G:/Projects/python/options/opto/strategies/sample_strategy.py", line 1, in
import optopsy as op

ModuleNotFoundError: No module named 'optopsy'

image

Still active?

Hello Michael

Thanks for creating this project. This one comes nearest to my backtesting requirements (mainly want to backtest straddles & strangles), but I wonder if this project is still active and any plans of the release 2.0 that you mentioned here?

Best Regards
Dharma

TypeError: long_call_spread() missing 2 required positional arguments: 'end' and 'filters'

Hey,

when running the sample code as is with the dataset you provided I get this error

File "strategies/sample_strat.py", line 27, in run_strategy
return op.option_strategies.long_call_spread(data, filters)
TypeError: long_call_spread() missing 2 required positional arguments: 'end' and 'filters'

Any idea what went wrong? I don´t see where long_call_spread() takes end as argument..
Thank you!

SPX singles examples generates empty output

I updated the script to point to './data/sample_spx_data.csv' since './data/Sample_SPX_20151001_to_20151030.csv' doesn't exist.

Then I ran it and it gave me the following empty output.

python3 spx_singles_example.py

Statistics for SPX long calls from 2015-10-01 to 2015-10-30

| index   | count   | mean   | std   | min   | 25%   | 50%   | 75%   | max   |
|---------|---------|--------|-------|-------|-------|-------|-------|-------|
Program Executed in 0.0

How to inject custom entry/exit dates?

Hi Michael,

First off, thank you for sharing your work on this package. It's the only one out there that I've seen dedicated to backtesting options strategies.

I'm curious how I can backtest strategies with my own entry/exit dates. In your wiki, you say "but theoretically, it is possible by injecting a list of entry and exit dates created from external sources based on indicators." After poking around in the code, I struggled to see where to do this and figured asking you might be faster.

Can you point me in the right direction? Thanks

Branch code-rewrite throws Error (Missing optopsy.orders module)

Hey

I would love to help developing this module.
What is the current status?

ModuleNotFoundError Traceback (most recent call last)
in
----> 1 import optopsy as op

/opt/notebooks/options/optopsy/init.py in
----> 1 from .api.strategy import Strategy
2 from .backtest import Backtest

/opt/notebooks/options/optopsy/api/strategy.py in
1 import logging
2
----> 3 from optopsy.api.order_filter import OrderFilter
4
5

/opt/notebooks/options/optopsy/api/order_filter.py in
2 from optopsy.api.order_size import OrderSize
3 from optopsy.api.order_filter_scope import OrderFilterScope
----> 4 from optopsy.api.order_filter_scope2 import OrderFilterScope2
5 from optopsy.api.order_filter_scope3 import OrderFilterScope3
6 from optopsy.api.order_filter_scope4 import OrderFilterScope4

/opt/notebooks/options/optopsy/api/order_filter_scope2.py in
----> 1 from optopsy.orders.order_filters.order_filter_scope import OrderFilterScope
2
3
4 class OrderFilterScope2(OrderFilterScope):
5 def init(self,

ModuleNotFoundError: No module named 'optopsy.orders'

Parameters selection

Hi Michael,
First of all, thank you for sharing your project with the community.
I've done a few tests over your code and find out that for a single leg spread (short put for example), your algorithm requires "leg1_delta" to be specified.
in optopsy/checks.py:

def singles_checks(f):
    return "leg1_delta" in f and _date_check(f) and _type_check(f)

Why you chose this parameter to be mandatory and is it possible to run a backtest without "leg1_delta" parameter?
Thanks!

long_call() takes 1 positional argument but 2 were given

Hi Michael,
I was working with version #23 of your package. After the update to #32 I start receiving the following error when running the strategy:

TypeError: long_call() takes 1 positional argument but 2 were given

According to your example from 'strategies/sample_spx_strategy.py' next code is using from api call to optopsy module:
spreads = op.long_call(data, filters)

I chected out optopsy/option_strategies.py and it seems to secive only one argument:

def long_call(leg):
    return _create_strategy([leg], singles_checks, [(OptionType.CALL, 1)])

Is there any changes in API that wasn't reflected in the example file 'strategies/sample_spx_strategy.py' or I'm doing something wrong?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.