The Python client for the Coinbase Pro API (formerly known as the GDAX)
Note: this library may be subtly broken or buggy. The code is released under the MIT License – please take the following message to heart:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This README is documentation on the syntax of the python client presented in
this repository. See function docstrings for full syntax details.
This API attempts to present a clean interface to CB Pro, but in order to use it
to its full potential, you must familiarize yourself with the official CB Pro
documentation.
https://docs.pro.coinbase.com/
You may manually install the project or use pip
:
```python
pip install cbpro
pip install git+git://github.com/danpaquin/coinbasepro-python.git ```
Only some endpoints in the API are available to everyone. The public endpoints
can be reached using PublicClient
python
import cbpro
public_client = cbpro.PublicClient()
get_products
python
public_client.get_products()
get_product_order_book ```python
public_client.get_product_order_book('BTC-USD')
public_client.get_product_order_book('BTC-USD', level=1) ```
public_client.get_product_ticker(product_id='ETH-USD') ```
public_client.get_product_trades(product_id='ETH-USD') ```
public_client.get_product_historic_rates('ETH-USD', granularity=3000) ```
get_product_24hr_stats
python
public_client.get_product_24hr_stats('ETH-USD')
get_currencies
python
public_client.get_currencies()
get_time
python
public_client.get_time()
Not all API endpoints are available to everyone.
Those requiring user authentication can be reached using AuthenticatedClient
.
You must setup API access within your
account settings.
The AuthenticatedClient
inherits all methods from the PublicClient
class, so you will only need to initialize one if you are planning to
integrate both into your script.
```python import cbpro auth_client = cbpro.AuthenticatedClient(key, b64secret, passphrase)
auth_client = cbpro.AuthenticatedClient(key, b64secret, passphrase, api_url="https://api-public.sandbox.pro.coinbase.com") ```
Some calls are paginated, meaning multiple
calls must be made to receive the full set of data. The CB Pro Python API provides
an abstraction for paginated endpoints in the form of generators which provide a
clean interface for iteration but may make multiple HTTP requests behind the
scenes. The pagination options before
, after
, and limit
may be supplied as
keyword arguments if desired, but aren't necessary for typical use cases.
```python
fills_gen = auth_client.get_fills()
all_fills = list(fills_gen)
One use case for pagination parameters worth pointing out is retrieving only
new data since the previous request. For the case of `get_fills()`, the
`trade_id` is the parameter used for indexing. By passing
`before=some_trade_id`, only fills more recent than that `trade_id` will be
returned. Note that when using `before`, a maximum of 100 entries will be
returned - this is a limitation of CB Pro.
python
from itertools import islice
recent_fills = islice(auth_client.get_fills(), 5)
before
parameter.new_fills = auth_client.get_fills(before=recent_fills[0]['trade_id']) ```
get_accounts
python
auth_client.get_accounts()
get_account
python
auth_client.get_account("7d0f7d8e-dd34-4d9c-a846-06f431c381ba")
get_account_history (paginated) ```python
auth_client.get_account_history("7d0f7d8e-dd34-4d9c-a846-06f431c381ba") ```
auth_client.get_account_holds("7d0f7d8e-dd34-4d9c-a846-06f431c381ba") ```
auth_client.buy(price='100.00', #USD
size='0.01', #BTC
order_type='limit',
product_id='BTC-USD')
python
auth_client.sell(price='200.00', #USD
size='0.01', #BTC
order_type='limit',
product_id='BTC-USD')
python
auth_client.place_limit_order(product_id='BTC-USD',
side='buy',
price='200.00',
size='0.01')
python
size
could be used to specify quantity in BTC amount.auth_client.place_market_order(product_id='BTC-USD',
side='buy',
funds='100.00')
python
funds
can be used instead of size
here.auth_client.place_stop_order(product_id='BTC-USD', stop_type='loss', price='200.00', size='0.01') ```
python
auth_client.cancel_order("d50ec984-77a8-460a-b958-66f114b0de9b")
cancel_all
python
auth_client.cancel_all(product_id='BTC-USD')
get_orders (paginated) ```python
auth_client.get_orders() ```
get_order
python
auth_client.get_order("d50ec984-77a8-460a-b958-66f114b0de9b")
get_fills (paginated) ```python
auth_client.get_fills()
auth_client.get_fills(order_id="d50ec984-77a8-460a-b958-66f114b0de9b")
auth_client.get_fills(product_id="ETH-BTC") ```
python
depositParams = {
'amount': '25.00', # Currency determined by account specified
'coinbase_account_id': '60680c98bfe96c2601f27e9c'
}
auth_client.deposit(depositParams)
```pythonwithdrawParams = { 'amount': '1.00', # Currency determined by account specified 'coinbase_account_id': '536a541fa9393bb3c7000023' } auth_client.withdraw(withdrawParams) ```
If you would like to receive real-time market updates, you must subscribe to the websocket feed.
```python import cbpro
wsClient = cbpro.WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products="BTC-USD", channels=["ticker"])
wsClient.close() ```
```python import cbpro
wsClient = cbpro.WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products=["BTC-USD", "ETH-USD"], channels=["ticker"])
wsClient.close() ```
The WebsocketClient
now supports data gathering via MongoDB. Given a
MongoDB collection, the WebsocketClient
will stream results directly into
the database collection.
```python
from pymongo import MongoClient import cbpro mongo_client = MongoClient('mongodb://localhost:27017/')
db = mongo_client.cryptocurrency_database BTC_collection = db.BTC_collection
wsClient = cbpro.WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products="BTC-USD", mongo_collection=BTC_collection, should_print=False) wsClient.start() ```
The WebsocketClient
subscribes in a separate thread upon initialization.
There are three methods which you could overwrite (before initialization) so it
can react to the data streaming in. The current client is a template used for
illustration purposes only.
wsClient = myWebsocketClient() wsClient.start() print(wsClient.url, wsClient.products) while (wsClient.message_count < 500): print ("\nmessage_count =", "{} \n".format(wsClient.message_count)) time.sleep(1) wsClient.close() ```
A test suite is under development. Tests for the authenticated client require a
set of sandbox API credentials. To provide them, rename
api_config.json.example
in the tests folder to api_config.json
and edit the
file accordingly. To run the tests, start in the project directory and run
python -m pytest
The OrderBook
is a convenient data structure to keep a real-time record of
the orderbook for the product_id input. It processes incoming messages from an
already existing WebsocketClient. Please provide your feedback for future
improvements.
```python import cbpro, time, Queue class myWebsocketClient(cbpro.WebsocketClient): def on_open(self): self.products = ['BTC-USD', 'ETH-USD'] self.order_book_btc = OrderBookConsole(product_id='BTC-USD') self.order_book_eth = OrderBookConsole(product_id='ETH-USD') def on_message(self, msg): self.order_book_btc.process_message(msg) self.order_book_eth.process_message(msg)
wsClient = myWebsocketClient() wsClient.start() time.sleep(10) while True: print(wsClient.order_book_btc.get_ask()) print(wsClient.order_book_eth.get_bid()) time.sleep(1) ```
Unit tests are under development using the pytest framework. Contributions are welcome!
To run the full test suite, in the project
directory run:
bash
python -m pytest
1.1.2 Current PyPI release - Refactor project for Coinbase Pro - Major overhaul on how pagination is handled
1.0 - The first release that is not backwards compatible - Refactored to follow PEP 8 Standards - Improved Documentation
0.3 - Added crypto and LTC deposit & withdraw (undocumented). - Added support for Margin trading (undocumented). - Enhanced functionality of the WebsocketClient. - Soft launch of the OrderBook (undocumented). - Minor bug squashing & syntax improvements.
0.2.2 - Added additional API functionality such as cancelAll() and ETH withdrawal.
0.2.1
- Allowed WebsocketClient
to operate intuitively and restructured example
workflow.
0.2.0 - Renamed project to GDAX-Python - Merged Websocket updates to handle errors and reconnect.
0.1.2 - Updated JSON handling for increased compatibility among some users. - Added support for payment methods, reports, and Coinbase user accounts. - Other compatibility updates.
0.1.1b2 - Original PyPI Release.
Many changes in Coinbase's API have been rolled out in the last year. https://docs.cloud.coinbase.com/exchange/docs/changelog
In particular, this change https://docs.cloud.coinbase.com/exchange/docs/changelog#2022-jun-27 makes the websocket to disconnect, whenever new_price or old_price fields appear.
I fixed this part in my fork, but I didn't submit a PR because of lack of time. It would be great if someone could work on this and check that everything works fine.
https://github.com/segurac/coinbasepro-python/commit/f91977da44d76d036f0bcad8702484af2d7ad608
Now that I see some activity in the repo I remembered my patches. It could be a good time to create a small community and maintain this awesome library together.
Bumps certifi from 2018.10.15 to 2022.12.7.
9e9e840
2022.12.07b81bdb2
2022.09.24939a28f
2022.09.14aca828a
2022.06.15.2de0eae1
Only use importlib.resources's new files() / Traversable API on Python ≥3.11 ...b8eb5e9
2022.06.15.147fb7ab
Fix deprecation warning on Python 3.11 (#199)b0b48e0
fixes #198 -- update link in license9d514b4
2022.06.154151e88
Add py.typed to MANIFEST.in to package in sdist (#196)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase
.
I've the following class for retrieving data from websocket and convert them in a format usable by my program:
``` from curses import cbreak import cbpro import logging import schedule import time import sys
log_formatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s") root_logger = logging.getLogger() file_handler = logging.FileHandler("cbpro.log") file_handler.setFormatter(log_formatter) root_logger.addHandler(file_handler)
console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(log_formatter) root_logger.addHandler(console_handler) root_logger.setLevel(logging.DEBUG)
class CBProFeed(cbpro.WebsocketClient): def init(self): cbpro.WebsocketClient.init(self) self.public_client = cbpro.PublicClient() self.main_currency = 'EUR' self.crypto_currencies = ['AUCTION'] self.products = ['AUCTION-EUR']
def on_open(self): self.url = "wss://ws-feed.pro.coinbase.com/" self.channels=["ticker"]
def on_message(self, msg): if 'price' in msg and 'type' in msg and msg['type'] == 'ticker': product_id = msg['product_id'] price = float(msg['price']) volume = float(msg['volume_24h']) logging.info("Received " + product_id + ", Price is " + str(price) + ". Volume 24H is " + str(volume));
def on_close(self): logging.info("Websocket connection closed")
def run_forever(self): logging.info("Starting feed") schedule.every().minute.at(':00').do(self._handle_candle_callback) self.start() while True: schedule.run_pending() time.sleep(.1); if (self.error): logging.error("Connection closed. Error is " + str(self.error) + ". Restarting...") self.close() self.error = None self.start()
def _handle_candle_callback(self): logging.debug("Minute processed")
feed = CBProFeed() feed.run_forever() logging.info("End of the script") ```
It works, except for the fact that the connection resets about every two minutes. This is the log when I run it:
...
2022-08-01 14:20:39,367 [MainThread ] [INFO ] Starting feed
2022-08-01 14:20:40,016 [Thread-1 ] [INFO ] Received AUCTION-EUR, Price is 7.52. Volume 24H is 7511.306
2022-08-01 14:21:00,003 [MainThread ] [DEBUG] Running job Job(interval=1, unit=minutes, do=_handle_candle_callback, args=(), kwargs={})
2022-08-01 14:21:00,003 [MainThread ] [DEBUG] Minute processed
2022-08-01 14:22:00,023 [MainThread ] [DEBUG] Running job Job(interval=1, unit=minutes, do=_handle_candle_callback, args=(), kwargs={})
2022-08-01 14:22:00,023 [MainThread ] [DEBUG] Minute processed
Connection is already closed. - data: None
2022-08-01 14:22:20,089 [Thread-1 ] [INFO ] Websocket connection closed
2022-08-01 14:22:20,147 [MainThread ] [ERROR] Connection closed. Error is Connection is already closed.. Restarting...
2022-08-01 14:22:20,829 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.52. Volume 24H is 7511.306
2022-08-01 14:22:34,593 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.53. Volume 24H is 7667.951
2022-08-01 14:22:41,850 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.53. Volume 24H is 7668.243
2022-08-01 14:22:46,204 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.54. Volume 24H is 7667.951
2022-08-01 14:22:46,247 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.55. Volume 24H is 7670.651
2022-08-01 14:22:46,798 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.56. Volume 24H is 7673.351
2022-08-01 14:22:46,996 [Thread-2 ] [INFO ] Received AUCTION-EUR, Price is 7.57. Volume 24H is 7676.051
2022-08-01 14:23:00,014 [MainThread ] [DEBUG] Running job Job(interval=1, unit=minutes, do=_handle_candle_callback, args=(), kwargs={})
2022-08-01 14:23:00,015 [MainThread ] [DEBUG] Minute processed
2022-08-01 14:24:00,052 [MainThread ] [DEBUG] Running job Job(interval=1, unit=minutes, do=_handle_candle_callback, args=(), kwargs={})
2022-08-01 14:24:00,052 [MainThread ] [DEBUG] Minute processed
Connection is already closed. - data: None
2022-08-01 14:24:27,123 [Thread-2 ] [INFO ] Websocket connection closed
2022-08-01 14:24:27,129 [MainThread ] [ERROR] Connection closed. Error is Connection is already closed.. Restarting...
2022-08-01 14:24:27,788 [Thread-3 ] [INFO ] Received AUCTION-EUR, Price is 7.57. Volume 24H is 7679.043
...
That are logs that appear when on_close
is called. What I'm doing wrong and how can solve the problem?
I've been doing CS50 and now I'm in my final project. I need this library so much for it but I keep getting so many erros after install. Please help me
https://stackoverflow.com/questions/72680275/can-i-make-this-requires-compatible
Hi, I wanna use this wrapping of coinbase pro api in an application written using python 3.10. But I got an issue while creating a PublicClient. This seems to be related to the python version cause when I made tests in a python 3.9 env everything works fine. An update will be welcome so. Thanks
Adding timeout parameters support
python-client websocket-client coinbase exchange wrapper libaray orderbook bitcoin ethereum trading coinbasepro coinbasepro-api cbpro