Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
# Changelog

## 1.2.0 - 2026-02-02

### Added
- Added a `restart` flag to the `FixConnector` connector to restart when receiving a `NEWS` message.

### Updated
- Updated `retrieve_messages_until` method to accept a list of message types.
- Fixed messages parsing issue that caused the error: `Field missing '=' separator`.

## 1.1.0 - 2025-10-27

### Updated
- Added parameters `min_price`, `max_price` and `min_price_increment` to `InstrumentList` response.

## 1.0.1 - 2025-05-08

### Removed
- Removed the references for `auto-reconnect` in the dropcopy session to fix the following [issue](https://github.com/binance/binance-fix-connector-python/issues/2).

Expand Down
47 changes: 13 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,29 @@ pip install binance-fix-connector
All the FIX messages can be created with the `BinanceFixConnector` class. The following example demonstrates how to create a simple order using the FIX API:
```python
import time
import os
from pathlib import Path

from binance_fix_connector.fix_connector import create_order_entry_session
from binance_fix_connector.utils import get_api_key, get_private_key
from constants import (
path,
FIX_OE_URL,
INSTRUMENT,
ORD_REJECT_REASON,
ORD_STATUS,
ORD_TYPES,
SIDES,
TIME_IN_FORCE,
)

# Credentials
path = config_path = os.path.join(
Path(__file__).parent.resolve(), "..", "config.ini"
)
API_KEY, PATH_TO_PRIVATE_KEY_PEM_FILE = get_api_key(path)

# FIX URL
FIX_OE_URL = "tcp+tls://fix-oe.testnet.binance.vision:9000"

# Response types
ORD_STATUS = {
"0": "NEW",
"1": "PARTIALLY_FILLED",
"2": "FILLED",
"4": "CANCELED",
"6": "PENDING_CANCEL",
"8": "REJECTED",
"A": "PENDING_NEW",
"C": "EXPIRED",
}
ORD_TYPES = {"1": "MARKET", "2": "LIMIT", "3": "STOP", "4": "STOP_LIMIT"}
SIDES = {"1": "BUY", "2": "SELL"}
TIME_IN_FORCE = {
"1": "GOOD_TILL_CANCEL",
"3": "IMMEDIATE_OR_CANCEL",
"4": "FILL_OR_KILL",
}
ORD_REJECT_REASON = {"99": "OTHER"}

# Parameter
INSTRUMENT = "BNBUSDT"

client_oe = create_order_entry_session(
api_key=API_KEY,
private_key=get_private_key(PATH_TO_PRIVATE_KEY_PEM_FILE),
endpoint=FIX_OE_URL,
)
client_oe.retrieve_messages_until(message_type="A")
client_oe.retrieve_messages_until(message_type=["A"])

example = "This example shows how to place a single order. Order type LIMIT.\nCheck https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md#newordersingled for additional types."
client_oe.logger.info(example)
Expand All @@ -79,7 +58,7 @@ msg.append_pair(59, 1) # TIME IN FORCE
client_oe.send_message(msg)


responses = client_oe.retrieve_messages_until(message_type="8")
responses = client_oe.retrieve_messages_until(message_type=["8"])
resp = next(
(x for x in responses if x.message_type.decode("utf-8") == "8"),
None,
Expand Down Expand Up @@ -118,7 +97,7 @@ client_oe.logger.info(f"Error code: {error_code} | Reason: {text}")
# LOGOUT
client_oe.logger.info("LOGOUT (5)")
client_oe.logout()
client_oe.retrieve_messages_until(message_type="5")
client_oe.retrieve_messages_until(message_type=["5"])
client_oe.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand Down
2 changes: 1 addition & 1 deletion examples/config.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

[keys]
API_KEY =
PATH_TO_PRIVATE_KEY_PEM_FILE =
PATH_TO_PRIVATE_KEY_PEM_FILE =
52 changes: 52 additions & 0 deletions examples/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import os
from pathlib import Path

# FIX URLs
FIX_OE_URL = "tcp+tls://fix-oe.testnet.binance.vision:9000"
FIX_MD_URL = "tcp+tls://fix-md.testnet.binance.vision:9000"

# Credentials
path = os.path.join(Path(__file__).parent.resolve(), "config.ini")

# Response types
ACTION = {"0": "NEW", "1": "CHANGE", "2": "DELETE"}
AGGRESSOR_SIDE = {"1": "BUY", "2": "SELL"}
CONTINGENCY_TYPE = {
"1": "ONE_CANCELS_THE_OTHER ",
"2": "ONE_TRIGGERS_THE_OTHER",
}
LIMIT_TYPES = {"1": "ORDER_LIMIT", "2": "MESSAGE_LIMIT", "3": "SUBSCRIPTION_LIMIT"}
LIST_ORD_STATUS = {"3": "EXECUTING", "6": "ALL_DONE", "7": "REJECT"}
LIST_ORD_TYPE = {"1": "ONE_CANCELS_THE_OTHER", "2": "ONE_TRIGGERS_THE_OTHER"}
LIST_STATUS_TYPE = {
"2": "RESPONSE",
"4": "EXEC_STARTED",
"5": "ALL_DONE",
"100": "UPDATED",
}
LIST_TRIG_TYPE = {"ACTIVATED": "1", "PARTIALLY_FILLED": "2", "FILLED": "3"}
LIST_TRIG_ACTION = {"RELEASE": "1", "CANCEL": "2"}
ORD_STATUS = {
"0": "NEW",
"1": "PARTIALLY_FILLED",
"2": "FILLED",
"4": "CANCELED",
"6": "PENDING_CANCEL",
"8": "REJECTED",
"A": "PENDING_NEW",
"C": "EXPIRED",
}
ORD_TYPES = {"1": "MARKET", "2": "LIMIT", "3": "STOP", "4": "STOP_LIMIT", "P": "PEGGED"}
ORD_REJECT_REASON = {"99": "OTHER"}
RESOLUTIONS = {"s": "SECOND", "m": "MINUTE", "h": "HOUR", "d": "DAY"}
SIDES = {"1": "BUY", "2": "SELL"}
TIME_IN_FORCE = {
"1": "GOOD_TILL_CANCEL",
"3": "IMMEDIATE_OR_CANCEL",
"4": "FILL_OR_KILL",
}
UPDATE = {"0": "BID", "1": "OFFER", "2": "TRADE"}

# Parameters
INSTRUMENT = "BNBUSDT"
TIMEOUT_SECONDS = 20
Empty file added examples/general/__init__.py
Empty file.
23 changes: 6 additions & 17 deletions examples/general/current_messages_limit_rate.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
#!/usr/bin/env python3

import os
from pathlib import Path

from binance_fix_connector.fix_connector import (
BinanceFixConnector,
create_market_data_session,
create_order_entry_session,
)
from binance_fix_connector.utils import get_api_key, get_private_key
from constants import path, RESOLUTIONS, LIMIT_TYPES, FIX_OE_URL, FIX_MD_URL

# Credentials
path = config_path = os.path.join(Path(__file__).parent.resolve(), "..", "config.ini")
API_KEY, PATH_TO_PRIVATE_KEY_PEM_FILE = get_api_key(path)

# FIX URLs
FIX_OE_URL = "tcp+tls://fix-oe.testnet.binance.vision:9000"
FIX_MD_URL = "tcp+tls://fix-md.testnet.binance.vision:9000"

# Response types
RESOLUTIONS = {"s": "SECOND", "m": "MINUTE", "h": "HOUR", "d": "DAY"}
LIMIT_TYPES = {"1": "ORDER_LIMIT", "2": "MESSAGE_LIMIT", "3": "SUBSCRIPTION_LIMIT"}


def show_rendered_limit_session(client: BinanceFixConnector) -> None:
"""Show the current LIMITS the session has."""
responses = client.retrieve_messages_until(message_type="XLR")
responses = client.retrieve_messages_until(message_type=["XLR"])
for msg in responses:
if msg.message_type.decode("utf-8") == "XLR":
limits = 0 if not msg.get(25003) else int(msg.get(25003).decode("utf-8"))
Expand Down Expand Up @@ -73,7 +62,7 @@ def show_rendered_limit_session(client: BinanceFixConnector) -> None:
private_key=get_private_key(PATH_TO_PRIVATE_KEY_PEM_FILE),
endpoint=FIX_OE_URL,
)
client_oe.retrieve_messages_until(message_type="A")
client_oe.retrieve_messages_until(message_type=["A"])

example = "This example shows how to query for current session limits and how to parse it's data. Check https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md#limitqueryxlq for additional information."
client_oe.logger.info(example)
Expand All @@ -87,7 +76,7 @@ def show_rendered_limit_session(client: BinanceFixConnector) -> None:
# LOGOUT
client_oe.logger.info("LOGOUT (5)")
client_oe.logout()
client_oe.retrieve_messages_until(message_type="5")
client_oe.retrieve_messages_until(message_type=["5"])
client_oe.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand All @@ -99,7 +88,7 @@ def show_rendered_limit_session(client: BinanceFixConnector) -> None:
private_key=get_private_key(PATH_TO_PRIVATE_KEY_PEM_FILE),
endpoint=FIX_MD_URL,
)
client_md.retrieve_messages_until(message_type="A")
client_md.retrieve_messages_until(message_type=["A"])

example = "This example shows how to query for current session limits and how to parse it's data. Check https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md for additional information."
client_md.logger.info(example)
Expand All @@ -113,7 +102,7 @@ def show_rendered_limit_session(client: BinanceFixConnector) -> None:
# LOGOUT
client_md.logger.info("LOGOUT (5)")
client_md.logout()
client_md.retrieve_messages_until(message_type="5")
client_md.retrieve_messages_until(message_type=["5"])
client_md.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand Down
14 changes: 3 additions & 11 deletions examples/general/instrument_list.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
#!/usr/bin/env python3

import time
import os
from pathlib import Path

from binance_fix_connector.fix_connector import (
BinanceFixConnector,
create_market_data_session,
)
from binance_fix_connector.utils import get_api_key, get_private_key
from constants import path, FIX_MD_URL

# Credentials
path = config_path = os.path.join(Path(__file__).parent.resolve(), "..", "config.ini")
API_KEY, PATH_TO_PRIVATE_KEY_PEM_FILE = get_api_key(path)

# FIX URL
FIX_MD_URL = "tcp+tls://fix-md.testnet.binance.vision:9000"

# Parameters
INSTRUMENT = "BNBUSDT"


def show_rendered_instrument_list(client: BinanceFixConnector) -> None:
"""Show the instrument list messages received."""
Expand Down Expand Up @@ -102,7 +94,7 @@ def show_rendered_instrument_list(client: BinanceFixConnector) -> None:
private_key=get_private_key(PATH_TO_PRIVATE_KEY_PEM_FILE),
endpoint=FIX_MD_URL,
)
client_md.retrieve_messages_until(message_type="A")
client_md.retrieve_messages_until(message_type=["A"])

example = "This example shows how to query information about active instruments.\nCheck https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md#instrumentlistrequestx for additional types."
client_md.logger.info(example)
Expand All @@ -125,7 +117,7 @@ def show_rendered_instrument_list(client: BinanceFixConnector) -> None:
# LOGOUT
client_md.logger.info("LOGOUT (5)")
client_md.logout()
client_md.retrieve_messages_until(message_type="5")
client_md.retrieve_messages_until(message_type=["5"])
client_md.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env python3

import time
import os
from pathlib import Path
from datetime import datetime, timedelta


Expand All @@ -11,26 +9,15 @@
create_market_data_session,
)
from binance_fix_connector.utils import get_api_key, get_private_key
from constants import path, ACTION, FIX_MD_URL, INSTRUMENT, UPDATE, TIMEOUT_SECONDS

# Credentials
path = config_path = os.path.join(Path(__file__).parent.resolve(), "..", "config.ini")
API_KEY, PATH_TO_PRIVATE_KEY_PEM_FILE = get_api_key(path)

# FIX URLs
FIX_MD_URL = "tcp+tls://fix-md.testnet.binance.vision:9000"

# Response types
UPDATE = {"0": "BID", "1": "OFFER", "2": "TRADE"}
ACTION = {"0": "NEW", "1": "CHANGE", "2": "DELETE"}

# Parameters
INSTRUMENT = "BNBUSDT"
TIMEOUT_SECONDS = 20


def show_rendered_snapshot_message(client: BinanceFixConnector) -> None:
"""Show the snapshot message received."""
responses = client.retrieve_messages_until(message_type="W")
responses = client.retrieve_messages_until(message_type=["W"])
for msg in responses:
if msg.message_type.decode("utf-8") == "W":
client.logger.info("Parsing a MarketDataSnapshot (W) ...")
Expand Down Expand Up @@ -115,7 +102,7 @@ def show_rendered_market_depth_stream(client: BinanceFixConnector) -> None:
private_key=get_private_key(PATH_TO_PRIVATE_KEY_PEM_FILE),
endpoint=FIX_MD_URL,
)
client_md.retrieve_messages_until(message_type="A")
client_md.retrieve_messages_until(message_type=["A"])

example = "This example shows how to subscribe to a book depth stream.\nCheck https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md#diffdepthstream for additional types."
client_md.logger.info(example)
Expand Down Expand Up @@ -166,7 +153,7 @@ def show_rendered_market_depth_stream(client: BinanceFixConnector) -> None:
# LOGOUT
client_md.logger.info("LOGOUT (5)")
client_md.logout()
client_md.retrieve_messages_until(message_type="5")
client_md.retrieve_messages_until(message_type=["5"])
client_md.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
#!/usr/bin/env python3

import time
import os
from pathlib import Path
from datetime import datetime, timedelta

from binance_fix_connector.fix_connector import (
BinanceFixConnector,
create_market_data_session,
)
from binance_fix_connector.utils import get_api_key, get_private_key
from constants import path, ACTION, FIX_MD_URL, INSTRUMENT, UPDATE, TIMEOUT_SECONDS

# Credentials
path = config_path = os.path.join(Path(__file__).parent.resolve(), "..", "config.ini")
API_KEY, PATH_TO_PRIVATE_KEY_PEM_FILE = get_api_key(path)

# FIX URL
FIX_MD_URL = "tcp+tls://fix-md.testnet.binance.vision:9000"

# Response types
UPDATE = {"0": "BID", "1": "OFFER", "2": "TRADE"}

# Parameters
INSTRUMENT = "BNBUSDT"
TIMEOUT_SECONDS = 20


def show_rendered_snapshot_message(client: BinanceFixConnector) -> None:
"""Show the snapshot message received."""
responses = client.retrieve_messages_until(message_type="W")
responses = client.retrieve_messages_until(message_type=["W"])
for msg in responses:
if msg.message_type.decode("utf-8") == "W":
client.logger.info("Parsing a MarketDataSnapshot (W) ...")
Expand Down Expand Up @@ -106,7 +94,7 @@ def show_rendered_market_book_ticker_stream(client: BinanceFixConnector) -> None
endpoint=FIX_MD_URL,
recv_window=100,
)
client_md.retrieve_messages_until(message_type="A")
client_md.retrieve_messages_until(message_type=["A"])

example = "This example shows how to subscribe to a book ticker stream.\nCheck https://github.com/binance/binance-spot-api-docs/blob/master/fix-api.md#symbolbooktickerstream for additional types."
client_md.logger.info(example)
Expand Down Expand Up @@ -157,7 +145,7 @@ def show_rendered_market_book_ticker_stream(client: BinanceFixConnector) -> None
# LOGOUT
client_md.logger.info("LOGOUT (5)")
client_md.logout()
client_md.retrieve_messages_until(message_type="5")
client_md.retrieve_messages_until(message_type=["5"])
client_md.logger.info(
"Closing the connection with server as we already sent the logout message"
)
Expand Down
Loading