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
from primary_api.models.enums import MarketDataEntry, MarketId
from primary_api.models.market_data import MarketDataMessage, MarketDataResponse

client = PrimaryApiClient(
    username="username",
    password="password",
    account="account123",
    rest_url="https://api.remarkets.primary.com.ar/",
    ws_url="wss://api.remarkets.primary.com.ar/"
)

# REST — returns typed Pydantic models
segments = client.get_segments()
print(segments.segments[0].market_segment_id)

md: MarketDataResponse = client.get_market_data("DLR/MAY26", [MarketDataEntry.LAST])
print(md.market_data.LA.price)

# WebSocket — handlers receive typed models
def on_md(msg: MarketDataMessage):
    print(msg.market_data.LA.price)

sub = client.market_data_subscription(
    tickers=["DLR/MAY26"],
    entries=[MarketDataEntry.BIDS, MarketDataEntry.OFFERS],
    handler=on_md
)

client.wait_for_interrupt()

Models

All API responses are typed Pydantic models with automatic camelCase to snake_case conversion. Every get_* method returns a typed model (not a raw dict).

segments: SegmentsResponse = client.get_segments()
print(segments.segments[0].market_segment_id)

Key models:

Model Description
SegmentsResponse Available market segments
AllInstrumentsResponse All instruments with CFI codes
InstrumentsByResponse Instruments by CFI code or segment
DetailedInstrumentsResponse Full instrument details
InstrumentDetailsResponse Single instrument details
MarketDataResponse Bids, offers, last price, etc.
OrderStatusResponse Order status / list of orders
OrderConfirmationResponse Order send/cancel confirmation
PositionsResponse Account positions
DetailedPositionsResponse Detailed positions by contract type
AccountReportResponse Account balance and report
TradesResponse Trade history
MarketDataMessage Parsed WS market data message (has instrument_id + market_data)
OrderReportMessage Parsed WS order report message (has order_report)
EnhancedOrderReport OrderReport with helper methods (is_open(), is_closed(), etc.)
pip install primary-api-models

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

Configuration

Environment

The client auto-detects the environment from the URL. If remarkets is in the URL, it configures is_remarkets = True and uses ISV_PBCP as the proprietary value.

Endpoint URL
Remarkets (testing) https://api.remarkets.primary.com.ar/
Live production Provided by your broker

Production environment

from primary_api import PrimaryApiClient

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"
)

REST API

Instruments

Method Return Type Description
get_segments() SegmentsResponse Get all available market segments
get_all_instruments() AllInstrumentsResponse Get all instruments
get_detailed_instruments() DetailedInstrumentsResponse Get detailed instrument list
get_instrument_details(ticker, market) InstrumentDetailsResponse Get details for a specific instrument
get_instruments_by_cfi(cfi_code) InstrumentsByResponse Filter instruments by CFICode
get_instruments_by_segment(market_segment, market) InstrumentsByResponse Filter instruments by MarketSegment

Market Data

Entries

Símbolo Significado Descripción
BI BIDS Mejor oferta de compra en el Book
OF OFFERS Mejor oferta de venta en el Book
LA LAST Último precio operado en el mercado
OP OPENING PRICE Precio de apertura
CL CLOSING PRICE Precio de cierre de la rueda de negociación anterior
SE SETTLEMENT PRICE Precio de ajuste (solo para futuros)
HI TRADING SESSION HIGH PRICE Precio máximo de la rueda
LO TRADING SESSION LOW PRICE Precio mínimo de la rueda
TV TRADE VOLUME Volumen operado en contratos/nominales para ese security
OI OPEN INTEREST Interés abierto (solo para futuros)
IV INDEX VALUE Valor del índice (solo para índices)
EV TRADE EFFECTIVE VOLUME Volumen efectivo de negociación para ese security
NV NOMINAL VOLUME Volumen nominal de negociación para ese security
ACP AUCTION PRICE Precio de cierre del día corriente
Method Return Type Description
get_market_data(ticker, entries, depth, market) MarketDataResponse Get market data (bids, offers, last price, etc.)

Orders

Method Return Type Description
send_order(ticker, size, side, ...) OrderConfirmationResponse Send a new order (REST)
send_order_via_websocket(...) None Send a new order (WebSocket)
cancel_order(client_order_id, proprietary) OrderConfirmationResponse Cancel an existing order (REST)
cancel_order_via_websocket(...) None Cancel an existing order (WebSocket)
get_order_status(client_order_id, proprietary) OrderStatusResponse Check order status by client ID
get_all_orders_by_id(client_order_id, proprietary) OrderStatusResponse All orders matching a client ID
get_order_by_order_id(order_id, proprietary) OrderStatusResponse Order by server-assigned order ID
get_order_by_exec_id(exec_id, proprietary) OrderStatusResponse Order by execution ID
get_all_orders_status(account) OrderStatusResponse Get all orders for an account
get_active_orders(account) OrderStatusResponse Get active (open) orders
get_filled_orders(account) OrderStatusResponse Get filled orders

Account

Method Return Type Description
get_account_position(account) PositionsResponse Get account position
get_detailed_position(account) DetailedPositionsResponse Get detailed position by contract type
get_account_report(account) AccountReportResponse Get account report (balance, margins)
get_trade_history(ticker, date, date_from, date_to, market) TradesResponse Get trade history

Example: Sending an Order

from primary_api.models.enums import Side, OrderType, TimeInForce, MarketId

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

WebSocket Subscriptions

init_websocket_connection

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

from primary_api.models.market_data import MarketDataMessage
from primary_api.models.order_report import OrderReportMessage

def on_market_data(msg: MarketDataMessage):
    print(msg.market_data.LA)

def on_order_report(msg: OrderReportMessage):
    print(msg.order_report.cl_ord_id)

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

def on_exception(e: Exception):
    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

from primary_api.models.market_data import MarketDataMessage

def handle_market_data(msg: MarketDataMessage):
    print(msg.market_data.LA.price)

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.to_dict())     # full details

Order Report Subscription

from primary_api.models.order_report import OrderReportMessage

def handle_order_report(msg: OrderReportMessage):
    print(msg.order_report.cl_ord_id)

sub = client.order_report_subscription(
    handler=handle_order_report
)

client.unsubscribe_order_report()

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.
  • Parsed messages: incoming WS messages are parsed into typed Pydantic models before reaching handlers — MarketDataMessage for market data, OrderReportMessage for order reports.
  • Cleanup: call client.close_websocket() to stop the reconnection loop.
  • Unsubscribe: use client.unsubscribe_market_data() / client.unsubscribe_order_report().

Enums Reference

All enums in primary_api.models.enums:

Enum Values
StatusResponse OK, ERROR
MessageType MARKET_DATA, ORDER_REPORT
MarketId ROFX
Side BUY, SELL
OrderType LIMIT, MARKET, STOP_LIMIT, STOP_LIMIT_MERVAL, MARKET_TO_LIMIT, PREVIOUSLY_QUOTED, STOP
OrderStatus PENDING_NEW, PENDING_CANCEL, PENDING_REPLACE, NEW, FILLED, PARTIALLY_FILLED, REPLACED, CANCELED, CANCELLED, EXPIRED, REJECTED
TimeInForce DAY, IOC, FOK, GTD, GTC
Currency ARS, USD, EXT, USG, UYD, UYU
CurrencyIndex ARS, ARS BCRA, EUR, UYU, U$S, USD MtR, USD UY, USD DB, USD G, USD R, USD C, USD D
SettlType T0 (CI), T1 (24hs), T2 (48hs), T3 (72hs), T4 (96hs), T5 (120hs)
SettlementIndex T0T5 (int 0–5)
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, FUTURE, PUT_STOCK, CALL_STOCK, PUT_FUTURE, CALL_FUTURE, CEDEAR, REPO, etc.
MarketSegment MERV, MFCI, DDF, DDA, DUAL, MAE, MATBA, TIVA, U-DDF, U-DDA, U-DUAL, U-DDF-S, U-FIN, U-COMM, U-STOCK, MVR, MVC, MVM, AVS, TEST
ContractType BOND, CEDEAR, FUTURE, NEGOTIABLE_OBLIGATION, OPTION_PUT, OPTION_CALL, STOCK, LETTER_NOTE, DEFAULT, REPURCHASE

Tests development

Environment variables (for testing)

Create a .env file:

CL_USERNAME=your_user
CL_PASSWORD=your_pass
CL_ACCOUNT=your_account
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.3.0.tar.gz (27.7 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.3.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: primary_api-0.3.0.tar.gz
  • Upload date:
  • Size: 27.7 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.3.0.tar.gz
Algorithm Hash digest
SHA256 a2063c478560b516f5f60e816b3b12197ee368b41ba32db230e38a03ee254d2e
MD5 4eb77bd0ba340b4649a13e23f72ff493
BLAKE2b-256 ea5a54b3de4670d76b629ff4b18382f6412827ae7a676a27ef9a2a83035dc59c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: primary_api-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 27.5 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 321214fb50bcb9329dbce5c9f73033287c9cd38d15ceb46ecf44cb5db971c671
MD5 644c7d01a97e28a4a4b3af183511d9a1
BLAKE2b-256 0130079ca68216a9f4f232de9b2e604e218d2f84988eb44e5ca5ee0b77a9980a

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