Skip to content

Commit

Permalink
updating options display; adding popularity; listing stop loss orders…
Browse files Browse the repository at this point in the history
… correctly
  • Loading branch information
anilshanbhag committed Jul 1, 2018
1 parent 80cf1fc commit 25a0579
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
34 changes: 27 additions & 7 deletions Robinhood.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@ class Bounds(Enum):
REGULAR = 'regular'
EXTENDED = 'extended'


class Transaction(Enum):
"""enum for buy/sell orders"""
BUY = 'buy'
SELL = 'sell'


class Robinhood:
"""wrapper class for fetching/parsing Robinhood endpoints"""
endpoints = {
Expand All @@ -37,6 +35,7 @@ class Robinhood:
"dividends": "https://api.robinhood.com/dividends/",
"edocuments": "https://api.robinhood.com/documents/",
"instruments": "https://api.robinhood.com/instruments/",
"instruments_popularity": "https://api.robinhood.com/instruments/popularity/",
"margin_upgrades": "https://api.robinhood.com/margin/upgrades/",
"markets": "https://api.robinhood.com/markets/",
"notifications": "https://api.robinhood.com/notifications/",
Expand All @@ -51,6 +50,7 @@ class Robinhood:
"user": "https://api.robinhood.com/user/",
"watchlists": "https://api.robinhood.com/watchlists/",
"news": "https://api.robinhood.com/midlands/news/",
"ratings": "https://api.robinhood.com/midlands/ratings/",
"fundamentals": "https://api.robinhood.com/fundamentals/",
"options": "https://api.robinhood.com/options/",
"marketdata": "https://api.robinhood.com/marketdata/"
Expand Down Expand Up @@ -197,6 +197,26 @@ def instruments(self, stock):

return res['results']

def instruments_popularity(self, ids):
""" fetch instruments popularity endpoint
Args:
instruments (list): list of instrument ids
Returns:
(:obj:`dict`): JSON contents from `instruments_popularity` endpoint
"""
url = str(self.endpoints['instruments_popularity']) + "?ids=" + '%2C'.join(ids)
try:
req = requests.get(url)
req.raise_for_status()
data = req.json()
except requests.exceptions.HTTPError:
raise NameError('Invalid Instruments')

return data

def quote_data(self, stock=''):
"""fetch stock quote
Args:
Expand All @@ -206,9 +226,9 @@ def quote_data(self, stock=''):
"""
url = None
if stock.find(',') == -1:
url = str(self.endpoints['quotes']) + str(stock) + "/"
url = str(self.endpoints['quotes']) + str(stock.upper()) + "/"
else:
url = str(self.endpoints['quotes']) + "?symbols=" + str(stock)
url = str(self.endpoints['quotes']) + "?symbols=" + str(stock.upper())
#Check for validity of symbol
try:
req = requests.get(url)
Expand All @@ -228,13 +248,13 @@ def quotes_data(self, stocks):
(:obj:`list` of :obj:`dict`): List of JSON contents from `quotes` endpoint, in the
same order of input args. If any ticker is invalid, a None will occur at that position.
"""
url = str(self.endpoints['quotes']) + "?symbols=" + ",".join(stocks)
url = str(self.endpoints['quotes']) + "?symbols=" + ",".join(stocks).upper()
try:
req = requests.get(url)
req.raise_for_status()
data = req.json()
except requests.exceptions.HTTPError:
raise NameError('Invalid Symbols: ' + ",".join(stocks)) #TODO: custom exception
raise NameError('Invalid Symbols: ' + ",".join(stocks)).upper() #TODO: custom exception

return data["results"]

Expand All @@ -258,7 +278,7 @@ def append_stock(stock):
#Prompt for stock if not entered
if not stock: #pragma: no cover
stock = input("Symbol: ")
data = self.quote_data(stock)
data = self.quote_data(stock.upper())
res = []
# Handles the case of multple tickers
if stock.find(',') != -1:
Expand Down
18 changes: 13 additions & 5 deletions shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def do_l(self, arg):
# Load Options
option_positions = self.trader.options_owned()
table = BeautifulTable()
table.column_headers = ["symbol", "price", "quantity", "equity", "cost basis", "p/l", "type", "expiry"]
table.column_headers = ["option", "price", "quantity", "equity", "cost basis", "p/l"]

for op in option_positions:
quantity = float(op['quantity'])
Expand All @@ -111,17 +111,17 @@ def do_l(self, arg):
quantity = -quantity
cost = -cost

symbol = op['chain_symbol']
instrument = op['option']
option_data = self.trader.session.get(instrument).json()
expiration_date = option_data['expiration_date']
strike = float(option_data['strike_price'])
type = option_data['type']
symbol = op['chain_symbol'] + ' ' + expiration_date + ' ' + type + ' $' + str(strike)
info = self.trader.get_option_marketdata(instrument)
last_price = float(info['adjusted_mark_price'])
total_equity = (100 * last_price) * quantity
change = total_equity - (float(cost) * quantity)
table.append_row([symbol, last_price, quantity, total_equity, cost, change, type, expiration_date])
table.append_row([symbol, last_price, quantity, total_equity, cost, change])

print "Options:"
print(table)
Expand Down Expand Up @@ -243,12 +243,20 @@ def do_o(self, arg):

index = 1
for order in open_orders:

if order['trigger'] == 'stop':
order_price = order['stop_price']
order_type = "stop loss"
else:
order_price = order['price']
order_type = order['side']+" "+order['type']

table.append_row([
index,
self.get_symbol(order['instrument']),
order['price'],
order_price,
int(float(order['quantity'])),
order['side'],
order_type,
order['id'],
])
index += 1
Expand Down

0 comments on commit 25a0579

Please sign in to comment.