Skip to content

Instantly share code, notes, and snippets.

@Jamonek
Created April 17, 2018 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jamonek/91753b8c919fe7c9ce1c2401881fbdfa to your computer and use it in GitHub Desktop.
Save Jamonek/91753b8c919fe7c9ce1c2401881fbdfa to your computer and use it in GitHub Desktop.
Robinhood merge conflicts
<<<<<<< master
##############################
#GET OPEN ORDER(S)
##############################
def get_open_orders(self):
"""
Returns all currently open (cancellable) orders.
If not orders are currently open, `None` is returned.
TODO: Is there a way to get these from the API endpoint without stepping through order history?
"""
open_orders = []
orders = self.order_history()
for order in orders['results']:
if(order['cancel'] is not None):
open_orders.append(order)
print(type(order))
if len(open_orders) > 0:
return open_orders
##############################
#CANCEL ORDER(S)
##############################
def cancel_order(
self,
order_id
):
"""
Cancels specified order and returns the response (results from `orders` command).
If order cannot be cancelled, `None` is returned.
Args:
order_id (str): Order ID that is to be cancelled or order dict returned from
order get.
"""
if order_id is str:
try:
order = self.session.get(self.endpoints['orders'] + order_id).json()
except (requests.exceptions.HTTPError) as err_msg:
raise ValueError('Invalid order id: ' + order_id)
if order.get('cancel') is not None:
try:
req = self.session.post(order['cancel'])
req.raise_for_status()
#TODO: confirm that the order has been dropped
except (requests.exceptions.HTTPError) as err_msg:
raise ValueError('Failed to cancel order ID: ' + order_id
+ '\n Error message: '+ repr(err_msg))
return None
# no cancel link - order type cannot be cancelled
else:
raise ValueError('No cancel link - unable to cancel order ID: '+ order_id)
return order
def cancel_open_orders(self):
"""
Cancels all open orders and returns the responses from the canelled orders (results from `orders` command).
If no orders are open or no orders were cancelled (i.e. failed to cancel), returns `None`
"""
cancelled_orders = []
open_orders = self.get_open_orders()
# no open orders
if open_orders is None:
return None
for order in open_orders:
cancel_order(order['id'])
cancelled_orders.append(order)
return cancelled_orders
=======
# Methods below here are a complete rewrite for buying and selling
# These are new. Use at your own risk!
def place_market_buy_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
quantity = None):
"""Wrapper for placing market buy orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
quantity (int): Number of shares to buy
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'market',
trigger = 'immediate',
side = 'buy',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
quantity = quantity))
def place_limit_buy_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
price = None,
quantity = None):
"""Wrapper for placing limit buy orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
price (float): The max price you're willing to pay per share
quantity (int): Number of shares to buy
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'limit',
trigger = 'immediate',
side = 'buy',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
price = price,
quantity = quantity))
def place_stop_loss_buy_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
stop_price = None,
quantity = None):
"""Wrapper for placing stop loss buy orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
stop_price (float): The price at which this becomes a market order
quantity (int): Number of shares to buy
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'market',
trigger = 'stop',
side = 'buy',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
stop_price = stop_price,
quantity = quantity))
def place_stop_limit_buy_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
stop_price = None,
price = None,
quantity = None):
"""Wrapper for placing stop limit buy orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
stop_price (float): The price at which this becomes a limit order
price (float): The max price you're willing to pay per share
quantity (int): Number of shares to buy
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'limit',
trigger = 'stop',
side = 'buy',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
stop_price = stop_price,
price = price,
quantity = quantity))
def place_market_sell_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
quantity = None):
"""Wrapper for placing market sell orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
quantity (int): Number of shares to sell
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'market',
trigger = 'immediate',
side = 'sell',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
quantity= quantity))
def place_limit_sell_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
price = None,
quantity = None):
"""Wrapper for placing limit sell orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
price (float): The minimum price you're willing to get per share
quantity (int): Number of shares to sell
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'limit',
trigger = 'immediate',
side = 'sell',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
price = price,
quantity = quantity))
def place_stop_loss_sell_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
stop_price = None,
quantity = None):
"""Wrapper for placing stop loss sell orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
stop_price (float): The price at which this becomes a market order
quantity (int): Number of shares to sell
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'market',
trigger = 'stop',
side = 'sell',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
stop_price = stop_price,
quantity = quantity))
def place_stop_limit_sell_order(self,
instrument_URL = None,
symbol = None,
time_in_force = None,
price = None,
stop_price = None,
quantity = None):
"""Wrapper for placing stop limit sell orders
Notes:
If only one of the instrument_URL or symbol are passed as
arguments the other will be looked up automatically.
Args:
instrument_URL (str): The RH URL of the instrument
symbol (str): The ticker symbol of the instrument
time_in_force (str): 'GFD' or 'GTC' (day or until cancelled)
stop_price (float): The price at which this becomes a limit order
price (float): The max price you're willing to get per share
quantity (int): Number of shares to sell
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
return(self.submit_order(order_type = 'limit',
trigger = 'stop',
side = 'sell',
instrument_URL = instrument_URL,
symbol = symbol,
time_in_force = time_in_force,
stop_price = stop_price,
price = price,
quantity = quantity))
def submit_order(self,
instrument_URL = None,
symbol = None,
order_type = None,
time_in_force = None,
trigger = None,
price = None,
stop_price = None,
quantity = None,
side = None):
"""Submits order to Robinhood
Notes:
This is normally not called directly. Most programs should use
one of the following instead:
place_market_buy_order()
place_limit_buy_order()
place_stop_loss_buy_order()
place_stop_limit_buy_order()
place_market_sell_order()
place_limit_sell_order()
place_stop_loss_sell_order()
place_stop_limit_sell_order()
Args:
instrument_URL (str): the RH URL for the instrument
symbol (str): the ticker symbol for the instrument
order_type (str): 'MARKET' or 'LIMIT'
time_in_force (:enum:`TIME_IN_FORCE`): GFD or GTC (day or
until cancelled)
trigger (str): IMMEDIATE or STOP enum
price (float): The share price you'll accept
stop_price (float): The price at which the order becomes a
market or limit order
quantity (int): The number of shares to buy/sell
side (str): BUY or sell
Returns:
(:obj:`requests.request`): result from `orders` put command
"""
# Start with some parameter checks. I'm paranoid about $.
if(instrument_URL is None):
if(symbol is None):
raise(valueError('Neither instrument_URL nor symbol were passed to submit_order'))
instrument_URL = self.instruments(symbol)[0]['url']
if(symbol is None):
symbol = self.session.get(instrument_URL, timeout=15).json()['symbol']
if(side is None):
raise(valueError('Order is neither buy nor sell in call to submit_order'))
if(order_type == None):
if(price == None):
if(stop_price == None):
order_type = 'market'
else:
order_type = 'limit'
symbol = str(symbol).upper()
order_type = str(order_type).lower()
time_in_force = str(time_in_force).lower()
trigger = str(trigger).lower()
side = str(side).lower()
if(order_type != 'market') and (order_type != 'limit'):
raise(valueError('Invalid order_type in call to submit_order'))
if(order_type == 'limit'):
if(price is None):
raise(valueError('Limit order has no price in call to submit_order'))
if(price <= 0):
raise(valueError('Price must be positive number in call to submit_order'))
if(trigger == 'stop'):
if(stop_price is None):
raise(valueError('Stop order has no stop_price in call to submit_order'))
if(price <= 0):
raise(valueError('Stop_price must be positive number in call to submit_order'))
if(stop_price is not None):
if(trigger != 'stop'):
raise(valueError('Stop price set for non-stop order in call to submit_order'))
if(price is None):
if(order_type == 'limit'):
raise(valueError('Limit order has no price in call to submit_order'))
if(price is not None):
if(order_type.lower() == 'market'):
raise(valueError('Market order has price limit in call to submit_order'))
price = float(price)
if(quantity is None):
raise(valueError('No quantity specified in call to submit_order'))
quantity = int(quantity)
if(quantity <= 0):
raise(valueError('Quantity must be positive number in call to submit_order'))
payload = {}
for field,value in [('account',self.get_account()['url']),
('instrument',instrument_URL),
('symbol',symbol),
('type',order_type),
('time_in_force', time_in_force),
('trigger',trigger),
('price',price),
('stop_price',stop_price),
('quantity',quantity),
('side',side)]:
if(value is not None):
payload[field] = value
res = self.session.post(endpoints.orders(), data=payload, timeout=15)
res.raise_for_status()
return res
>>>>>>> master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment