Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option base model #224

Open
wants to merge 68 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
ddc830b
create a model for an option instrument
jeffweng8 Apr 14, 2020
6bb7c2c
add options arg for endpoints, refactor get_instruments
jeffweng8 Apr 14, 2020
a1a2c47
streamline instrument getter functions
jeffweng8 Apr 14, 2020
97d965a
add popularity endpoint
jeffweng8 Apr 14, 2020
4c62b0a
remove deprecated
jeffweng8 Apr 15, 2020
b4b5f7d
add some basic unit tests for option
jeffweng8 Apr 15, 2020
0953fad
and news/docs
jeffweng8 Apr 15, 2020
4ab33a9
fix typos, requested changes
jeffweng8 Apr 15, 2020
cf6653e
fix indentation
jeffweng8 Apr 15, 2020
8be08b3
fix indentation
jeffweng8 Apr 15, 2020
b8d42ef
fix bugs, style
jeffweng8 Apr 15, 2020
346bc61
update known_third_party
jeffweng8 Apr 15, 2020
b6eae0c
fix OptionSchema init
jeffweng8 Apr 15, 2020
87909ae
fix formatting of data in option
jeffweng8 Apr 15, 2020
0facead
fix order of isinstance args
jeffweng8 Apr 15, 2020
c5538b0
fix attr name
jeffweng8 Apr 15, 2020
5e130c1
fix option model, tests
jeffweng8 Apr 18, 2020
2075429
remove redundant code
jeffweng8 Apr 18, 2020
cae9060
create a model for an option instrument
jeffweng8 Apr 14, 2020
dec0d73
streamline instrument getter functions
jeffweng8 Apr 14, 2020
b0b55fa
remove deprecated
jeffweng8 Apr 15, 2020
109ef49
add some basic unit tests for option
jeffweng8 Apr 15, 2020
fd583ef
and news/docs
jeffweng8 Apr 15, 2020
fa8d01f
fix typos, requested changes
jeffweng8 Apr 15, 2020
0e14bb2
fix indentation
jeffweng8 Apr 15, 2020
508a57d
fix indentation
jeffweng8 Apr 15, 2020
556fc99
fix bugs, style
jeffweng8 Apr 15, 2020
bea0f9d
update known_third_party
jeffweng8 Apr 15, 2020
24294c8
fix OptionSchema init
jeffweng8 Apr 15, 2020
18017fd
fix formatting of data in option
jeffweng8 Apr 15, 2020
f4e9044
fix order of isinstance args
jeffweng8 Apr 15, 2020
2c391de
fix attr name
jeffweng8 Apr 15, 2020
30898f4
fix option model, tests
jeffweng8 Apr 18, 2020
41313cd
remove redundant code
jeffweng8 Apr 18, 2020
229bce4
fix conflicts
jeffweng8 Apr 18, 2020
a632053
update endpoints to urls
jeffweng8 Apr 18, 2020
477bada
Merge branch 'master' into add_options_endpoints
jeffweng8 Apr 18, 2020
57d5e3f
create a model for an option instrument
jeffweng8 Apr 14, 2020
f39b124
add some basic unit tests for option
jeffweng8 Apr 15, 2020
802ab14
and news/docs
jeffweng8 Apr 15, 2020
01dedf0
fix typos, requested changes
jeffweng8 Apr 15, 2020
f1e4445
fix indentation
jeffweng8 Apr 15, 2020
8167931
fix indentation
jeffweng8 Apr 15, 2020
a78dd19
fix bugs, style
jeffweng8 Apr 15, 2020
845575c
update known_third_party
jeffweng8 Apr 15, 2020
fca8680
fix OptionSchema init
jeffweng8 Apr 15, 2020
5f94094
fix formatting of data in option
jeffweng8 Apr 15, 2020
ce4eb1b
fix order of isinstance args
jeffweng8 Apr 15, 2020
036b83b
fix attr name
jeffweng8 Apr 15, 2020
4e85da5
fix option model, tests
jeffweng8 Apr 18, 2020
3d1e943
remove redundant code
jeffweng8 Apr 18, 2020
44b7ee8
streamline instrument getter functions
jeffweng8 Apr 14, 2020
ea75509
remove deprecated
jeffweng8 Apr 15, 2020
734b2ac
fix indentation
jeffweng8 Apr 15, 2020
d42ba4f
fix indentation
jeffweng8 Apr 15, 2020
93641bd
fix bugs, style
jeffweng8 Apr 15, 2020
50a019e
fix option model, tests
jeffweng8 Apr 18, 2020
ea407fe
remove redundant code
jeffweng8 Apr 18, 2020
91a37b0
update endpoints to urls
jeffweng8 Apr 18, 2020
e6e88ea
fix merge conflicts
jeffweng8 Apr 20, 2020
99bc47f
Merge branch 'add_options_endpoints' of https://github.com/jeffweng8/…
jeffweng8 Apr 20, 2020
1cc267f
fix merge conflicts
jeffweng8 Apr 20, 2020
40dcae9
fix merge conflicts
jeffweng8 Apr 20, 2020
3f0185a
add chain model, basic tests
jeffweng8 Apr 21, 2020
9287b4f
Add option manager, paginator
jeffweng8 Apr 26, 2020
3c0d61d
add repr for option model
jeffweng8 May 3, 2020
1372cb4
merge from master, get_option_positions using model
jeffweng8 May 4, 2020
efcc31b
get option quote using model, update news
jeffweng8 May 4, 2020
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
28 changes: 13 additions & 15 deletions pyrh/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,13 @@ def edocuments():
return API_BASE.with_path("/documents/")


def instruments(instrument_id=None, option=None):
def instruments(options=False):
"""
Return information about a specific instrument by providing its instrument id.
Add extra options for additional information such as "popularity"
"""
url = API_BASE.with_path(f"/instruments/")
if instrument_id is not None:
url += f"{instrument_id}"
if option is not None:
url += f"{option}"

return url
opt = "/options" if options else ""
return API_BASE.with_path(f"{opt}/instruments/")


def margin_upgrades():
Expand All @@ -63,9 +58,9 @@ def notifications():
return API_BASE.with_path("/notifications/")


def orders(order_id=""):
return API_BASE.with_path(f"/orders/{order_id}/")

def orders(order_id="", options=False):
opt = "/options" if options else ""
return base.with_path(f"{opt}/orders/{order_id}/")

def password_reset():
return API_BASE.with_path("/password_reset/request/")
Expand All @@ -75,16 +70,19 @@ def portfolios():
return API_BASE.with_path("/portfolios/")


def positions():
return API_BASE.with_path("/positions/")
def positions(options=False):
opt = "/options" if options else ""
return API_BASE.with_path("{opt}/positions/")


def quotes():
return API_BASE.with_path("/quotes/")


def historicals():
return API_BASE.with_path("/quotes/historicals/")
def historicals(options=False):
if options:
return API_BASE.with_path(f"/marketdata/options/historicals/")
return API_BASE.with_path(f"/quotes/historicals/")


def document_requests():
Expand Down
80 changes: 80 additions & 0 deletions pyrh/models/option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""Current portfolio."""

from typing import Any

from marshmallow import fields, post_load

from pyrh.common import JSON

from .base import BaseModel, BaseSchema


class Option(BaseModel):
"""Robinhood Option data class. Represents an options instrument"""

pass


class OptionSchema(BaseSchema):
"""Robinhood Option schema data loader.
Sample result payload from
{
jeffweng8 marked this conversation as resolved.
Show resolved Hide resolved
"chain_id": "cee01a93-626e-4ee6-9b04-60e2fd1392d1",
"chain_symbol": "AAPL",
"created_at": "2020-03-31T01:27:43.249339Z",
"expiration_date": "2020-04-17",
"id": "f098f169-74f9-4b91-b955-6834e1b67a12",
"issue_date": "2004-11-29",
"min_ticks": {
"above_tick": "0.05",
"below_tick": "0.01",
"cutoff_price": "3.00"
},
"rhs_tradability": "untradable",
"state": "active",
"strike_price": "232.5000",
"tradability": "tradable",
"type": "put",
"updated_at": "2020-03-31T01:27:43.249354Z",
"url": "https://api.robinhood.com/options/instruments/f098f169-74f9-4b91-b955-6834e1b67a12/"
}
"""

__model__ = Options

chain_id = fields.String()
chain_symbol = fields.String()
created_at = fields.NaiveDateTime()
expiration_date = fields.Date()
options_id = fields.String()
issue_date = fields.Date()
min_ticks = fields.Dict()
rhs_tradability = fields.String()
state = fields.String()
strike_price = fields.Float()
tradability = fields.String()
options_type = fields.String()
updated_at = fields.NaiveDateTime()
url = fields.URL()

@post_load
def make_object(self, data: JSON, **kwargs: Any) -> Option:
"""Build model for the Option class.

Args:
data: The JSON diction to use to build the Option.
**kwargs: Unused but required to match signature of `Schema.make_object`

Returns:
An instance of the Option class.

"""
# Can potentially move this preprocessing part to a helper file
prefix = self.__class__.__name__.lower()
reserved_word_overwrite = ["type", "id"]
for attr in reserved_word_overwrite:
k, v = f"{prefix}_{attr}", data.pop("attr")
data[k] = v
jeffweng8 marked this conversation as resolved.
Show resolved Hide resolved

data = data.get("results", [{}])[0]
return self.__model__(**data)
22 changes: 22 additions & 0 deletions pyrh/robinhood.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ def investment_profile(self):
"""Fetch investment_profile."""
return self.get(endpoints.investment_profile())

def get_instruments(self, symbol, match=True, options=False):
"""Query for instruments that match with the given ticker.

Args:
symbol (str): stock ticker
jeffweng8 marked this conversation as resolved.
Show resolved Hide resolved
match (bool): True if want exact match, False for partial match

Returns:
(:obj: (list)): JSON contents from `instruments` endpoint - list
of instruments that match the ticker
"""
ticker = stock.upper()
params = {"symbol": ticker} if match else {"query": ticker}
res = self.get(endpoints.instruments(options=options), params=params)
results = res.get("results", [])
while res.get("next"):
res = res.get("next")
results.extend(res.get("results", []))
return results

@deprecated
jeffweng8 marked this conversation as resolved.
Show resolved Hide resolved
def instruments(self, stock):
"""Fetch instruments endpoint.

Expand All @@ -67,6 +88,7 @@ def instruments(self, stock):

return res["results"]

@deprecated
jeffweng8 marked this conversation as resolved.
Show resolved Hide resolved
def instrument(self, id):
"""Fetch instrument info.

Expand Down