torreyleonard / algotrader

Simple algorithmic stock and option trading for Node.js.

Home Page:https://www.npmjs.com/package/algotrader

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Trading RH options with stop loss

aashidham opened this issue · comments

commented

Thanks for digging out the API for RH options trading! I can place a limit order to buy options algorithmically. However I was hoping you could provide an example to add a stop loss to my options order. I think it can be enabled by adding to the legs option here:

https://github.com/Ladinn/algotrader/blob/a111eaafd8c85a51e952734429a41d5ba87dd7a6/objects/broker/robinhood/OptionOrder.js#L39

Here is an example of how I can buy qty contracts of instrument x under account a for ask price p:

{
"quantity":qty,
"direction":"debit",
"type":"limit",
"price": p,
"account":a,
"time_in_force":"gfd",
"trigger":"immediate",
"legs":
[
      {"side":"buy","option":instrument,"position_effect":"open","ratio_quantity":"1"}
],
"override_day_trade_checks":False,
"override_dtbp_checks":False, 
"ref_id":ref_id}

How would I amend to this JSON statement to add a stop loss at price q, where q < p?

Thanks for bringing this up! It's been a while since I worked on the options API, but I forgot to fully integrate the ability to add limit/stop orders. As of now, I think only limit orders are accepted by Robinhood when trading options, but I could be wrong.

It looks like I worked on this at one point, but I'll keep looking at this along with #10 to try and complete the options API.

commented

I don't think "legs" has to do with stop losses or anything. More likely (I'm guessing, but it makes much more sense to me) is it refers to the "legs" of a multi-option strategy, such as a spread or iron condor, etc.

If stop losses/limits etc are possible with options through the API, that's amazing and would be best. Barring that, a goal of mine is to write code to "fake" all my desired advanced orders ... things like trailing stops, bracket orders, stop losses on options, etc. Just fake it by listening to the quotes and triggering a buy or sell if it meets my conditions.

Closing this for now as it seems like stop loss orders aren't possible through Robinhood as of now. If any new information is found regarding this I can take a second look.

commented

@aashidham
I'm trying to place option order using Python api (see jmfernandes/robin_stocks#7). Could you post an example payload? I'm trying to figure out what ref_id is.
Thanks!

@briansp2020

Happy to help as much as I can,

Submitting a new option order returns the same response as fetching your past orders, so this will look similar to your new order requests. I'm assuming that id and ref_id are used to uniquely identify option orders within Robinhood's database, but I'm not sure where the difference between the two lies.

commented

@Ladinn
Thanks for your help. I tried to place an option order but was not successful. I'm new to javascript so I'm sure I did something wrong. Could you take a look at the code below and let me know what I'm doing wrong?

myUser.authenticate()
.then(() => {
// User was authenticated

// First, we'll get the instrument and tradable expiration dates for SPY.
Instrument.getBySymbol("SPY").then(ins => {
    OptionInstrument.getExpirations(myUser, ins).then(option => {
        // Next, we'll fetch an option chain for the upcoming expiration date.
    	OptionInstrument.getChain(myUser, ins, option[0], "put").then(optionChain => {
                console.log(optionChain[4]);

    	    // An array of OptionInstruments will be returned. See the example below.
	    // You'll then want to find the specific OptionInstrument that you want to trade.
	    // In this example, we'll buy using the first element in the array.
	    let order = new OptionOrder(null, myUser, optionChain[4], "credit", "gtc", "buy", "market", 1);
	    order.submit().then(res => {
    	        // Order was submitted, the response will be parsed as a completed OptionOrder.
		console.log("Order submitted");
		console.log(res);
		});
	    })
	})
    });
})
.catch(error => {
	// Either the request failed, or Robinhood responded with an error.
    // (Ex: you don't have internet access or your user credentials were incorrect)
})

I get the following error message

OptionInstrument {
  url: 'https://api.robinhood.com',
  tradability: 'tradable',
  strikePrice: 260,
  state: 'active',
  type: 'put',
  symbol: 'SPY',
  minTicks: { cutoff_price: '0.00', below_tick: '0.01', above_tick: '0.01' },
  instrumentURL: 'https://api.robinhood.com/options/instruments/487f72f2-b797-4016-8ff7-8dd172029808/',
  ids: 
   { chain: 'c277b118-58d9-4060-8dc5-a3b5898955cb',
     option: '487f72f2-b797-4016-8ff7-8dd172029808' },
  dates: 
   { expiration: 2019-03-04T00:00:00.000Z,
     created: 2019-01-25T03:08:09.376Z,
     updated: 2019-01-25T03:08:09.376Z } }
(node:25477) UnhandledPromiseRejectionWarning: Error: Robinhood responded with code 500 | <h1>Server Error (500)</h1>

> Please report all unexpected errors on GitHub: https://git.io/vpYYL

    at Function.handleResponse (/home/briansp/node_modules/algotrader/objects/broker/robinhood/Robinhood.js:23:11)
    at Request.request.post [as _callback] (/home/briansp/node_modules/algotrader/objects/broker/robinhood/OptionOrder.js:98:22)
    at Request.self.callback (/home/briansp/node_modules/request/request.js:185:22)
    at emitTwo (events.js:126:13)
    at Request.emit (events.js:214:7)
    at Request.<anonymous> (/home/briansp/node_modules/request/request.js:1161:10)
    at emitOne (events.js:116:13)
    at Request.emit (events.js:211:7)
    at IncomingMessage.<anonymous> (/home/briansp/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:313:30)
(node:25477) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:25477) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Server error 500 is the same error message I'm getting from the python api. If I change "gtc" to "GTC" as shown in the example in readme, I get 400 error along with the following error message.

(node:25697) UnhandledPromiseRejectionWarning: Error: Robinhood responded with code 400.

{
  "time_in_force": [
    "\"GTC\" is not a valid choice."
  ]
}

Any ideas? I'd like to get the option order placement working using this API before trying to get the python API working. Any help would be appreciated.

Thanks!

I'm getting the same error. Thanks for letting me know- it looks like they must have changed something since this was working when I last tested it.

Opening a new issue and troubleshooting this today.

commented

This worked for me. Everything is correct. All you have to do is dump string in the payload using: data=json.dumps(payload)

session.post("https://api.robinhood.com/options/orders/", data=json.dumps(payload), timeout=15)

My payload is:
payload = {"account" : account_url,
"direction" : "debit",
"time_in_force" : "gtc",
"legs" : [{'position_effect' : 'open', 'side' : 'buy', 'ratio_quantity' : 1, 'option': iurl}],
"type" : "limit",
"trigger" : "immediate",
"price" : float(price),
"quantity" : int(count),
"override_day_trade_checks" : False,
"override_dtbp_checks" : False,
'ref_id' : str(uuid.uuid4())}