Skip to main content

Python client for the Alfax Trade API (Binance-compatible).

Project description

alfax Python SDK

First-party Python 3.12+ client for the Alfax Trade API.

The endpoint paths, request/response schemas, authentication, and WebSocket stream formats are byte-compatible with Binance Futures USDT-M. Existing ccxt, python-binance, Freqtrade, and Hummingbot strategies work by changing only the base_url.

Install

pip install alfax
# with dev/test tools:
pip install "alfax[dev]"

Quick start

import os
from alfax import Client

c = Client(
    api_key=os.environ["ALFAX_KEY"],
    api_secret=os.environ["ALFAX_SECRET"],
    base_url="https://api.alfax.trade",   # default
)

# Public endpoints (no auth required)
print(c.ping())                          # {}
print(c.server_time())                   # 1700000000000
info = c.exchange_info()
print(info.symbols[0].symbol)            # "BTCUSDT"

# Private endpoints
acc = c.account()
print(acc.totalWalletBalance)            # Decimal("10000.00")
print(acc.challenge.stage)              # "STAGE_1"

# Place an order (money values are strings — no floats)
order = c.new_order(
    symbol="BTCUSDT",
    side="BUY",
    type="LIMIT",
    quantity="0.001",
    price="60000.00",
    time_in_force="GTC",
)
print(order.orderId, order.status)

# Cancel it
cancelled = c.cancel_order(symbol="BTCUSDT", order_id=order.orderId)

WebSocket streams (async)

import asyncio
from alfax import Client, MarketStream, UserStream

async def main():
    # Public market stream
    async with MarketStream(["btcusdt@bookTicker"], base_url="wss://api.alfax.trade") as stream:
        async for msg in stream:
            print(msg)
            break

    # Private user-data stream
    c = Client(api_key="K", api_secret="S")
    listen_key = c.new_listen_key()
    async with UserStream(listen_key=listen_key, base_url="wss://api.alfax.trade") as stream:
        async for event in stream:
            print(event)
            break

asyncio.run(main())

Environment variables

Variable Description Default
ALFAX_KEY API key
ALFAX_SECRET API secret
ALFAX_BASE_URL REST base URL https://api.alfax.trade

Endpoints covered

Public (no auth)

Method Path SDK method
GET /fapi/v1/ping client.ping()
GET /fapi/v1/time client.server_time()
GET /fapi/v1/exchangeInfo client.exchange_info()
GET /fapi/v1/ticker/bookTicker client.book_ticker()
GET /fapi/v1/klines client.klines()

Private (HMAC-SHA256 signed)

Method Path SDK method
GET /fapi/v2/account client.account()
GET /fapi/v2/positionRisk client.position_risk()
GET /fapi/v1/userTrades client.user_trades()
POST /fapi/v1/order client.new_order()
DELETE /fapi/v1/order client.cancel_order()
GET /fapi/v1/order client.get_order()
GET /fapi/v1/openOrders client.open_orders()
GET /fapi/v1/allOrders client.all_orders()
POST /fapi/v1/leverage client.change_leverage()
POST /fapi/v1/listenKey client.new_listen_key()
PUT /fapi/v1/listenKey client.keepalive_listen_key()
DELETE /fapi/v1/listenKey client.close_listen_key()

Alfax extensions

Method Path SDK method
GET /fapi/v1/challenge client.challenge_status()
GET /fapi/v1/challenge/rules client.challenge_rules()
POST /fapi/v1/challenge/purchase client.create_challenge_purchase(product_id=…)
GET /fapi/v1/challenge/lifecycle client.challenge_lifecycle(challenge_id)
POST /fapi/v1/payout client.request_payout(challenge_id=…, amount=…)
GET /fapi/v1/payout client.get_payout(payout_id)
POST /fapi/v1/payout/approve client.approve_payout(payout_id) (operator)
POST /fapi/v1/payout/reject client.reject_payout(payout_id, reason) (operator)

Challenge purchase saga

# Trader buys a challenge — a Temporal workflow on the server side
# creates the payment intent, waits for the provider webhook, verifies,
# and mints the challenge.
purchase = c.create_challenge_purchase(product_id="challenge-10k-v1")
print(purchase.workflowId, purchase.status)  # purchase-…, "initiated"

# Later (once the workflow has completed) — inspect the minted
# challenge's lifecycle workflow:
state = c.challenge_lifecycle(challenge_id)
print(state.Stage, state.Status)  # STAGE_1, ACTIVE

Payouts

# Trader requests a withdrawal from a FUNDED challenge
p = c.request_payout(challenge_id="44444444-…", amount="500")
print(p.payoutId, p.status)  # ?, "requested"

# Operator (key must hold "operator" permission)
c.approve_payout(p.payoutId)

# Poll until terminal
state = c.get_payout(p.payoutId)
print(state.Status, state.TxRef)   # paid, stub-tx-…

# Over-cap requests are accepted but the workflow rejects them
over = c.request_payout(challenge_id="44444444-…", amount="999999")
c.approve_payout(over.payoutId)  # signals approve; cap check still runs first
state = c.get_payout(over.payoutId)
assert state.Status == "rejected"
assert "exceeds available" in state.FailReason

Error handling

from alfax.errors import AlfaxError, AlfaxAPIError, AuthError, RateLimitError, OrderError

try:
    order = c.new_order(...)
except OrderError as e:
    print(f"Order rejected (code {e.code}): {e.msg}")
except RateLimitError:
    print("Rate limited — back off")
except AlfaxAPIError as e:
    print(f"API error {e.status}: {e.msg}")

Examples

See examples/ for runnable scripts:

Development

python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest -q
ruff check .

Money handling

All money fields use decimal.Decimal — never float. Pass prices and quantities as strings:

# Correct
c.new_order(symbol="BTCUSDT", side="BUY", type="LIMIT",
            quantity="0.001", price="60000.00")

# Wrong — will break precision
c.new_order(symbol="BTCUSDT", side="BUY", type="LIMIT",
            quantity=0.001, price=60000.00)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

alfax-0.1.0.tar.gz (47.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

alfax-0.1.0-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file alfax-0.1.0.tar.gz.

File metadata

  • Download URL: alfax-0.1.0.tar.gz
  • Upload date:
  • Size: 47.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for alfax-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8c05942116809451b0393a51dd9a99ceac49526c86b628391fb81c717df41d96
MD5 2a0127ed9ad1939698705f005644e390
BLAKE2b-256 9e8a614d75af2708059fe03a93d7f217980a0f653f0e3c52e08f012616777a6a

See more details on using hashes here.

File details

Details for the file alfax-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: alfax-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for alfax-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cc0bc668e1e06689eba2262da712e03f8855b89539dc494cf6fda9981ab18414
MD5 6d802298234411294c89b196be36fe6f
BLAKE2b-256 b2177139574068038bc78f3eb8204b1ea4917c9ae848fe8a943ec8cf3508a977

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page