Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Add option strategy generator #5

Merged
merged 3 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ jobs:
run: |
source venv/bin/activate
mypy optionsmonkey/ --ignore-missing-imports
black . --check --diff --color
pytest
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ For options, the dictionary should contain up to 7 keys:

Either "buy" or "sell". It is mandatory.

- "prevpos" : float
- "prev_pos" : float

Premium effectively paid or received in a previously opened position. If positive, it means that the position remains open and the payoff calculation takes this price into account, not the current price of the option. If negative, it means that the position is closed and the difference between this price and the current price is considered in the payoff calculation.

Expand All @@ -174,7 +174,7 @@ For stocks, the dictionary should contain up to 4 keys:

Either "buy" or "sell". It is mandatory.

- "prevpos" : float
- "prev_pos" : float

Stock price effectively paid or received in a previously opened position. If positive, it means that the position remains open and the payoff calculation takes this price into account, not thecurrent price of the stock. If negative, it means that the position is closed and the difference between this price and the current price is considered in the payoff calculation.

Expand All @@ -188,7 +188,7 @@ For a non-determined previously opened position to be closed, which might consis

It must be "closed". It is mandatory.

- "prevpos" : float
- "prev_pos" : float

The total value of the position to be closed, which can be positive if it made a profit or negative if it is a loss. It is mandatory.

Expand Down
110 changes: 110 additions & 0 deletions examples/.ipynb_checkpoints/strategies-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"cells": [
{
"cell_type": "code",
"outputs": [
{
"data": {
"text/plain": "{'language': 'en-US',\n 'region': 'US',\n 'quoteType': 'EQUITY',\n 'typeDisp': 'Equity',\n 'quoteSourceName': 'Delayed Quote',\n 'triggerable': True,\n 'customPriceAlertConfidence': 'HIGH',\n 'currency': 'USD',\n 'marketState': 'CLOSED',\n 'regularMarketChangePercent': -0.6149154,\n 'regularMarketPrice': 404.06,\n 'exchange': 'NMS',\n 'shortName': 'Microsoft Corporation',\n 'longName': 'Microsoft Corporation',\n 'messageBoardId': 'finmb_21835',\n 'exchangeTimezoneName': 'America/New_York',\n 'exchangeTimezoneShortName': 'EST',\n 'gmtOffSetMilliseconds': -18000000,\n 'market': 'us_market',\n 'esgPopulated': False,\n 'firstTradeDateMilliseconds': 511108200000,\n 'priceHint': 2,\n 'postMarketChangePercent': -0.17571436,\n 'postMarketTime': 1708131600,\n 'postMarketPrice': 403.35,\n 'postMarketChange': -0.70999146,\n 'regularMarketChange': -2.5,\n 'regularMarketTime': 1708117201,\n 'regularMarketDayHigh': 408.27,\n 'regularMarketDayRange': '403.53 - 408.27',\n 'regularMarketDayLow': 403.53,\n 'regularMarketVolume': 22296495,\n 'regularMarketPreviousClose': 406.56,\n 'bid': 403.2,\n 'ask': 403.5,\n 'bidSize': 10,\n 'askSize': 9,\n 'fullExchangeName': 'NasdaqGS',\n 'financialCurrency': 'USD',\n 'regularMarketOpen': 407.96,\n 'averageDailyVolume3Month': 25389093,\n 'averageDailyVolume10Day': 22286910,\n 'fiftyTwoWeekLowChange': 158.45,\n 'fiftyTwoWeekLowChangePercent': 0.6451284,\n 'fiftyTwoWeekRange': '245.61 - 420.82',\n 'fiftyTwoWeekHighChange': -16.76001,\n 'fiftyTwoWeekHighChangePercent': -0.039827026,\n 'fiftyTwoWeekLow': 245.61,\n 'fiftyTwoWeekHigh': 420.82,\n 'fiftyTwoWeekChangePercent': 59.916092,\n 'dividendDate': 1710374400,\n 'earningsTimestamp': 1706653800,\n 'earningsTimestampStart': 1713869940,\n 'earningsTimestampEnd': 1714392000,\n 'trailingAnnualDividendRate': 2.86,\n 'trailingPE': 36.500454,\n 'dividendRate': 3.0,\n 'trailingAnnualDividendYield': 0.007034632,\n 'dividendYield': 0.74,\n 'epsTrailingTwelveMonths': 11.07,\n 'epsForward': 12.38,\n 'epsCurrentYear': 10.81,\n 'priceEpsCurrentYear': 37.378353,\n 'sharesOutstanding': 7430439936,\n 'bookValue': 32.06,\n 'fiftyDayAverage': 388.6076,\n 'fiftyDayAverageChange': 15.452393,\n 'fiftyDayAverageChangePercent': 0.039763484,\n 'twoHundredDayAverage': 348.3632,\n 'twoHundredDayAverageChange': 55.696808,\n 'twoHundredDayAverageChangePercent': 0.15988144,\n 'marketCap': 3002343620608,\n 'forwardPE': 32.638126,\n 'priceToBook': 12.603243,\n 'sourceInterval': 15,\n 'exchangeDataDelayedBy': 0,\n 'averageAnalystRating': '1.7 - Buy',\n 'tradeable': False,\n 'cryptoTradeable': False,\n 'displayName': 'Microsoft',\n 'symbol': 'MSFT'}"
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from optionsmonkey.api import get_options_chain\n",
"from optionsmonkey.utils import get_fridays_date\n",
"from optionsmonkey.strategies import generate_strategies\n",
"\n",
"\n",
"friday_in_3_weeks = get_fridays_date(weeks_until=3)\n",
"options = get_options_chain('MSFT', friday_in_3_weeks)\n",
"options.underlying"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-02-18T21:51:38.193175Z",
"start_time": "2024-02-18T21:51:37.970843Z"
}
},
"id": "83463b241c45c82b",
"execution_count": 7
},
{
"cell_type": "code",
"outputs": [
{
"ename": "AttributeError",
"evalue": "'dict' object has no attribute 'regular_market_price'",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[6], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m strike \u001B[38;5;241m=\u001B[39m \u001B[43moptions\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43munderlying\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mregular_market_price\u001B[49m \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m10\u001B[39m\n\u001B[1;32m 2\u001B[0m strike\n",
"\u001B[0;31mAttributeError\u001B[0m: 'dict' object has no attribute 'regular_market_price'"
]
}
],
"source": [
"strike = options.underlying.regular_market_price + 10\n",
"strike"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-02-18T21:51:16.365671Z",
"start_time": "2024-02-18T21:51:16.358319Z"
}
},
"id": "9ff9d78568685850",
"execution_count": 6
},
{
"cell_type": "markdown",
"source": [
"# covered call"
],
"metadata": {
"collapsed": false
},
"id": "7af69ff8acb39e1e"
},
{
"cell_type": "code",
"outputs": [],
"source": [
"\n",
"\n",
"strategy = generate_strategies('covered-call', )"
],
"metadata": {
"collapsed": true
},
"id": "initial_id",
"execution_count": 0
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
4 changes: 2 additions & 2 deletions examples/call_spread.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
}
],
"source": [
"s,pl_total=st.getPL()\n",
"s,pl_total=st.get_pl()\n",
"zeroline=zeros(s.shape[0])\n",
"plt.xlabel(\"Stock price\")\n",
"plt.ylabel(\"Profit/Loss\")\n",
Expand Down Expand Up @@ -381,7 +381,7 @@
}
],
"source": [
"s,pl_total=st.getPL()\n",
"s,pl_total=st.get_pl()\n",
"zeroline=zeros(s.shape[0])\n",
"plt.xlabel(\"Stock price\")\n",
"plt.ylabel(\"Profit/Loss\")\n",
Expand Down
6 changes: 3 additions & 3 deletions examples/covered_call.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Profit/loss profiles for each leg and the overall strategy are obtained by calling the *getPL()* method and plotted at the option's maturity."
"Profit/loss profiles for each leg and the overall strategy are obtained by calling the *get_pl()* method and plotted at the option's maturity."
]
},
{
Expand Down Expand Up @@ -145,11 +145,11 @@
}
],
"source": [
"s,pl_total=st.getPL()\n",
"s,pl_total=st.get_pl()\n",
"leg=[]\n",
"\n",
"for i in range(len(strategy)):\n",
" leg.append(st.getPL(i)[1])\n",
" leg.append(st.get_pl(i)[1])\n",
" \n",
"zeroline=zeros(s.shape[0])\n",
"plt.xlabel(\"Stock price\")\n",
Expand Down
159 changes: 159 additions & 0 deletions examples/strategies.ipynb

Large diffs are not rendered by default.

9 changes: 1 addition & 8 deletions optionsmonkey/api.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import datetime as dt
from dataclasses import dataclass
from typing import Any

import pandas as pd
from yfinance import Ticker


@dataclass
class OptionsChain:
calls: pd.DataFrame
puts: pd.DataFrame
underlying: dict[str, Any] # TODO: pydantic model
from optionsmonkey.models import OptionsChain


def get_options_chain(ticker: str, expiration_date: dt.date) -> OptionsChain:
Expand Down
Loading
Loading