Created
April 17, 2018 18:50
-
-
Save Jamonek/91753b8c919fe7c9ce1c2401881fbdfa to your computer and use it in GitHub Desktop.
Robinhood merge conflicts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<<<<<<< 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