Metadata-Version: 2.1
Name: notbank
Version: 1.1.1a1
Summary: Notbank API client library
Home-page: https://github.com/notbank-exchange/notbank-python
Author: Notbank
Keywords: api,notbank,cryptomkt,cryptomarket,bitcoin,client
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: certifi ==2021.10.8
Requires-Dist: charset-normalizer ==2.0.12 ; python_full_version >= "3.5.0"
Requires-Dist: simplejson ==3.20.1 ; python_version >= "2.5" and python_version not in "3.0, 3.1, 3.2, 3.3"
Requires-Dist: urllib3 ==1.26.9 ; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" and python_version < "4"
Requires-Dist: requests ==2.27.1 ; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4, 3.5"
Requires-Dist: idna ==3.3 ; python_version >= "3.5"
Requires-Dist: dacite ==1.9.2 ; python_version >= "3.7"
Requires-Dist: websocket-client ==1.6.1 ; python_version >= "3.7"

# Notbank Python SDK

[main page](https://notbank.exchange)

[sign up in Notbank](https://www.cryptomkt.com/account/register).

## Installation

To install Notbank use pip

```bash
pip install notbank
```

## Documentation

This sdk makes use of the [api](https://apidoc.notbank.exchange) of Notbank.

## Quick start

### Client creation

There are two communication protocols supported by the Notbank client. Communication via websocket, and via rest. Communication via websocket requires connection and permits subscriptions, other than that they are equivalent.

```python
from notbank_python_sdk.requests_models import *
from notbank_python_sdk.client_connection_factory import new_websocket_client_connection, new_rest_client_connection
from notbank_python_sdk.error import NotbankException
from notbank_python_sdk.notbank_client import NotbankClient

# a websocket client
try:
    websocket_connection = new_websocket_client_connection()
    websocket_connection.connect()
    client = NotbankClient(websocket_connection)

    # an http client
    rest_connection = new_rest_client_connection()
    client = NotbankClient(rest_connection)
except NotbankException as e:
    print(e)
```

### Error handling

All internal notbank client and notbank server errors inherit from NotbankException, and all client methods may throw it (e.g. invalid request, request timeout, ...)

```python
# client : NotbankClient : ....
try:
    orderbook = client.get_order_book(OrderBookRequest("BTCUSDT", 1, 1))
except NotbankException as e:
    print(e)
```

### Put order at the top of book example

```python
import random
from decimal import Decimal

from notbank_python_sdk.notbank_client import NotbankClient
from notbank_python_sdk.client_connection_factory import new_websocket_client_connection

account_id: int = 13  # must be user account id

# connect to notbank
websocket_connection = new_websocket_client_connection()
websocket_connection.connect()
client = NotbankClient(websocket_connection)

# authentication (same for rest client or websocket client)
authenticate = client.authenticate(
    AuthenticateRequest(
        api_public_key="api-public-key",
        api_secret_key="api-secret-key",
        user_id="user-id",
    )
)
if not authenticate.authenticated:
    raise Exception("client not authenticated")

# get USDT user balance (also known as position)
positions = client.get_account_positions(
    GetAccountPositionsRequest(account_id))
usdt_balance = None
product = "USDT"
market_pair = "BTCUSDT"
for position in positions:
    if position.product_symbol == product:
        usdt_balance = position
if usdt_balance is None:
    raise Exception("user has no balance")

# define order_amount (between all usdt_balance and half usdt_balance)
total_balance = usdt_balance.amount
quantity_to_spend = total_balance - \
    Decimal(random.random()) * (total_balance/2)

# define order_price (around market top)
orderbook = client.get_order_book(
    OrderBookRequest(market_pair, level=2, depth=5))
top_orderbook = orderbook.bids[0]
delta = Decimal(random.randrange(10, 100))/1000
order_price = top_orderbook.price + delta
order_quantity = quantity_to_spend / order_price

# send order
instrument = client.get_instrument_by_symbol(market_pair)
request = SendOrderRequest(
    instrument=instrument,
    account_id=account_id,
    time_in_force=TimeInForce.GTC,
    side=Side.Buy,
    quantity=order_quantity,
    limit_price=order_price,
    order_type=OrderType.Limit,
)
response = client.send_order(request)

# handle order result
if response.status == SendOrderStatus.REJECTED:
    # order was rejected
    raise Exception("rejected order")
else:
    # order was accepted
    order_id = response.order_id
    print(order_id)

# disconnect
client.close()
```

## Websocket reconnection

The websocket client reconnects automatically in case of unexpected disconnection.

On reconnection the client resubscribes to what it was already subscribed before the reconnection. This means that the on_snapshot handler of subscriptions will be called once per reconnection, and on_update handlers will be continuoslly called before and after reconnections.

authentication is also kept on reconnection, by re-authenticating the new connection with the last authentication request instance
