jessecooper / pyetrade

Python E-Trade API Wrapper
GNU General Public License v3.0
205 stars 96 forks source link

Keep getting requests.exceptions.HTTPError: 400 Client Error: Bad Request for url when trying to place options order. #77

Open rockwoodquant opened 1 year ago

rockwoodquant commented 1 year ago

I am trying to send an options order using pyetrade and got bad url error. Other modules seem to work fine - e.g. market / accounts etc.

Can someone please help? I'm out of ideas now - thanks!

here is what I was trying to do:

-----------------code below----------------

  action = "BUY_OPEN"
  symbol = "SPX"
  callPut = "CALL"
  expiryDate = "2023-02-16"
  strikePrice = 4140
  quantity = 1
  limitPrice=0.25
  orderTerm = "GOOD_UNTIL_CANCEL"  # "IMMEDIATE_OR_CANCEL"  # "GOOD_FOR_DAY"
  marketSession = "REGULAR"
  priceType = "LIMIT"
  account_id = ACCOUNT_ID_KEY
  clientOrderId = "888"

  resp = orders.place_option_order(
        accountId = account_id,
        symbol = symbol,
        callPut=callPut,
        expiryDate=expiryDate,
        strikePrice=strikePrice,
        orderAction=action,
        clientOrderId=clientOrderId,
        priceType= priceType,
        limitPrice=limitPrice,
        allOrNone=False,
        quantity=quantity,
        orderTerm=orderTerm,
        marketSession=marketSession,
      )

------------end of code---------------

This gets the following error --

-----------start of error---------------

  File "<input>", line 15, in <module>
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\pyetrade\order.py", line 449, in place_option_order
    return self.place_equity_order(resp_format, **kwargs)
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\pyetrade\order.py", line 475, in place_equity_order
    preview = self.preview_equity_order(resp_format, **kwargs)
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\pyetrade\order.py", line 417, in preview_equity_order
    return self.perform_request(self.session.post, resp_format, api_url, payload)
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\pyetrade\order.py", line 302, in perform_request
    return get_request_result(req, resp_format, {})
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\pyetrade\order.py", line 49, in get_request_result
    req.raise_for_status()
  File "C:\Users\KeyUser\PycharmProjects\ETradeTrading\venv\lib\site-packages\requests\models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.etrade.com/v1/accounts/[...my account id key...]/orders/preview

------------end of error------------

Thanks in advance...

-RQ

rockwoodquant commented 1 year ago

I tried to use account_id instead of accountIdKey, i also tried to add in resp_type = "xml" in the function call. every time so far got to the same error...

xabaddonx1 commented 1 year ago

Same issue here.

edit I figured it out, the expiry date format needs to be month-day-year

rockwoodquant commented 1 year ago

@xabaddonx1 I tried your suggestion, same error...

xabaddonx1 commented 1 year ago

You must have another issue. I think the client order id needs to be unique for each order, i generate it with clientOrderId = dt.datetime.timestamp(presentDate) * 1000000 maybe that's it.

rockwoodquant commented 1 year ago

Again, same error with this change... @xabaddonx1

xozxro commented 1 year ago

Any update on this?

Running into the identical issue and have taken identical steps with no luck. Is this a bug in PyEtrade or picky E*Trade request formatting?

Odd that it works for some... @xabaddonx1 would you mind sharing your working request code and param formatting for option orders? Would be a large help.

xabaddonx1 commented 1 year ago

Here's mine, a couple things I thought of:

It could be the clientOrderId needs to be an int.

    resp = orders.place_option_order(
        resp_format='xml',
        accountId=brokerageAccountIdKey,
        symbol=symbol,
        callPut=callPut,
        expiryDate=expiryDate,
        strikePrice=formatNumber(strikePrice),
        orderAction=action,
        clientOrderId=int(clientOrderId),
        priceType=priceType,
        limitPrice=limitPrice,
        allOrNone=False,
        quantity=quantity,
        orderTerm="GOOD_FOR_DAY",
        marketSession='REGULAR')

i'm running the code below on strikePrice, I ran into an issue where sometimes it would say 12.0 and the api doesn't like that :


def formatNumber(num):
  if num % 1 == 0:
    return int(num)
  else:
    return num
Robert-Zacchigna commented 1 year ago

The client_order_id does need to be an int cast as a str. This is what i have working in my code without issue:

from random import randint

client_order_id = str(randint(1000000000, 9999999999))