tedchou12 / webull Goto Github PK
View Code? Open in Web Editor NEWUnofficial APIs for Webull.
License: MIT License
Unofficial APIs for Webull.
License: MIT License
when call wb.get_mfa(), error indicates no this function
I am getting below response when i am trying to place order.. Did you see error like below, your input would be appreciated.
<200,{"success":false,"code":"trade.webull.DAY_BUYING_POWER_INSUFFICIENT","msg":"Buying power is insufficient, please cancel open buy orders(if there is any) and try again
right now I don't have 25k in my account . Is it because of that ??.. Just FYI I am able to place order from mobile app.
Thanks
The web sockets appear to be MQTT based, which after some googling is a common internet of things format --- go figure. There appears to be two sockets open, one (wss://platpush.webullbroker.com/mqtt port 443) just for order status updates (fill, cancel, modify), spends most of its time doing a keep-alive message to keep the socket open. The other (wss://wspush.webullbroker.com/mqtt port 443) does streaming quotes for the charts/screens, there appear to be at least thee different price update formats for the different parts of the app
Line 268 in e83b9a1
for instance...
>>> wb.get_quote('NNVC')
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/webull/webull.py", line 445, in get_quote
tId = str(self.get_ticker(stock))
File "/usr/local/lib/python3.7/site-packages/webull/webull.py", line 269, in get_ticker
raise ValueError('TickerId could not be found for stock {}'.format(stock))
ValueError: TickerId could not be found for stock NNVC
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/webull/webull.py", line 447, in get_quote
raise ValueError("Could not find ticker for stock {}".format(stock))
ValueError: Could not find ticker for stock NNVC
But, NNVC is an actual good stock with a valid ticker ID
curl -k 'https://infoapi.webull.com/api/search/tickers5?keys=NNVC&queryNumber=1'| jq -r
{
"categoryId": 0,
"categoryName": "综合",
"hasMore": false,
"list": [
{
"tickerId": 913303706,
"exchangeId": 12,
"type": 2,
"secType": [
61
],
"regionId": 6,
"regionCode": "US",
"currencyId": 247,
"name": "NANOVIRICIDES",
"symbol": "NNVC",
"disSymbol": "NNVC",
"disExchangeCode": "AMEX",
"exchangeCode": "ASE",
"listStatus": 1,
"template": "stock"
}
]
}
Hey @tedchou12, sweet project :)
I'm wondering how you'd feel about an async client particularly for streaming quotes.
There's already an effort to get trio
support for paho.mqtt
: trio-paho-mqtt
so it should be a mostly minimal addition.
I'm personally after trio
support for my infra and am happy to help, make a PR, etc.
I figured I'd ask if you'd take the contribution before going off on my own; it seems like there's already a lot of good stuff here!
Cheers.
Hello.
I'm new on GitHub, how can I show you what I would like to add to your project?
I want to add shell.py by analogy with Robinhood samples and make some changes in your webull.py.
config.py.txt
shell.py.txt
Best regards,
Mikhail.
Is there api for VWAP of a quote?
I want to get the instant bid and ask price to determine the order. Thank you very much!
I have the following option from a webull.get_options(stock="JCP", expireDate="2020-05-01")
{'strikePrice': '2.00', 'call': {'tickerId': 1014438795, 'close': '0.0100', 'change': '0.000', 'changeRatio': '0.0000', 'volume': '12', 'preClose': '0.0100', 'open': '0.0100', 'high': '0.0100', 'low': '0.0100', 'askList': [{'price': '0.0100', 'volume': '6'}, {}, {}, {}, {}, {}, {}, {}, {}, {}], 'bidList': [{'price': '0.0000', 'volume': '0'}, {}, {}, {}, {}, {}, {}, {}, {}, {}], 'strikePrice': '2.00', 'direction': 'call', 'expireDate': '2020-05-01', 'openInterest': 11, 'openIntChange': 0, 'impVol': '8.4971', 'gamma': '0.0000', 'theta': '0.0000', 'vega': '0.0000', 'rho': '0.0000', 'delta': '0.0000', 'activeLevel': 4, 'weekly': 1, 'quoteMultiplier': 100, 'unSymbol': 'JCP'}, 'put': {'tickerId': 1014438799, 'close': '1.960', 'change': '0.210', 'changeRatio': '0.1200', 'volume': '18', 'preClose': '1.750', 'open': '1.580', 'high': '1.960', 'low': '1.580', 'askList': [{'price': '1.960', 'volume': '9'}, {}, {}, {}, {}, {}, {}, {}, {}, {}], 'bidList': [{'price': '1.310', 'volume': '1'}, {}, {}, {}, {}, {}, {}, {}, {}, {}], 'strikePrice': '2.00', 'direction': 'put', 'expireDate': '2020-05-01', 'openInterest': 1, 'openIntChange': 0, 'gamma': '0.0000', 'theta': '0.0000', 'vega': '0.0000', 'rho': '0.0000', 'delta': '-1.0000', 'activeLevel': 4, 'weekly': 1, 'quoteMultiplier': 100, 'unSymbol': 'JCP'}}
I'm using the tickerId
as the optionId which seems to be the same as the webull client is going on network inspecting
I'm trying this
webull.place_option_order(optionId="1014438795", lmtPrice=0.01, action='BUY', orderType='LMT', enforce='DAY', quant=1)
I'm getting a 403
Traceback (most recent call last):
File "./main.py", line 19, in <module>
webull.place_option_order(optionId=1014438795, lmtPrice="0.01", action='BUY', orderType='LMT', enforce='DAY', quant=1)
File "/Users/mzupan/mz/option-trader/webull.py", line 443, in place_option_order
raise Exception('place_option_order failed', response.status_code, response.reason)
Exception: ('place_option_order failed', 403, 'Forbidden')
Is this because of the issue of not being able to trade options on webull over the weekend? The web client does a 200 but my guess is the endpoint might be different.
get_ticker('DSS') returning error -->'msg': 'Could not find a healthy node to handle the request.', 'traceId': 'b0f00b095e154f37963c8e690996b9b9', 'code': '500'}
did the API endpoint changed?
Did it break or just me? I'm sure that i used correct pin/pass
I receive the following error when I try to obtain an MFA
from webull import webull, paper_webull
wb = webull()
wb.get_mfa('[email protected]')
wb.login('[email protected]', 'MyPass!, mfa')
AttributeError Traceback (most recent call last)
in
5
6 wb = webull()
----> 7 wb.get_mfa('[email protected]')
AttributeError: 'webull' object has no attribute 'get_mfa'
hi, got trade_token expired sometimes. Is there a way to refresh it gracefully? I assume we can call get_trade_token(password) periodically.
Found that the access/refresh token is valid for 90 days.
Why NOT we use that instead of MFA everytime.. if we can personally manage and cache.
Can we have API added api_login(id, access_token, refresh_token) ?
Does login method support both mobil and email login?
Here is an example response from the API when I attempt to make an order on my cash account with unsettled funds.
On the app, you can make these orders as long as you tap the circle that says you understand a good faith violation (GFV) will occur if you sell before funds are settled. However, with this API, the order just gets rejected.
I am able to make other orders through this API just fine.
could you add function to retrieve historical orders, including those filled or canceled, and including those closed positions? thanks
webull.get_account gets 404 response and raises the following error:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
When I try to get the account details by response = requests.get('https://tradeapi.webulltrade.com/api/trade/v2/home/10129689', headers=headers), I get the message that "This account does not belong to this user". How can you find the id 10129689 in your account?
Hello,
Does anybody tried subj?
When I'm trying:
response = requests.put('https://tradeapi.webulltrade.com/api/trade/order/' + self.account_id + '/modifyStockOrder/' + str(orderId), data=data, headers=headers)
I'm getting:
'Service is not available,please try again later'
Thank you
I want to help building this repo, but I could't find any docs for webull API, can anyone link me?
My online account keeps getting locked while using the webull api,
The email says "Trading password locked, Your Webull account has been locked because of too many failed trading password verification attempts"
From the code perspective everything works fine and I can execute all commands but when I try to view my account on my cell phone it says it locked and I have to wait 5 minutes up to 2 hours if it keeps being locked.
I am using the wb.refresh_login() every time I run the script and only use the wb.login() after a long time of not using the script. Have you experience this account locking?
Here is my exact code:
# First time login if access token expires
get_access_code = False
if get_access_code:
self.wb.get_mfa(self.webull_email)
# Check email for 6 digit access code. Enter it below
access_code = '123456'
data = self.wb.login(self.webull_email, self.webull_password,'windows', access_code)
self.logger.info(data)
# Get login token for session
data = self.wb.refresh_login()
# I think this is the line that is causing the account locking
data = self.wb.login(self.webull_email, self.webull_password)
if 'accessToken' in data :
self.logger.info("successful login")
# Get trade token for session
self.wb.get_trade_token(self.webull_password)
It would be great to add a method to Webull class to extract the various ticks for Movers, gainers, and losers. This way, one can use the market information on Webull website to create a strategy for their trading rules.
Hey guys,
Great job so far on all of the work that's been done here. I've been able to connect up and place an order using this API so far and it's been rather painless.
One of my objectives here is to be able to pull out the active gainers / losers lists that are on webull's app (market section) to use for further analysis. When pulling this info using get_active_gainers_losers(), I get a list of names (about 20 long). However, this list does not match up with the gainers list (1-day) when comparing to the app.
My question is: Is there a option to choose the time frame of the list (i.e. 5-minute, 1-day, pre-market, after-hours, etc.) of the list that's being produced?
To build further, is there an option to choose the length of the list being returned (it seems the Webull lists have no limit)?
Let me know when you get the chance. Looking forward to helping out any way I can.
Thanks!
I cannot pip install webull
Printed the response in the get_ticker() function. It checked for "hasMore" false and dies. The tickerId is still there in the list. Stock is SPLK as example
Started to see this issue.{'categoryId': 0, 'categoryName': '综合', 'hasMore': False, 'list': [{'tickerId': 913255699, 'exchangeId': 96, 'type': 2, 'secType': [61], 'regionId': 6, 'regionCode': 'US', 'currencyId': 247, 'name': 'Splunk', 'symbol': 'SPLK', 'disSymbol': 'SPLK', 'disExchangeCode': 'NASDAQ', 'exchangeCode': 'NSQ', 'listStatus': 1, 'template': 'stock', 'derivativeSupport': 1}]}
def get_ticker(self, stock=''):
'''
Lookup ticker_id
'''
ticker_id = 0
if stock and isinstance(stock, str):
response = requests.get(self._urls.stock_id(stock))
result = response.json()
if result['hasMore'] == False:
raise ValueError('TickerId could not be found for stock {}'.format(stock))
elif result['list']:
for item in result['list']: # implies multiple tickers, but only assigns last one?
ticker_id = item['tickerId']
else:
raise ValueError('Stock symbol is required')
return ticker_id
I am getting the below as result for the method. Is the api changed ?
{'msg': 'Failed to convert value of type 'java.lang.String' to required type 'java.util.Set'; nested exception is java.lang.NumberFormatException: For input string: "AAPL"', 'traceId': 'd104228cfba340d0b8c986fda5a4f263', 'code': '400'}
I found the below api but it has different structure
Hi. I noticed that for some Webull stocks, BNGO and TTNP for example, are not supported by the api. I get a "Could not find ticker BNGO" error when I try to access the data or place an order for BNGO. I this correct that the api does not support some Webull stocks. Thanks.
Hello,
I am working on this in colab and keep ending up with the same message after trying multiple workarounds. I have a True when I log in but with the next line 'get_account_info()' I continue to get this message. Thank you in advance.
`---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in ()
2 webull = webull()
3 webull.login('j**********', '*********')
----> 4 webull.get_account_id()
5 #webull.get_trade_token('123456')
6 #print(webull.get_account())
in get_account_id(self)
276
277 if result['success']:
--> 278 self.account_id = str(result['data'][0]['secAccountId'])
279 return True
280 else:
KeyError: 'secAccountId'`
When I comment out the above code the results show as
'{'success': True,
'data': [{'brokerId': 8, 'brokerName': 'Individual', 'status': 'unopen', 'registerTradeUrl':
'/mgt/redirect/tradeh5', 'openAccountUrl':
'https://tradeh5.webull.com/register/ib/continue.html', 'supportOutsideRth': True,
'userTradePermissionVOs': [{'type': 'stock', 'hasPermission': False, 'brokerId': 8}],
'supportClickIPO': True, 'isDefaultChecked': False, 'supportOpenOption': True}]}'
It would be really nice to have a way to see all tickers that are on webull to then loop through other functions.
When I check the source code, I find when placing order, 'outsideRegularTradingHour': True
. May I ask what's the extra benefit to trade before or after regular market time?
May be it is a biz question more than coding question ;). Having extra hours to trade is always a good thing?
Shall we give people an option to trade only at market time?
Option Order doesn't work. I am able to find it and added below code to my local copy. Still need formatting.
I just changed for first one, lmtPrice is string, at least that how portal works.
if orderType == 'LMT' and lmtPrice:
data['lmtPrice'] = lmtPrice #removed float
if orderType == 'STP' and stpPrice:
data['auxPrice'] = float(stpPrice)
if orderType == 'STP LMT' and lmtPrice and stpPrice:
data['lmtPrice'] = float(lmtPrice)
data['auxPrice'] = float(stpPrice)
Made few changes....
response = requests.post(self.urls.place_option_orders(self.account_id), json=data, headers=headers)
data1 = json.loads(response.content) # reading response in json; This is to capture order message 8:00 AM to 4:00PM.
if response.status_code != 200 or not data1["forward"]: # added a check to see if its success; you will see status code 200 but there will no order placed after 4:00 PM so we need to capture that.
raise Exception('place_option_order failed', response.status_code, response.reason,
data1["checkResultList"][0]["msg"]) #Added message here
response = requests.post(self.urls.place_option_orders1(self.account_id), json=data, headers=headers) # this is the actual trade url; just placed URL under endpoints.py
return True
endpoint.py
def place_option_orders(self, account_id):
return f'{self.base_trade_url}/v2/option/checkOrder/{account_id}'
def place_option_orders1(self, account_id):
return f'{self.base_trade_url}/v2/option/placeOrder/{account_id}'
Every time I try to login I get the error {'msg': 'deviceId=null','traceId':'xxx','code':'500'}
Can we stream/get macd, rsi, ema data?
i am very new to this im not sure how to install and get it running
I'm trying to get account details via .get_account_id():
from webull import webull
wb = webull()
pw = "MY PASSWORD"
un = 'MY USERNAME'
wb.login(un, pw,"Max's Python", '423251')
print(wb.get_account_id())
wb.logout()
I keep getting the following response:
Traceback (most recent call last):
File "D:/Trading Bots/Webull Trading.py", line 7, in
{'success': True, 'data': [{'brokerId': 8, 'brokerName': 'Individual', 'status': 'unopen', 'registerTradeUrl': '/mgt/redirect/tradeh5', 'openAccountUrl': 'https://tradeh5.webull.com/register/ib/continue.html', 'supportOutsideRth': True, 'userTradePermissionVOs': [{'type': 'stock', 'hasPermission': False, 'brokerId': 8}, {'type': 'crypto', 'hasPermission': False, 'brokerId': 8}], 'supportClickIPO': True, 'isDefaultChecked': False, 'supportOpenOption': True}]}
print(wb.get_account_id())
File "D:\Trading Bots\venv\lib\site-packages\webull\webull.py", line 188, in get_account_id
id = str(result['data'][0]['secAccountId'])
KeyError: 'secAccountId'
I was trying to troubleshoot the code by putting a print statement into project. It keeps saying that my account status is unopen. However, when I request the mfa I can get it using the same password and username. I'm not sure what to do at this point.
Any advice is much appreciated. Fairly new to coding.
Latest version in PyPI (0.0.8) is from May 13th and doesn't include the mfa updates.
With options trading being added on Webull it would be nice to see this supported.
When trying to place an order, I get this:
{'success': False, 'code': 'trade.system.exception', 'msg': 'The system is busy', 'data': {'lastSerialId': '5f0c8537ca18e90001147115'}}
Is this just due to webull servers being overloaded or am I facing locked account issues?
The KeyError 'hasMore' is printed out everytime I try to get quote information from a stock. It had worked perfectly fine for 2 months up until now. I'm not sure what that error means so I have no idea what the problem is. Is there a reason why get_quote() is doing this?
Please help me. Thanks
wb.place_order('SBUX', 913257472, 70, 'BUY', 'LMT', 'GTC', 1)
{'timestamp': '2020-07-14T18:02:17.598+0000', 'status': 404, 'error': 'Not Found', 'message': 'No message available', 'path': '/webull-paper-center/api/paper/1/acc//orderop/place/913257472'}
Can this api be extended for options trading?
login would fail and returns:
{'success': False, 'msg': 'deviceId=null'}
it seems 2FA has been enforce by webull, and 2FA is not yet supported by the python login.
I want to test my strategies on a paper account before trying it with real money. Ideally every function in the webull class should be identical to the paper class to have the easiest migration.
It would be great to add a method for paper trading in the Webull class so one can test their trading strategy without losing money.
Most of the time I get the Websocket handshake error
when trying to connect to streaming quotes. Only out of 10 or more attempts it succeeds once.
Any clue on why it's happening? or Is it only me?
self.streamConnection.connect(did=self.wb._get_did()) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/webull/streamconn.py", line 166, in connect self.client_streaming_quotes.connect('wspush.webullbroker.com', 443, 30) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/paho/mqtt/client.py", line 937, in connect return self.reconnect() File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/paho/mqtt/client.py", line 1107, in reconnect sock = WebsocketWrapper(sock, self._host, self._port, self._ssl, File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/paho/mqtt/client.py", line 3556, in __init__ self._do_handshake(extra_headers) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/paho/mqtt/client.py", line 3640, in _do_handshake raise WebsocketConnectionError("WebSocket handshake error") paho.mqtt.client.WebsocketConnectionError: WebSocket handshake error
hi, came across this repo. Looking really neat. any way to get historicals? Thanks
so right now all i have is:
import pytest
import webull
webull = webull()
webull.login('************', '*********')
webull.get_account_id()
webull.get_trade_token('123456')
print(webull.get_account())
and all I'm getting right now is:
webull = webull()
TypeError: 'module' object is not callable
how do I fix this
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.