jessecooper / pyetrade Goto Github PK
View Code? Open in Web Editor NEWPython E-Trade API Wrapper
License: GNU General Public License v3.0
Python E-Trade API Wrapper
License: GNU General Public License v3.0
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.
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?
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
`
https://github.com/jessecooper/pyetrade/blob/master/pyetrade/order.py#L159
order["stopPrice"] = ""
This line should be changed to:
if "stopPrice" in kwargs:
stopPrice = (float(kwargs["stopPrice"]) - 0.01)
if stopPrice > 0:
order["stopPrice"] = "%.2f" % stopPrice
to properly convert float number to 2 decimal place dollar value.
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?
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.
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=
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)
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'
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
Love this entire collection! Where would I get a consumer/secret key? I'm relatively new to API's, but was trying to implement this module into a personal project. Any help would be great!
Thanks
Line 159 in 289bdb8
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!
The v0 Etrade API had support for a Rate Limit, see page 205 at https://cdn.etrade.net/1/20190322.0/static_devportal/static/downloads/ETRADE_Developer_Platform_Guide.pdf Do we know if this is supported in v1 Etrade API? If so, can we create a pyetrade function to support it?
An exception occurred in the get_option_chains method call.
Prompt 401 error.
Are there any examples of successful calls? Thank you!
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?
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
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!
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!
anyone else having trouble connecting? After providing credentials, I get a blank response rather than the usual 5 character code
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?
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!
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?
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.
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?
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.
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.
Sandbox env worked well and when switched production keys, get the error
HTTPError: 401 Client Error: Unauthorized for url: https://apisb.etrade.com/v1/accounts/list.json
Is there setting or call that will switch dev to false?
Thanks for the work on pyetrade!
Jesse, can you add a sample for complete placing LIMIT equity order .
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.
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>
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.
Any possibility of getting the ability to place option orders (puts, calls etc.) into Etrade via PyEtrade?
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()?
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'
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
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?
when response is empty text
https://github.com/jessecooper/pyetrade/blob/master/pyetrade/order.py#L107
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I tried pyetrade api wraper and custom request model for previewing and placing trade equity order but place order responding with following error
For your protection, we have timed out your original order request. If you would like to place this order, please resubmit it now.
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)
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
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?
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 etrade 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.
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>
type Status report
message oauth_problem=token_rejected
description This request requires HTTP authentication (oauth_problem=token_rejected).
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.
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>type Status report
message oauth_problem=signature_invalid
description This request requires HTTP authentication (oauth_problem=signature_invalid).
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!
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!
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")
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.
Hi there,
Do you have any ETA on the new version implementation?
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.