Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
47fcc4a
update gitignore
carlosmiei Feb 27, 2025
7399a42
Merge branch 'master' of github.com:sammchardy/python-binance
carlosmiei Feb 27, 2025
2ed81d9
Merge branch 'master' of github.com:sammchardy/python-binance
carlosmiei Feb 27, 2025
890d191
Merge branch 'master' of github.com:sammchardy/python-binance
carlosmiei May 19, 2025
00d9d34
bump version
carlosmiei May 19, 2025
8b37156
Merge branch 'master' of github.com:sammchardy/python-binance
carlosmiei Sep 23, 2025
14b08b5
feat: add demo trading support
carlosmiei Sep 23, 2025
c440827
update url
carlosmiei Sep 23, 2025
92cd227
add futures helper methods
carlosmiei Sep 24, 2025
b13d3a8
update conf test
carlosmiei Sep 24, 2025
f8abe00
fix missing url
carlosmiei Sep 24, 2025
327e1e4
8911
carlosmiei Sep 24, 2025
d37715b
rm proxy none
carlosmiei Sep 24, 2025
4f56189
update ws_futures_demo_url
carlosmiei Sep 26, 2025
4a32a95
skip failing test and update options symbol
pcriadoperez Sep 27, 2025
4169ef6
remove 3.7
pcriadoperez Sep 27, 2025
404708d
temporarly only test 3.12
pcriadoperez Sep 27, 2025
96b65bd
add several fixes including parallel testing
pcriadoperez Sep 28, 2025
2bd9539
fix failing tests
pcriadoperez Sep 28, 2025
3f90ef9
run all tox versions
pcriadoperez Sep 28, 2025
bbe1ebd
update proxy on github action
pcriadoperez Sep 28, 2025
fd8a6ea
add timeout
pcriadoperez Sep 28, 2025
29b0e00
fix ws proxy
pcriadoperez Sep 28, 2025
a64cbd1
add proxy fix for async ws client
pcriadoperez Sep 28, 2025
2e82f83
add fix for for options tests
pcriadoperez Sep 28, 2025
b90af45
fix failing tests
pcriadoperez Sep 29, 2025
0b5161d
fix lint
pcriadoperez Sep 29, 2025
98855f2
run all tox versions
pcriadoperez Sep 29, 2025
b588562
add max parallel to 1
pcriadoperez Sep 29, 2025
279f9a1
skip ws proxy for py37
pcriadoperez Sep 29, 2025
1b1b93c
comment options test for py37
pcriadoperez Sep 29, 2025
fd022e2
remove 3.7
pcriadoperez Sep 29, 2025
fa5e187
increase max parallel to 2
pcriadoperez Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ Features

- Implementation of all General, Market Data and Account endpoints.
- Asyncio implementation
- Testnet support for Spot, Futures and Vanilla Options
- Demo trading support (by providing demo=True)
- Testnet support for Spot, Futures and Vanilla Options (deprecated)
- Simple handling of authentication include RSA and EDDSA keys
- No need to generate timestamps yourself, the wrapper does it for you
- RecvWindow sent by default
Expand Down
4 changes: 4 additions & 0 deletions binance/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def __init__(
tld: str = "com",
base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT,
testnet: bool = False,
demo: bool = False,
loop=None,
session_params: Optional[Dict[str, Any]] = None,
private_key: Optional[Union[str, Path]] = None,
Expand All @@ -48,6 +49,7 @@ def __init__(
tld,
base_endpoint,
testnet,
demo,
private_key,
private_key_pass,
time_unit=time_unit,
Expand All @@ -62,6 +64,7 @@ async def create(
tld: str = "com",
base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT,
testnet: bool = False,
demo: bool = False,
loop=None,
session_params: Optional[Dict[str, Any]] = None,
private_key: Optional[Union[str, Path]] = None,
Expand All @@ -76,6 +79,7 @@ async def create(
tld,
base_endpoint,
testnet,
demo,
loop,
session_params,
private_key,
Expand Down
13 changes: 13 additions & 0 deletions binance/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,28 @@
class BaseClient:
API_URL = "https://api{}.binance.{}/api"
API_TESTNET_URL = "https://testnet.binance.vision/api"
API_DEMO_URL = "https://demo-api.binance.com/api"
MARGIN_API_URL = "https://api{}.binance.{}/sapi"
WEBSITE_URL = "https://www.binance.{}"
FUTURES_URL = "https://fapi.binance.{}/fapi"
FUTURES_TESTNET_URL = "https://testnet.binancefuture.com/fapi"
FUTURES_DEMO_URL = "https://demo-fapi.binance.com/fapi"
FUTURES_DATA_URL = "https://fapi.binance.{}/futures/data"
FUTURES_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
FUTURES_COIN_URL = "https://dapi.binance.{}/dapi"
FUTURES_COIN_TESTNET_URL = "https://testnet.binancefuture.com/dapi"
FUTURES_COIN_DEMO_URL = "https://demo-dapi.binance.com/dapi"
FUTURES_COIN_DATA_URL = "https://dapi.binance.{}/futures/data"
FUTURES_COIN_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
OPTIONS_URL = "https://eapi.binance.{}/eapi"
OPTIONS_TESTNET_URL = "https://testnet.binanceops.{}/eapi"
PAPI_URL = "https://papi.binance.{}/papi"
WS_API_URL = "wss://ws-api.binance.{}/ws-api/v3"
WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3"
WS_API_DEMO_URL = "wss://demo-ws-api.binance.com/ws-api/v3"
WS_FUTURES_URL = "wss://ws-fapi.binance.{}/ws-fapi/v1"
WS_FUTURES_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1"
WS_FUTURES_DEMO_URL = "wss://demo-ws-fapi.binance.com/ws-fapi/v1"
PUBLIC_API_VERSION = "v3"
PRIVATE_API_VERSION = "v3"
MARGIN_API_VERSION = "v1"
Expand Down Expand Up @@ -157,6 +162,7 @@ def __init__(
tld: str = "com",
base_endpoint: str = BASE_ENDPOINT_DEFAULT,
testnet: bool = False,
demo: bool = False,
private_key: Optional[Union[str, Path]] = None,
private_key_pass: Optional[str] = None,
loop: Optional[asyncio.AbstractEventLoop] = None,
Expand Down Expand Up @@ -201,6 +207,7 @@ def __init__(
self._requests_params = requests_params
self.response = None
self.testnet = testnet
self.demo = demo
self.timestamp_offset = 0
ws_api_url = self.WS_API_TESTNET_URL if testnet else self.WS_API_URL.format(tld)
if self.TIME_UNIT:
Expand Down Expand Up @@ -250,6 +257,8 @@ def _create_api_uri(
url = self.API_URL
if self.testnet:
url = self.API_TESTNET_URL
elif self.demo:
url = self.API_DEMO_URL
v = self.PRIVATE_API_VERSION if signed else version
return url + "/" + v + "/" + path

Expand All @@ -273,6 +282,8 @@ def _create_futures_api_uri(self, path: str, version: int = 1) -> str:
url = self.FUTURES_URL
if self.testnet:
url = self.FUTURES_TESTNET_URL
elif self.demo:
url = self.FUTURES_DEMO_URL
options = {
1: self.FUTURES_API_VERSION,
2: self.FUTURES_API_VERSION2,
Expand All @@ -290,6 +301,8 @@ def _create_futures_coin_api_url(self, path: str, version: int = 1) -> str:
url = self.FUTURES_COIN_URL
if self.testnet:
url = self.FUTURES_COIN_TESTNET_URL
elif self.demo:
url = self.FUTURES_COIN_DEMO_URL
options = {
1: self.FUTURES_API_VERSION,
2: self.FUTURES_API_VERSION2,
Expand Down
4 changes: 3 additions & 1 deletion binance/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __init__(
tld: str = "com",
base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT,
testnet: bool = False,
demo: bool = False,
private_key: Optional[Union[str, Path]] = None,
private_key_pass: Optional[str] = None,
ping: Optional[bool] = True,
Expand All @@ -41,6 +42,7 @@ def __init__(
tld,
base_endpoint,
testnet,
demo,
private_key,
private_key_pass,
time_unit=time_unit,
Expand Down Expand Up @@ -13999,7 +14001,7 @@ def futures_historical_data_link(self, **params):
"data": [
{
"day": "2023-06-30",
"url": "https://bin-prod-user-rebate-bucket.s3.ap-northeast-1.amazonaws.com/future-data-symbol-update/2023-06-30/BTCUSDT_T_DEPTH_2023-06-30.tar.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230925T025710Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86399&X-Amz-Credential=AKIAVL364M5ZNFZ74IPP%2F20230925%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Signature=5fffcb390d10f34d71615726f81f99e42d80a11532edeac77b858c51a88cbf59"
"url": ""
}
]
}
Expand Down
25 changes: 25 additions & 0 deletions binance/ws/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ class BinanceSocketType(str, Enum):
class BinanceSocketManager:
STREAM_URL = "wss://stream.binance.{}:9443/"
STREAM_TESTNET_URL = "wss://stream.testnet.binance.vision/"
STREAM_DEMO_URL = "wss://demo-stream.binance.com/"
FSTREAM_URL = "wss://fstream.binance.{}/"
FSTREAM_TESTNET_URL = "wss://stream.binancefuture.com/"
FSTREAM_DEMO_URL = "wss://fstream.binancefuture.com/"
DSTREAM_URL = "wss://dstream.binance.{}/"
DSTREAM_TESTNET_URL = "wss://dstream.binancefuture.com/"
DSTREAM_DEMO_URL = "wss://dstream.binancefuture.com/"
OPTIONS_URL = "wss://nbstream.binance.{}/eoptions/"

WEBSOCKET_DEPTH_5 = "5"
Expand Down Expand Up @@ -60,6 +63,7 @@ def __init__(
self._client = client
self._user_timeout = user_timeout
self.testnet = self._client.testnet
self.demo = self._client.demo
self._max_queue_size = max_queue_size
self.ws_kwargs = {}

Expand All @@ -69,6 +73,8 @@ def _get_stream_url(self, stream_url: Optional[str] = None):
stream_url = self.STREAM_URL
if self.testnet:
stream_url = self.STREAM_TESTNET_URL
elif self.demo:
stream_url = self.STREAM_DEMO_URL
return stream_url

def _get_socket(
Expand Down Expand Up @@ -128,10 +134,14 @@ def _get_futures_socket(
stream_url = self.FSTREAM_URL
if self.testnet:
stream_url = self.FSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.FSTREAM_DEMO_URL
else:
stream_url = self.DSTREAM_URL
if self.testnet:
stream_url = self.DSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.DSTREAM_DEMO_URL
return self._get_socket(path, stream_url, prefix, socket_type=socket_type)

def _get_options_socket(self, path: str, prefix: str = "ws/"):
Expand Down Expand Up @@ -907,6 +917,8 @@ def user_socket(self):
stream_url = self.STREAM_URL
if self.testnet:
stream_url = self.STREAM_TESTNET_URL
elif self.demo:
stream_url = self.STREAM_DEMO_URL
return self._get_account_socket("user", stream_url=stream_url)

def futures_user_socket(self):
Expand All @@ -922,6 +934,8 @@ def futures_user_socket(self):
stream_url = self.FSTREAM_URL
if self.testnet:
stream_url = self.FSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.FSTREAM_DEMO_URL
return self._get_account_socket("futures", stream_url=stream_url)

def coin_futures_user_socket(self):
Expand All @@ -948,8 +962,11 @@ def margin_socket(self):
stream_url = self.STREAM_URL
if self.testnet:
stream_url = self.STREAM_TESTNET_URL
elif self.demo:
stream_url = self.STREAM_DEMO_URL
return self._get_account_socket("margin", stream_url=stream_url)


def futures_socket(self):
"""Start a websocket for futures data

Expand All @@ -962,6 +979,8 @@ def futures_socket(self):
stream_url = self.FSTREAM_URL
if self.testnet:
stream_url = self.FSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.FSTREAM_DEMO_URL
return self._get_account_socket("futures", stream_url=stream_url)

def coin_futures_socket(self):
Expand All @@ -976,6 +995,8 @@ def coin_futures_socket(self):
stream_url = self.DSTREAM_URL
if self.testnet:
stream_url = self.DSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.DSTREAM_DEMO_URL
return self._get_account_socket("coin_futures", stream_url=stream_url)

def portfolio_margin_socket(self):
Expand All @@ -990,6 +1011,8 @@ def portfolio_margin_socket(self):
stream_url = self.FSTREAM_URL
if self.testnet:
stream_url = self.FSTREAM_TESTNET_URL
elif self.demo:
stream_url = self.FSTREAM_DEMO_URL
stream_url += "pm/"
return self._get_account_socket("portfolio_margin", stream_url=stream_url)

Expand All @@ -1008,6 +1031,8 @@ def isolated_margin_socket(self, symbol: str):
stream_url = self.STREAM_URL
if self.testnet:
stream_url = self.STREAM_TESTNET_URL
elif self.demo:
stream_url = self.STREAM_DEMO_URL
return self._get_account_socket(symbol, stream_url=stream_url)

def options_ticker_socket(self, symbol: str):
Expand Down
Loading