GithubHelp home page GithubHelp logo

jessecooper / pyetrade Goto Github PK

View Code? Open in Web Editor NEW
192.0 31.0 94.0 427 KB

Python E-Trade API Wrapper

License: GNU General Public License v3.0

Makefile 0.31% Python 99.69%
etrade market stock api-client python

pyetrade's People

Contributors

1rocketdude avatar andronat avatar davidboertjes avatar ecourreges avatar franciszver avatar hz2018tv avatar jessecooper avatar mw66 avatar patter001 avatar robert-zacchigna avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyetrade's Issues

401 Client Error: Unauthorized for url

I am trying to automate login and use the resulting session object with pyetrade modules. However, I am getting 401 Client Error when trying to get account balance, list accounts, list orders, or preview equity order with pyetrade modules. However, for some functions, I am able to get a response if I use xmltodict.parse({login.session}.get(LIVE URL).text) on the login object. Here is the automated login function:

from rauth import OAuth1Service
import undetected_chromedriver.v2 as uc
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
import xmltodict
import json
import random
import pyetrade
import urllib.parse

class AutomatedLogin():
    def __init__(self, consumer_key, consumer_secret, web_username, web_password):
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.web_username = web_username
        self.web_password = web_password
        self.service = OAuth1Service(
                  name='etrade',
                  consumer_key=consumer_key,
                  consumer_secret=consumer_secret,
                  request_token_url='https://api.etrade.com/oauth/request_token',
                  access_token_url='https://api.etrade.com/oauth/access_token',
                  authorize_url='https://us.etrade.com/e/t/etws/authorize?key={}&token={}',
                  base_url='https://api.etrade.com')
        self.oauth_token, self.oauth_token_secret = self.service.get_request_token(params={'oauth_callback': 'oob', 'format': 'json'})
        self.auth_url = self.service.authorize_url.format(consumer_key, self.oauth_token)
        self.verifier = self.__get_verifier(headless=True, action_delay_sec=2)
        if self.verifier:
            self.session = self.service.get_auth_session(self.oauth_token, self.oauth_token_secret, params={'oauth_verifier': self.verifier})

    def __get_verifier(self, headless=True, action_delay_sec=2):
        if headless:
            options = uc.ChromeOptions()
            options.headless = True
            options.add_argument('--headless')
            driver = uc.Chrome(options=options, driver_executable_path='H:\My Drive\etradebot\chromedriver.exe')
            print(f'Headless web login with action_delay set to: {action_delay_sec} seconds')
        else:
            driver = uc.Chrome()
        web_action = ActionChains(driver)

        try:
            with driver:
                driver.get(self.auth_url)
                # log in
                username = driver.find_element(By.NAME, "USER")
                password = driver.find_element(By.NAME, "PASSWORD")
                username.send_keys(web_username)
                password.send_keys(web_password)
                driver.find_element(By.ID, "logon_button").click()
                time.sleep(action_delay_sec)
                web_action.send_keys(Keys.TAB).send_keys(Keys.RETURN).perform()
                return driver.find_element(By.TAG_NAME, "input").get_attribute("value")
        except Exception as e:
            print(str(e))
            return

# Automated Login
login = AutomatedLogin(consumer_key, consumer_secret, web_username, web_password)

I then obtain tokens like this:

tokens = {
    'oauth_token': login.oauth_token,
    'oauth_token_secret': login.oauth_token_secret
}

which looks like this (not real tokens, just demonstrating):

tokens
{
    'oauth_token': 'FfegWsfgdhfrhfew94hf84h399hfer/gfdgRgrfd=',
    'oauth_token_secret': 'greFGnfeFESFsFSfsfsfsfhgedgsssfsfdfGFRSsDbkjju='
}

If I try to get accounts list with pyetrade like this:

accounts = pyetrade.ETradeAccounts(
    consumer_key,
    consumer_secret,
    tokens['oauth_token'],
    tokens['oauth_token_secret'],
    dev
)

print(accounts.list_accounts(resp_format='xml'))

results in:

HTTPError: 401 Client Error: Unauthorized for url: https://api.etrade.com/v1/accounts/list

But when I use this code instead, it works:

xmltodict.parse(login.session.get('https://api.etrade.com/v1/accounts/list', params={'format': 'json'}).text)

If I try to get account balance, neither method works. For example, if I try with pyetrade:

print(accounts.get_account_balance(accountIDKey, resp_format='xml'))

I get (redacted):

HTTPError: 401 Client Error: Unauthorized for url: https://api.etrade.com/v1/accounts/{accountIDKey}/balance?
realTimeNAV=True&instType=BROKERAGE

If I try the other method to get account balance:

xmltodict.parse(login.session.get('https://api.etrade.com/v1/accounts/{}/balance?instType=
{}&realTimeNAV=true'.format(accountIDKey, 'BROKERAGE')).text)

I get:

{'Error': {'message': 'oauth_problem=signature_invalid'}}

In my google search, I found someone saying (https://stackoverflow.com/a/66405709/19349500), "The reason turned out to be that the oauth_signature and other parameters must be percent-encoded (rfc3986)." Could this be the reason to my problem? I tried to convert my tokens to rfc3986 percent-encoded like this:

tokens_rfc3986 = {
    'oauth_token': urllib.parse.quote(login.oauth_token),
    'oauth_token_secret': urllib.parse.quote(login.oauth_token_secret)
}

Convert tokens to look like this

tokens
{
    'oauth_token': 'FfegWsfgdhfrhfew94hf84h399hfer%gfdgRgrfd%3D',
    'oauth_token_secret': 'greFGnfeFESFsFSfsfsfsfhgedgsssfsfdfGFRSsDbkjju%3D'
}

But to no avail. Thanks for any help.

missing kwargs exception error when executing preview_equity_order

Getting 'Missing required parameters' error below

if not all(param in kwargs for param in mandatory):
--> 135 raise OrderException
136
137 if kwargs["priceType"] == "STOP" and "stopPrice" not in kwargs

Below is the kwargs dictionary I am using in SandBox environment
kwargs = {
"accountId":"6_Dpy0rmuQ9cu9IbTfvF2A",
"symbol":"AAPL",
"orderAction":"BUY",
"clientOrderId": random.randint(10000000,99999999),
"priceType":"MARKET",
"allOrNone": True,
"limitPrice":0,
"stopPrice":0,
}

Looked through the ETradeOrder module but couldn't find any issue in the self.check function for the kwargs. Does anyone know how to resolve this? Or will it work if I test code in production environment?

Issue with placing a new equity order

I am trying to place an equity order in the sandbox environment. I am able to list the accounts. However, I am probably going wrong with the payload. Below is the script I have put together for the same.

`

import pyetrade
from requests_oauthlib import OAuth1Session

base_url = "https://apisb.etrade.com"
account_id = 'account_id'
consumer_key = 'consumer_key'
consumer_secret = 'consumer_secret'

oauth = pyetrade.ETradeOAuth(consumer_key, consumer_secret)
print(oauth.get_request_token()) # Use the printed URL

verifier_code = input("Enter verification code: ")
tokens = oauth.get_access_token(verifier_code)
print(tokens)

accounts = pyetrade.ETradeAccounts(
consumer_key,
consumer_secret,
tokens['oauth_token'],
tokens['oauth_token_secret']
)

print(accounts.list_accounts())

orders = pyetrade.order.ETradeOrder(
consumer_key,
consumer_secret,
tokens['oauth_token'],
tokens['oauth_token_secret'],
dev=True
)

account_id = 'account_id'
symbol = 'symbol'

orders.place_equity_order(
accountId = account_id,
symbol = symbol,
orderAction="BUY",
clientOrderId= "1a2b3c",
priceType="MARKET",
quantity=100,
orderTerm="GOOD_UNTIL_CANCEL",
marketSession="REGULAR",
)

`

Below is the error I am getting.

`


HTTPError Traceback (most recent call last)
in
27 quantity=100,
28 orderTerm="GOOD_UNTIL_CANCEL",
---> 29 marketSession="REGULAR",
30 )

~/opt/anaconda3/lib/python3.7/site-packages/pyetrade/order.py in place_equity_order(self, resp_format, **kwargs)
525 "because of an Etrade bug as of 1/1/2019"
526 )
--> 527 preview = self.preview_equity_order(resp_format, **kwargs)
528 if resp_format == "xml":
529 preview = jxmlease.parse(preview)

~/opt/anaconda3/lib/python3.7/site-packages/pyetrade/order.py in preview_equity_order(self, resp_format, **kwargs)
483 payload = self.build_order_payload("PreviewOrderRequest", **kwargs)
484
--> 485 return self.perform_request(self.session.post, resp_format, api_url, payload)
486
487 def change_preview_equity_order(self, resp_format=None, **kwargs):

~/opt/anaconda3/lib/python3.7/site-packages/pyetrade/order.py in perform_request(self, method, resp_format, api_url, payload)
195
196 LOGGER.debug(req.text)
--> 197 req.raise_for_status()
198
199 if resp_format == "json":

~/opt/anaconda3/lib/python3.7/site-packages/requests/models.py in raise_for_status(self)
939
940 if http_error_msg:
--> 941 raise HTTPError(http_error_msg, response=self)
942
943 def close(self):

HTTPError: 400 Client Error: Bad Request for url: https://apisb.etrade.com/v1/accounts/83405188/orders/preview

`

Change equity order

Hi - I'm having the time of my life getting the preview equity order working. Does pyetrade work for that or is that a new feature? And how hard would it be for you to implement it?

get_quote symbols check

It appears ETrade has updated the quote API with an overrideSymbolCount option. Once set to true, the symbol length limit of 25 is increased to 50. It seems the get_quote function doesn't allow for the option, and seems to warn if any symbol length is > 25. Will the latest version include support for overrideSymbolCount as an option, and then alter the len(symbols) check depending upon overrideSymbolCount being true or false? Not sure if there are any tests for these conditions.

Verification code

What are you inputting on verification code. Because if I enter say abc or 123 it doesnt take. Where to get this value from. oauth.get_request_token is giving me back this value:

token: https://us.etrade.com/e/t/etws/authorize?key=2b85989shjgdjhsgdhgs&token=66uucqXz5Nb6tsKmhdghghgd=

  • The values are wrong and manually typed up.

This piece of code is where it is not working.

verifier_code = input("Enter verification code: ")
#verifier_code = token
tokens = oauth.get_access_token(verifier_code)
print(tokens)

ModuleNotFound during pip install

When installing with pip, the requirements for pyetrade are not automatically downloaded.

If I manually install them before installing pyetrade (e.g. pip install requests_oauthlib) , then installation succeeds.

How can we get the dependencies to automatically be installed first when running pip install pyetrade?

$ pip install pyetrade                                                                                                                                                           [14:15:43]
Collecting pyetrade
  Using cached pyetrade-1.2.1.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /private/tmp/venv/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/setup.py'"'"'; __file__='"'"'/private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-pip-egg-info-em8699_b
         cwd: /private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/
    Complete output (9 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/setup.py", line 4, in <module>
        from pyetrade import __version__
      File "/private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/pyetrade/__init__.py", line 9, in <module>
        from . import authorization  # noqa: F401
      File "/private/var/folders/ts/z2m10kg55q1gj22m9sbl4x5m0000gn/T/pip-install-639_mm9p/pyetrade/pyetrade/authorization.py", line 10, in <module>
        from requests_oauthlib import OAuth1Session
    ModuleNotFoundError: No module named 'requests_oauthlib'

Preview Equity Order issue - requests.exceptions.HTTPError: 400 Client Error: Bad Request for url

I've tried switching from accountKey to accountID and still the same response. I've tried XML and JSON. No changes.

CODE:

def OrderPreview(symbol,quantity,orderAction="BUY",priceType="MARKET",marketSession="REGULAR",orderTerm="GOOD_FOR_DAY"):
client_order_id = random.randint(1000000000, 9999999999)
accountID = AccountKey()

order_spec = {
        'resp_format': 'xml','accountId': str(accountID),
        'symbol': str(symbol),'orderAction': str(orderAction),
        'clientOrderId': str(client_order_id),'priceType': str(priceType),
        'quantity': int(quantity),'marketSession': str(marketSession),
        'orderTerm': str(orderTerm)
        }

orders = pyetrade.ETradeOrder(
        consumer_key,
        consumer_secret,
        tokens['oauth_token'],
        tokens['oauth_token_secret'],
        #dev=True
        dev=False
        )
orderpreview = orders.preview_equity_order(**order_spec)

ERROR:
orderpreview = orders.preview_equity_order(**order_spec)
File "/usr/local/lib/python3.6/dist-packages/pyetrade/order.py", line 322, in preview_equity_order
return self.perform_request(self.session.post, resp_format, api_url, payload)
File "/usr/local/lib/python3.6/dist-packages/pyetrade/order.py", line 201, in perform_request
req.raise_for_status()
File "/usr/local/lib/python3.6/dist-packages/requests/models.py", line 943, 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/XXXXXXXXXXXXXXXXX/orders/preview

stopPrice

order["stopPrice"] = ""

Hi, folks.

I have a question on the line 159. I may be wrong, but to my understanding the stopPrice is always an empty string, which means it would be useless even if I pass a stop price in the payload. Can anyone please advise me on this?

Thanks!

401 Client Error: Unauthorized for URL in prod

I was able to work in the sandbox, but for prod, I went through the full process of getting my PROD API approved (filled out survey, signed usage agreement), and then got the OAuth token, but I'm getting "401 Client Error: Unauthorized for url" for both "get_quote" and "list_accounts" functions. Has anyone else had this even after getting approved for a production key?

Please add usage examples

The docs are fairly thorough on the API, but there is nothing about how to actually use this to accomplish typical goals (login, get balance, get ticker price, get moving average, place an order)

this repo will be 100x more valuable with just 1 simple example in the readme

Are contingent orders actually supported?

Hi,

I'm reading this doc:

https://apisb.etrade.com/docs/api/order/api-order-v1.html#/definitions/OrderDetail

conditionType string The type of comparison to be used in a conditional order (contingent orders are not supported in API currently) CONTINGENT_GTE, CONTINGENT_LTE
conditionFollowPrice string In a conditional order, the type of price being followed ASK, BID, LAST

And found it's confusing: on one hand, the doc listed all the fields needed by the contingent orders, on the other hand, it also says: it's not supported.

So I am wondering if it's actually supported?

Has anyone tried to place contingent orders using API before? What's your experience?

Thanks!

Need help: preview request works but cannot place order

First, I tried using your pyetrade package but not be able to place order.
Then I tried to use the Etrade provided sample code, but I got this error.

{'code': 101, 'message': '{com.etrade.api.v1.order.InvalidPreviewId}'

The second time I tried though, I got a different error.
{'code': 101, 'message': 'For your protection, we have timed out your original order request. If you would like to place this order, please resubmit it now.'}

Payload I sent is like this:

                   <PlaceOrderRequest>
                       <orderType>EQ</orderType>
                       <clientOrderId>5340619102</clientOrderId>
                       <previewIds>
                           <previewId>1627181131</previewId>
                           <cashMargin>CASH</cashMargin>
                       </previewIds>
                       <Order>
                           <allOrNone>false</allOrNone>
                           <priceType>LIMIT</priceType>
                           <orderTerm>IMMEDIATE_OR_CANCEL</orderTerm>
                           <marketSession>REGULAR</marketSession>
                           <stopPrice></stopPrice>
                           <limitPrice>100</limitPrice>
                           <Instrument>
                               <Product>
                                   <securityType>EQ</securityType>
                                   <symbol>GOOG</symbol>
                               </Product>
                               <orderAction>BUY</orderAction>
                               <quantityType>QUANTITY</quantityType>
                               <quantity>1</quantity>
                           </Instrument>
                       </Order>
                   </PlaceOrderRequest  >

I hate that Etrade makes me preview order before placing one, but I see that pyetrade also need to preview order before placing it. If you seen this before, any help is appreciated.
If you can give me some code example of how to use pyetrade to preview and place order, I would also much prefer doing it that way. I'm kinda reading challenged when reading documentations without code examples. Thanks!

auth server down on 2022-06-29

anyone else having trouble connecting? After providing credentials, I get a blank response rather than the usual 5 character code

get_account_positions marker support

I had old code that used get_account_positions with the marker parameter to return more than 25 positions. This seems to have gone away now. How do I get all of my positions if there are more than 25?

cancel_order producing error - 400 Client Error: Bad Request for url

Hello,

Generally having success with this really nice package. I am running into an issue when attempting to cancel an order I've placed previously. Here is a test I'm trying to run:

orderID = random.randint(100000, 999999)
orders.place_equity_order(accountId=ACCOUNTIDKEY, symbol=symbol, orderAction="BUY", clientOrderId=orderID, priceType="LIMIT", limitPrice=thePrice, quantity=shareSize, orderTerm="GOOD_UNTIL_CANCEL", marketSession="REGULAR")

time.sleep(2)

cancelResponse = orders.cancel_order(account_id=ACCOUNTIDKEY, order_num=orderID, resp_format='json')
print(cancelResponse)

The above code successfully places an order, but when it tries to cancel it I receive this error:
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url

According to the Etrade docs this means the AccountID key is incorrect. But I'm 100% sure it is correct. Does anyone have an idea of how to fix this?

Thanks!

How can I use pytrade in a script?

I'm currently following the example on the README file here but when I rerun my script with my newly acquired verifier_code, I get an error:

Traceback (most recent call last):
  File "bot.py", line 11, in <module>
    tokens = oauth.get_access_token(verifier_code)
  File "/usr/local/lib/python3.7/site-packages/pyetrade/authorization.py", line 146, in get_access_token
    self.access_token = self.session.fetch_access_token(self.access_token_url)
  File "/Users/tasos/Library/Python/3.7/lib/python/site-packages/requests_oauthlib/oauth1_session.py", line 320, in fetch_access_token
    token = self._fetch_token(url, **request_kwargs)
  File "/Users/tasos/Library/Python/3.7/lib/python/site-packages/requests_oauthlib/oauth1_session.py", line 368, in _fetch_token
    raise TokenRequestDenied(error % (r.status_code, r.text), r)
requests_oauthlib.oauth1_session.TokenRequestDenied: Token request failed with code 401, response was '<html><head><title> - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - oauth_problem=token_rejected</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>oauth_problem=token_rejected</u></p><p><b>description</b> <u>This request requires HTTP authentication (oauth_problem=token_rejected).</u></p><HR size="1" noshade="noshade"><h3></h3></body></html>'.

I also tried to run the following skipping the oauth.get_request_token() but setting verifier_code from what I got online in a previous execution:

consumer_key = "<my_key>"
consumer_secret = "<my_secret>"
verifier_code = "<what I got from a previous execution>"

oauth = pyetrade.ETradeOAuth(consumer_key, consumer_secret)
# oauth.get_request_token()
# Follow url and get verification code

tokens = oauth.get_access_token(verifier_code)
accounts = pyetrade.ETradeAccounts(
    consumer_key,
    consumer_secret,
    tokens['oauth_token'],
    tokens['oauth_token_secret']
)
accounts.list_accounts()

but I got the following error:

Traceback (most recent call last):
  File "bot.py", line 11, in <module>
    tokens = oauth.get_access_token(verifier_code)
  File "/usr/local/lib/python3.7/site-packages/pyetrade/authorization.py", line 144, in get_access_token
    self.session._client.client.verifier = verifier
AttributeError: 'ETradeOAuth' object has no attribute 'session'

Any suggestions on how can I make this work as a script?

change existing orders

hi, can we change existing orders directly? I know it can be done by canceling the old ones and place new ones. ETRADE API doc seems to have /change/place.

requests_oauthlib.oauth1_session.TokenRequestDenied

just started happening on 2020-11-30. Hard to tell if this is an E*trade problem, a problem with my key, or some interaction with requests-2.25.0 that just updated.

Status 401 - oauth_problem=consumer_key_rejected

anyone else successful today getting consumer_keys? Perhaps it's just my personal key that expired?

Preview equity order doesn't work

Hi,

I'm trying to preview (and later on place) an equity order.
It seems authentication runs and I'm getting tokens.
This is the code I'm running (somehow code envioement scrambles the code):

oauth = pyetrade.ETradeOAuth(consumer_key1, consumer_secret1)
authorize_url = oauth.get_request_token()
webbrowser.open(authorize_url)
text_code = input('Please accept agreement and enter text code from browser: ')
token1 = oauth.get_access_token(text_code)
client_order_id = random.randint(1000000000, 9999999999)
order = pyetrade.ETradeOrder(consumer_key1,
consumer_secret1,
token1['oauth_token'],
token1['oauth_token_secret'], dev=False)
data = order.preview_equity_order(resp_format='json', accountId=account_id_key1, symbol='F',
orderAction='BUY', clientOrderId=client_order_id,
priceType='LIMIT', limitPrice=2.1, quantity=3,
marketSession='REGULAR',
orderTerm='GOOD_UNTIL_CANCEL')

and I'm getting this Traceback:

Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.1\plugins\python-ce\helpers\pydev\pydevd.py", line 1448, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.1\plugins\python-ce\helpers\pydev_pydev_imps_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/Owner/PycharmProjects/stacky/etrade_api.py", line 94, in
data = order.preview_equity_order(resp_format='json', accountId=account_id_key1, symbol='F',
File "C:\Users\Owner\PycharmProjects\stacky\venv\lib\site-packages\pyetrade\order.py", line 485, in preview_equity_order
return self.perform_request(self.session.post, resp_format, api_url, payload)
File "C:\Users\Owner\PycharmProjects\stacky\venv\lib\site-packages\pyetrade\order.py", line 197, in perform_request
req.raise_for_status()
File "C:\Users\Owner\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\models.py", line 941, 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/_lSY20dXKIHRGpiJ6faoEQ/orders/preview

Your help will be greatly appreciated.

timeout setting of requests on all classes

Hello,
I see a timeout param on ETradeOrder, however there isn't any on market, accounts, authorization.
The E*Trade API is running very slow right now and the default requests timeout is just too long (even though it ends up answering in success but after a couple of minutes).
I may issue a PR later if you don't have time to implement this.

Thanks,
Regards.

oauth problems

as of 2021-11-11, anyone else getting this error when calling oauth.get_request_token()?

oauth_problem=timestamp_refused,oauth_acceptable_timestamps=1636665132-16366687

I'm pretty sure my account and keys are valid. Renewed 3 months ago.

Token request failed with code 401

Anyone else getting this while attempting login? I just ran it last night and got this error. Rebooted thinking it was something simple but looks like it's not. Looks like it hanging up on the following. Any thoughts on what's happening as things were working fine a week ago.

self.session.fetch_request_token(self.req_token_url)
token = self._fetch_token(url, **request_kwargs)
raise TokenRequestDenied(error % (r.status_code, r.text), r)

TokenRequestDenied: Token request failed with code 401, response was '<!doctype html><title>HTTP Status 401 โ€“ Unauthorized</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style>

HTTP Status 401 โ€“ Unauthorized


Type Status Report

Message oauth_problem=consumer_key_rejected

Description The request has not been applied because it lacks valid authentication credentials for the target resource.


'.

oauth issue

If I understand correctly, shouldn't renew_access_token(), if called every day, continue to allow access? After several weeks of operation I just received error 401 after calling renew_access_token() and had to call get_access_token() and go through the entire login process. Is there a programmatic way to avoid having to call get_access_token()?

Help wanted - getQuote

Hello,

I am using the following code:

symbols = ['MAXR']

list_stock_quote = pyetrade.ETradeMarket.get_quote(
symbols=symbols,
detail_flag=None,
require_earnings_date=None,
skip_mini_options_check=None,
resp_format="xml")

print(list_stock_quote)

and getting the following error. What is it looking for for self?
list_stock_quote = pyetrade.ETradeMarket.get_quote(
TypeError: get_quote() missing 1 required positional argument: 'self'

Get Select fields from Market module

Hi
I am using Market.py and modifying it according to my needs. can I know how I can pull only few fields from api call using
url = self.base_url + "/v1/market/quote/" + symbols + ".json"
likes of

url = self.base_url + "/v1/market/quote/fields=symbol,symbolDescrition" + symbols + ".json"

your help is much appreciated.
fields here are from standard fields available with api call one from ALL , Extended Hours etc.
attached market.py, cannot upload market.py so attached as docx
Thank you in advance

market.docx

HTTPError: 401 Client Error: Unauthorized for url

Hello,

I'm getting an error while trying to use the list_accounts() function in the sandbox environment. My censored code:

#!/usr/bin/python3
import pyetrade
consumer_key = "REMOVED"
consumer_secret = "REMOVED"
oauth = pyetrade.ETradeOAuth(consumer_key, consumer_secret)
print("checkpoint 1")
print("Visit site and obtain code")
print(oauth.get_request_token())
tokens = oauth.get_access_token(input("Enter Token:  "))
print("checkpoing 2")
print(tokens)
accounts = pyetrade.ETradeAccounts(
        consumer_key,
        consumer_secret,
        tokens['oauth_token'],
        tokens['oauth_token_secret']
    )
print("checkpoint 3")
accounts.list_accounts()
print("checkpoint 4")

All seems well until the accounts.list_accounts() function. The censored output:

checkpoint 1
Visit site and obtain code
https://us.etrade.com/e/t/etws/authorize?key=REMOVED
Enter Token:  REMOVED
checkpoing 2
{'oauth_token_secret': 'REMOVED', 'oauth_token': 'REMOVED'}
checkpoint 3
Traceback (most recent call last):
  File "./etrade-test.py", line 22, in <module>
    accounts.list_accounts()
  File "/usr/local/lib/python3.5/dist-packages/pyetrade/accounts.py", line 54, in list_accounts
    req.raise_for_status()
  File "/home/REMOVED/.local/lib/python3.5/site-packages/requests/models.py", line 940, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://etwssandbox.etrade.com/accounts/sandbox/rest/accountlist.json

uname -a
Linux THX-1138 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux

hwclock --debug
hwclock from util-linux 2.29.2
Using the /dev interface to the clock.
Last drift adjustment done at 1543475777 seconds after 1969
Last calibration done at 1543475777 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.

Any suggestions on this issue?

User Login via Selenium

Good library. I would suggest a modification to your ETradeOAuth class to support automated login. Below is a working test script to benefit others if you decided to not add the feature.

from rauth import OAuth1Service
import undetected_chromedriver.v2 as uc
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
import xmltodict
import json


class AutomatedLogin():
    def __init__(self, consumer_key, consumer_secret, web_username, web_password):
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.web_username = web_username
        self.web_password = web_password
        self.service = OAuth1Service(
                  name='etrade',
                  consumer_key=consumer_key,
                  consumer_secret=consumer_secret,
                  request_token_url='https://apisb.etrade.com/oauth/request_token',
                  access_token_url='https://apisb.etrade.com/oauth/access_token',
                  authorize_url='https://us.etrade.com/e/t/etws/authorize?key={}&token={}',
                  base_url='https://apisb.etrade.com')
        self.oauth_token, self.oauth_token_secret = self.service.get_request_token(params={'oauth_callback': 'oob', 'format': 'json'})
        self.auth_url = self.service.authorize_url.format(consumer_key, self.oauth_token)
        self.verifier = self.__get_verifier(headless=True, action_delay_sec=2)
        if self.verifier:
            self.session = self.service.get_auth_session(self.oauth_token, self.oauth_token_secret, params={'oauth_verifier': self.verifier})

    def __get_verifier(self, headless=True, action_delay_sec=2):
        if headless:
            options = uc.ChromeOptions()
            options.headless = True
            options.add_argument('--headless')
            driver = uc.Chrome(options=options)
            print(f'Headless web login with action_delay set to: {action_delay_sec} seconds')
        else:
            driver = uc.Chrome()
        web_action = ActionChains(driver)

        try:
            with driver:
                driver.get(self.auth_url)
                # log in
                username = driver.find_element_by_name("USER")
                password = driver.find_element_by_name("PASSWORD")
                username.send_keys(web_username)
                password.send_keys(web_password)
                driver.find_element_by_id("logon_button").click()
                time.sleep(action_delay_sec)
                web_action.send_keys(Keys.TAB).send_keys(Keys.RETURN).perform()
                return driver.find_element_by_tag_name("input").get_attribute("value")
        except Exception as e:
            print(str(e))
            return

# User Parameters
consumer_key = 'dxxx...xxx007'
consumer_secret = 'e7xxx...xxxa4e8'
web_username = 'user_name'
web_password = 'password'

# Automated Login
login = AutomatedLogin(consumer_key, consumer_secret, web_username, web_password)

# Test Session
url = 'https://apisb.etrade.com/v1/accounts/list'
resp = login.session.get(url, params={'format': 'json'})
resp_json = json.dumps(xmltodict.parse(resp.text))
print(resp_json)

Issues placing equity order

orders = pyetrade.ETradeOrder( consumer_key, consumer_secret, oauth_token, oauth_token_secret, dev=True ) #print(orders.list_orders(accountID, resp_format='json')) orders.place_equity_order(resp_format='json',clientOrderId='33ad33f3fdc',priceType='MARKET',accountId=accountID,symbol='GOOG',orderAction='BUY',quantity='10000',marketSession='REGULAR',orderTerm='GOOD_FOR_DAY')

This is the code I have but I get a "400 Client Error: Bad Request for url: https://apisb.etrade.com/v1/accounts/6_Dpy0rmuQ9cu9IbTfvF2A/orders/preview" error no matter which account id key I try, as you can see I have a line to print the order list commented out and it works with the account id key but it wont work to place an equity order

Invalid Order Requests

orders.place_equity_order('json', accountId = 'XX', symbol=symbol, orderAction='SELL_SHORT', clientOrderId=uuid.uuid4().hex, priceType='LIMIT', limitPrice=float(price), quantity=int(float(qty)), marketSession='EXTENDED', orderTerm='GOOD_FOR_DAY')

send: b'{"PreviewOrderRequest": {"orderType": "EQ", "clientOrderId": "d0068a1b51fb46fc94dca56cab49bacd", "Order": {"accountId": "XXX", "symbol": "UCO", "orderAction": "SELL_SHORT", "clientOrderId": "d0068a1b51fb46fc94dca56cab49bacd", "priceType": "LIMIT", "limitPrice": 10.5, "quantity": 10, "marketSession": "EXTENDED", "orderTerm": "GOOD_FOR_DAY", "Instrument": {"Product": {"securityType": "EQ", "symbol": "UCO"}, "orderAction": "SELL_SHORT", "quantityType": "QUANTITY", "quantity": 10}, "stopPrice": ""}}}'

Response from Etrade:

reply: 'HTTP/1.1 400 Bad Request\r\n'
header: Date: Mon, 18 May 2020 02:57:24 GMT
header: Server: Apache
header: Cache-Control: no-cache, no-store
header: Pragma: no-cache
header: apiServerName: 40w303m5
header: Set-Cookie: JSESSIONID=46B2CF38EC415F7C92ACA45AB9B1E17D.tomcat1;path=/;Secure;HttpOnly
header: Cneonction: close
header: Transfer-Encoding: chunked
header: Content-Type: application/xml
DEBUG:urllib3.connectionpool:https://apisb.etrade.com:443 "POST /v1/accounts/XX/orders/preview HTTP/1.1" 400 None
DEBUG:pyetrade.order:
9999
Please validate the input and try again

Looks like stopPrice is sent irrespective of the order type. Don't know how this module is working to execute trade?

AccountID is obfuscated

Can someone please help if I'm missing something?

Robot Framework automated OAuth proposal

Hello all, I have been happily using your lib for 9months, and happy to see you are working on the v1 which took me by surprise (got the email from ETrade only on December 4th...).
Would you be interested in my RobotFramework automation that automatically logs you in for the e
trade API?
Or do you think it has nothing to do with a python api lib, or is it legally risky?
I was tired of logging in every single day for my bot to keep working in production, so I coded that, and I've saved a lot of time in 6 months thanks to that.
I may also have time to help with any market order bugs on the v1 next week, as I'll be testing the sandbox.
Regards,
Emmanuel.

Token Request Denied Error

Hello,

I tried to get this code up and running with the example provided in the readme but after pasting in my key and secret I get the following error:

https://us.etrade.com/e/t/etws/authorize?key=**********************&token=******************
Traceback (most recent call last):
File "trade.py", line 10, in
tokens = oauth.get_access_token(verifier_code)
File "/Users/isaacshiffman/Documents/pyetrade/pyetrade/authorization.py", line 139, in get_access_token
self.access_token = self.session.fetch_access_token(self.access_token_url)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests_oauthlib/oauth1_session.py", line 304, in fetch_access_token
token = self._fetch_token(url, **request_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests_oauthlib/oauth1_session.py", line 351, in _fetch_token
raise TokenRequestDenied(error % (r.status_code, r.text), r)
requests_oauthlib.oauth1_session.TokenRequestDenied: Token request failed with code 401, response was '<title> - Error report</title><style></style>

HTTP Status 401 - oauth_problem=token_rejected


type Status report

message oauth_problem=token_rejected

description This request requires HTTP authentication (oauth_problem=token_rejected).


'.

Automatic Authentication

When you authenticate it requires you to manually open up the E*TRADE website to obtain a code. Is there any way to automate this so that my trading strategy can run without me being there to start it up? I might be missing something obvious. Please help.

HTTP Status 401 - oauth_problem=signature_invalid

I inserted my consumer_key and consumer_secret and i get the following error. I believe this is because the keys are bad, but i wanted to confirm.

<title> - Error report</title><style></style>

HTTP Status 401 - oauth_problem=signature_invalid


type Status report

message oauth_problem=signature_invalid

description This request requires HTTP authentication (oauth_problem=signature_invalid).


Issues Implementing

Hey everyone,

I'm a bit new to python, but not new working with APIs. For some reason I'm having issues getting this to work. Would someone mind posting an example file?

Thanks!

[Warning!] ETrade API *sever* bug: Stop Price and Trailing Stop Parameter are swapped!

with this parameter:

[ place_equity_order()] {'accountId': 'xxx', 'symbol': 'STLD', 'orderAction': 'SELL', 'clientOrderId': xxx,
 'priceType': 'TRAILING_STOP_CNST', 'offsetType': 'TRAILING_STOP_CNST',
 'offsetValue': '0.66', 'trailPrice': '0.66', 'stopPrice': '64.49', 'allOrNone': False,
 'quantity': 50, 'orderTerm': 'GOOD_UNTIL_CANCEL', 'marketSession': 'REGULAR'}

I saw the placed order is:

STLD
Initial Stop Price: 0.66
Trailing Stop Parameter: 64.49 point(s) below bid

This is ridiculous: the Initial Stop Price and Trailing Stop Parameter are swapped!

I contacted ETrade customer service, this is what they said:

The current trailing stop price is set in "stopPrice" field

I cannot believe it, looks like they are not going to fix their bugs!

Using the get_quote only returns GOOGL

Regardless of the parameters I input (detail flag, symbols), it only returns "All" for GOOGL.

market = pyetrade.ETradeMarket(
consumer_key,
consumer_secret,
tokens['oauth_token'],
tokens['oauth_token_secret'],
dev = True
)

symbols = ['PETS']
r = market.get_quote(symbols, detail_flag="fundamental")

full portfolio response

How do we get the full portfolio response if it has more than 1 page? It seems like beyond the 1st page is not available in get_account_portfolio...

Thanks Jesse.

New version

Hi there,
Do you have any ETA on the new version implementation?

any1 has issues getting the request_token?

pretty much failed here

    self.session = OAuth1Session(
        self.consumer_key,
        self.consumer_secret,
        callback_uri=self.callback_url,
        signature_type="AUTH_HEADER",
    )
    # get request token
    self.session.fetch_request_token(self.req_token_url)

also tried etrade official python client, also failed at this step.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.