Skip to main content

Primary API Library

Project description

primary-api

Python library for connecting to the Primary API (Matba Rofex exchange). Fork/refactor of pyRofex. Provides REST and WebSocket clients for market data, order management, and account reports.

Stack: Python 3.8+, requests, simplejson, websocket-client, pydantic


Installation

pip install primary-api

Quick Start

from primary_api import PrimaryApiClient, Environment, MarketDataEntry

client = PrimaryApiClient(
    username="username",
    password="password",
    account="account123",
    environment=Environment.REMARKET
)

# REST: get market data
md = client.get_market_data("DLR/MAY26", [MarketDataEntry.LAST])
print(md)

# Market data handler
def on_md(msg):
    print(msg)

# WebSocket: subscribe to market data
sub = client.market_data_subscription(
    tickers=["DLR/MAY26"],
    entries=[MarketDataEntry.BIDS, MarketDataEntry.OFFERS],
    handler=on_md
)

client.wait_for_interrupt()

Models

You can use primary-api-models built on Pydantic BaseModel for automatic responses and messages validations.

pip install primary-api-models

For docs, visit https://pypi.org/project/primary-api-models/

Configuration

Environment

Two environments are available via the Environment enum:

Environment Description
Environment.REMARKET Remarkets (testing/simulation) — proprietary = "PBCP"
Environment.LIVE Live production — proprietary = "api"

Production environment

from primary_api import PrimaryApiClient, Environment

client = PrimaryApiClient(
    username="matriz-username",
    password="matriz-password",
    account="matriz-account",
    rest_url="https://api.your-broker.xoms.com.ar",
    ws_url="wss://api.your-broker.xoms.com.ar",
    environment=Environment.LIVE
)

REST API

Market Data

Method Description
get_segments() Get all available market segments
get_all_instruments() Get all instruments
get_detailed_instruments() Get detailed instrument list
get_instrument_details(ticker, market) Get details for a specific instrument
get_market_data(ticker, entries, depth, market) Get market data (bids, offers, last price, etc.)

Orders

Method Description
send_order(ticker, size, order_type, side, ...) Send a new order (REST)
send_order_via_websocket(ticker, size, order_type, side, ...) Send a new order (WebSocket)
cancel_order(client_order_id, proprietary) Cancel an existing order (REST)
cancel_order_via_websocket(client_order_id, proprietary) Cancel an existing order (WebSocket)
get_order_status(client_order_id, proprietary) Check order status
get_all_orders_status(account) Get all orders for an account
get_active_orders(account_id) Get active orders for an account

Account

Method Description
get_account_position(account) Get account position
get_detailed_position(account) Get detailed position
get_account_report(account) Get account report
get_trade_history(ticker, start_date, end_date, market) Get trade history

Example: Sending an Order

from primary_api import Side, OrderType, TimeInForce, Market

order = client.send_order(
    ticker="DLR/MAY26",
    size=10,
    order_type=OrderType.LIMIT,
    side=Side.BUY,
    market=Market.ROFEX,
    time_in_force=TimeInForce.DAY,
    price=850.50,
)

WebSocket Subscriptions

init_websocket_connection

Set up all handlers and establish the WebSocket connection in one call (pyRofex compatible):

def on_market_data(msg):
    print(msg)

def on_order_report(msg):
    print(msg)

def on_error(msg):
    print(f"Error: {msg}")

def on_exception(e):
    print(f"Exception: {e}")

client.init_websocket_connection(
    market_data_handler=on_market_data,
    order_report_handler=on_order_report,
    error_handler=on_error,
    exception_handler=on_exception,
)

# Handlers are already set — subscribe without passing handler
sub = client.market_data_subscription(tickers=["DLR/MAY26"], entries=[...])

Market Data Subscription

def handle_market_data(message):
    print(message)

sub = client.market_data_subscription(
    tickers=["DLR/MAY26", "DLR/JUN26"],
    entries=[
        MarketDataEntry.BIDS,
        MarketDataEntry.OFFERS,
        MarketDataEntry.LAST,
    ],
    depth=5,
    handler=handle_market_data
)

print(sub.count())       # 2 tickers
print(sub.active)        # True
print(sub.to_dict())     # full details (handler is no longer None)
print(sub.to_dict()["handler"])  # the handler function

sub.unsubscribe()        # stop receiving updates (also removes the handler)

Order Report Subscription

def handle_order_report(message):
    print(message)

sub = client.order_report_subscription(
    handler=handle_order_report
)

sub.unsubscribe()        # also removes the handler

WebSocket Lifecycle

  • First connect(): raises ApiException if the endpoint is unreachable.
  • Auto-reconnect: after a successful connection, if the WebSocket drops, it reconnects automatically in a background thread. All active subscriptions are re-sent on reconnect.
  • Cleanup: call client.close_websocket() to stop the reconnection loop.
  • Handler cleanup: sub.unsubscribe() removes both the subscription and its associated handler from the active list.

Enums Reference

Enum Values
Environment REMARKET, LIVE
Market ROFEX
MarketSegment DDF, DDA, DUAL, U_DDF, U_DDA, U_DUAL, MERV
Side BUY, SELL
OrderType LIMIT, MARKET, MARKET_TO_LIMIT
TimeInForce DAY, ImmediateOrCancel, FillOrKill, GoodTillDate
MarketDataEntry BIDS, OFFERS, LAST, OPENING_PRICE, CLOSING_PRICE, SETTLEMENT_PRICE, HIGH_PRICE, LOW_PRICE, TRADE_VOLUME, OPEN_INTEREST, INDEX_VALUE, TRADE_EFFECTIVE_VOLUME, NOMINAL_VOLUME, ACP, TRADE_COUNT
CFICode STOCK, BOND, CALL_STOCK, PUT_STOCK, FUTURE, PUT_FUTURE, CALL_FUTURE, CEDEAR, ON

Tests development

Environment variables (for testing)

Create a .env file:

CL_USERNAME=your_user
CL_PASSWORD=your_pass
CL_ACCOUNT=your_account
CL_ENVIRONMENT=REMARKET
CL_API_HTTPS=https://api.remarkets.primary.com.ar/
CL_API_WSS=wss://api.remarkets.primary.com.ar/

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

primary_api-0.2.0.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

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

primary_api-0.2.0-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file primary_api-0.2.0.tar.gz.

File metadata

  • Download URL: primary_api-0.2.0.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.18

File hashes

Hashes for primary_api-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d304b04364806563b2194ccd50017cf21b7622c09a6635f7d796e1943385ff50
MD5 2fd9cdd90d0cac2224a1a6916893f225
BLAKE2b-256 67bab833c3ff67a9eff9e0742a4c116dada11d412f51431b7524bd7268c70b88

See more details on using hashes here.

File details

Details for the file primary_api-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: primary_api-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.18

File hashes

Hashes for primary_api-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 92ffed17f233869ddcc68d605a9a72e6adb31e825cc75da5ac07464d9b03d8fd
MD5 32ad519f828b2ae81990fedd31d3f44e
BLAKE2b-256 846e4134331a8397ef2b963edf2cf419e66890ef5f5947775711f70fb8bdfa86

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