Closed briansp2020 closed 5 years ago
Unfortunately I haven't been able to make any progress on that. If you want to try to figure out how to buy and sell options, you can use the function in the helper.py file called 'request_post()'. It takes in a url and a payload. The documentation tells more about what the format looks like. But as long as you use the correct url and payload then the API can execute the command.
I'm pretty sure the url is https://api.robinhood.com/options/orders/ but I have no idea what the payload needs to be. I even used the developer tools on chrome to see what calls to the API were being made when placing orders for options on the robin hood website. As far as I can tell, I was inputing the same information as the website but it always failed.
Thank you for that information. Are you familiar with JavaScript? I found this code (https://github.com/Ladinn/algotrader/blob/master/objects/broker/robinhood/OptionOrder.js) which I think is code to build payload information for option order placement. I'll experiment a bit ans see if I can figure anything out. Also, if you can give me any code you use to experiment, that would be helpful.
Thanks!
That's awesome. Thanks for the link. I'm still getting a 500 interval server error. It looks like this is exactly what is in the Java. So idk if his code is wrong or mine. Here is a function I wrote.
def order_buy_option(symbol,quantity,expirationDate,strike,optionType,timeInForce='gtc'):
try:
symbol = symbol.upper().strip()
except AttributeError as message:
print(message)
return None
optionID = helper.id_for_option(symbol,expirationDate,strike,optionType)
payload = {
'account': profiles.load_account_profile(info='url'),
'direction': 'debit',
'time_in_force': timeInForce,
'legs': {'position_effect': 'open', 'side' : 'buy', 'ratio_quantity': 1, 'option': urls.option_instruments(optionID) },
'type': 'market',
'quantity': quantity
}
url = urls.option_orders()
data = helper.request_post(url,payload)
return(data)
Hi Joshua, I found someone who claims that he was able to place option order using the algotrader software. (see https://github.com/Ladinn/algotrader/issues/12) It seems that the had to send additional parameters on top of what you provided as well as passing 'ratio_quantity' value as string. However, I'm not sure what the ref_id value he is using is. Do you have any idea?
I'm not sure either. There is a chain id associated with options. maybe its that? Also I notice that they have the type be 'limit' instead of 'market'. Maybe that is an error as well? I don't think I have time this weekend to do any testing. Could you help me out with that?
in helper there is a function, id_for_chain and id_for_group. Use those to get ids and set one as the ref_id. If it doesn't work then try the other id. Also try setting the type to 'limit'. I don't think passing in ratio_quantity as an int instead of string would generate an error....I could be wrong though.
I tried
def order_buy_option_limit(symbol,quantity,expirationDate,strike,optionType,price,timeInForce='gfd'):
try:
symbol = symbol.upper().strip()
except AttributeError as message:
print(message)
return None
optionID = helper.id_for_option(symbol,expirationDate,strike,optionType)
payload = {
'account': profiles.load_account_profile(info='url'),
'direction': 'debit',
'time_in_force': timeInForce,
'legs': {'position_effect': 'open', 'side' : 'buy', 'ratio_quantity': '1', 'option': urls.option_instruments(optionID) },
'type': 'limit',
'price': float(price),
'trigger': 'immediate',
'override_day_trade_checks':False,
'override_dtbp_checks':False,
'quantity': quantity
}
print (payload)
url = urls.option_orders()
data = helper.request_post(url,payload)
return(data)
which sends
{'account': '...', 'direction': 'debit', 'time_in_force': 'gfd', 'legs': {'position_effect': 'open', 'side': 'buy', 'ratio_quantity': '1', 'option': 'https://api.robinhood.com/options/instruments/c6a86cbc-5373-4fb2-99b4-8a91bfae1ee4/'}, 'type': 'limit', 'price': 0.23, 'trigger': 'immediate', 'override_day_trade_checks': False, 'override_dtbp_checks': False, 'quantity': 1}
as payload but I still get error. I'll try using the id you mentioned.
Thanks
I tried
payload = {
'account': profiles.load_account_profile(info='url'),
'direction': 'debit',
'legs': {'position_effect': 'open', 'side' : 'buy', 'ratio_quantity': 1, 'option': urls.option_instruments(optionID) },
'price': float(price),
'time_in_force': timeInForce,
'trigger': 'immediate',
'type': 'limit',
'quantity': quantity,
'override_day_trade_checks': False,
'override_dtbp_checks': False,
'ref_id':str(uuid.uuid4())
}
and now I get 400 error. When I provided wrong value for an option order using algotrader, I was getting 400 error as well. So, I'm guessing the name of the fields are right but some of the values are wrong. Unfortunately, I can't get exact error messages from request_post. See https://github.com/Ladinn/algotrader/issues/12#issuecomment-457749773
yeah I tried
payload = {
"quantity":"1",
"direction":"debit",
"type":"limit",
"account":r.profiles.load_account_profile(info="url"),
"time_in_force":"gfd",
"trigger":"immediate",
"legs":[{"side":"buy","option":r.urls.option_instruments(optionID),"position_effect":"open","ratio_quantity":"1"}],
"override_day_trade_checks":"false",
"override_dtbp_checks":"false"}
and I'm getting the 500 error. and sometimes a 400 error as i play around with parameters. Can't find what I'm doing differently than the javascript code you linked.
I may have figured it out. I found a comment that the session info needs to be updated to
'Content-type': 'application/json; charset=utf-8',
in my code its
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
but then i think it needs to be set back to original after setting order for option?
EDIT: Nope. not working.
Hi @jmfernandes , @briansp2020 , Have any of you figured this out yet? Cheers
@m256 I used fast_arrow to make option trade. See https://github.com/westonplatter/fast_arrow for more info. Hope that helps.
@m256 I used fast_arrow to make option trade. See https://github.com/westonplatter/fast_arrow for more info. Hope that helps.
Thanks for sharing that @briansp2020 . I am still curious if you were able to figure out the payload details. I'm experimenting with a version in MATLAB and am using the exact same payload at @jmfernandes in https://github.com/jmfernandes/robin_stocks/issues/7#issuecomment-458419226 with an additional ref_id parameter. However, the order does not go through and I get a response with all existing orders. My payload looks like this:
'account', 'https://api.robinhood.com/accounts/',myAccountNumber,'/',... 'direction', 'debit',... 'legs', {"side":"buy","option":"https://api.robinhood.com/options/instruments/24881756-c18a-48ee-8251-37db1c538346/","position_effect":"open","ratio_quantity":"1"},... 'price', '0.11',... 'quantity', '1.0',... 'time_in_force', 'gfd',... 'trigger', 'immediate',... 'type', 'limit',... 'override_day_trade_checks', 'false',... 'override_dtbp_checks', 'false',... 'ref_id', char(java.util.UUID.randomUUID),...
The payload of option_order.py from https://github.com/westonplatter/fast_arrow also looks the same:
payload = json.dumps({ "account": client.account_url, "direction": direction, "legs": legs, "price": price, "quantity": quantity, "time_in_force": time_in_force, "trigger": trigger, "type": order_type, "override_day_trade_checks": False, "override_dtbp_checks": False, "ref_id": str(uuid.uuid4()) })
Just not able to figure out why the option orders are not going through and I'm getting a response with all my past option orders.
I think I got it working for an option limit buy based on your code @jmfernandes . May not be the cleanest possible solution because I had to change the request_post more than i would like, but it works and can be refactored: https://github.com/jmfernandes/robin_stocks/pull/35.
I tested using print(robin.order_buy_option_limit('0.01', 'FIT', 1, '2019-08-23', '3', 'call'))
If you and @briansp2020 could test my changes and verify it works, that'd be gr8.
@Jmarkaba yeah its unfortunate that you had to change request_post, but its fine. I need to refactor that function anyway, to get rid of the logic for logging in. All of that should be in the log in function. request_post should only post and be as "dumb" as possible. But I'll worry about that later.
I have a question, could you change the "direction" to "credit" and the "side" inside "legs" to "sell" and see if you can do a sell limit? And if so write up that function as well? Thanks a lot for help as always!
and yes I'll test the changes on my end
Yeah I'll work on abstracting the function and making it work for all cases. Also the request post should just return a status code, data tuple I think. Or maybe just data. I'll see what I can work out
What parameters did you use for stock, strike, etc.? I tried a few different options and I was getting an error, but I'll try again tomorrow during open trading hours
Edit. Nvm. I saw your post saying what you used.
Got it working for me, so i added documentation, added a function to sell options (short puts and short calls), added a function to cancel option orders, and merged it into master.
Buying and selling options is now supported.
Hi Fernandes for the option selling or buying I need to have updated all others functions inside that function?
I'd like to have ability to buy/sell options using this API. You mentioned that you are working on such capability https://github.com/jmfernandes/robin_stocks/issues/3. Are you close to getting it working? I'd like to help if you can give me pointers. Though I'm new to REST API and Robinhood API, I'm a software engineer so I think I can help if you want.
Also, thanks for great software!