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.1.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.1-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: alfax-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 87e66c232a9963e208fe49c7ac11aa73751cf708827833f83de56c13f8518323
MD5 4363aae329727c8a17712d75a54490e2
BLAKE2b-256 60ca945c33a644c6b6d05dc7189ac70247fe88597eff3bf9059e60d9fed6aa4f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: alfax-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9a8ab63e416b7c012b3e87dd3403b505ad3d8f09d3289fe89334cba49b7fdd86
MD5 d7e2530e27aa8f6fe765ce147942abfb
BLAKE2b-256 528a70b372f26d869f5955dcb99cdbdff6d591594d3ff77c1f9d3240b1da2c7f

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