Skip to main content

PyPSX SDK

API-first trading infrastructure for the Pakistan Stock Exchange.

Installation

pip install pypsx

Try it in a notebook

Open In Colab

One-liners — no client to construct

import pypsx

df = pypsx.download("OGDC", period="1y")
result = pypsx.backtest("dual_sma_momentum", "OGDC", period="1y", initial_cash=1_000_000)
quote = pypsx.get_quote("OGDC")
depth = pypsx.get_market_depth("OGDC")

These read PYPSX_API_KEY_ID/PYPSX_API_SECRET_KEY from the environment automatically. For order placement, positions, and account state, use TradingClient below.

Quick Start

Start with paper trading. It is the safety-first way to test your strategy, validate your order flow, and watch your dashboard update in real time before risking real capital.

import os
from dotenv import load_dotenv
from pypsx import TradingClient

load_dotenv()

client = TradingClient(
    api_key=os.getenv("PYPSX_API_KEY_ID"),
    secret_key=os.getenv("PYPSX_API_SECRET_KEY"),
    paper=True,
)

account = client.get_account()
print(f"Connected! Current Balance: PKR {account.cash}")

order = client.place_manual_order(
    symbol="OGDC",
    side="BUY",
    quantity=10,
    order_type="MARKET",
)

print("Submitted:", order["order_id"], order["status"])

You can also load keys directly from environment variables:

from pypsx import TradingClient

client = TradingClient.from_env(paper=True)

Your First Trade

Step 1: Generate a paper key in the PyPSX dashboard.
Step 2: Copy the script above into my_bot.py.
Step 3: Set your own PYPSX_API_KEY_ID and PYPSX_API_SECRET_KEY in .env.
Step 4: Run python my_bot.py while the market is open.
Step 5: Watch orders, fills, and positions appear in the dashboard automatically.

The Power of PyPSX

PyPSX gives algorithmic traders a clean Python interface for the Pakistan Stock Exchange without exposing them to exchange plumbing.

Paper Trading

PyPSX currently operates in paper trading mode: simulated orders, no real money.

Real-Time Trading Experience

With PyPSX you can:

  • Read positions, orders, and account state from Python
  • Submit orders with a simple REST interface
  • See fills reflected in the web dashboard without manual refresh
  • Build bots around trading logic instead of exchange protocol handling

Developer's Promise

PyPSX handles the operational complexity of PSX integration, including request authentication, endpoint routing, and exchange connectivity. You focus on signal generation, risk rules, and execution logic. We handle the FIX-side complexity behind the API.

Authentication

How To Get Your Keys

  1. Sign in to the PyPSX dashboard.
  2. Open Settings.
  3. Select the account you want to trade.
  4. Click Generate Paper Key or Generate Live Key.
  5. Copy the Public Key ID and Secret Key.

How The SDK Uses Them

Use the credentials directly in TradingClient(...):

from pypsx import TradingClient

client = TradingClient(
    api_key=os.getenv("PYPSX_API_KEY_ID"),
    secret_key=os.getenv("PYPSX_API_SECRET_KEY"),
    paper=True,
)

Under the hood, the SDK automatically sends:

PYPSX-API-KEY-ID: <your-public-key-id>
PYPSX-API-SECRET-KEY: <your-secret-key>

If you are building against the API without the Python SDK, send those same headers yourself.

API Reference

Method What it does Returns
get_account(account_id=None) Account snapshot: cash, equity, buying_power, can_trade (attribute access supported) dict
get_portfolio_valuation() Returns the latest equity, cash, positions value, and pricing snapshot dict
get_positions() Returns open positions for the selected paper trading account list[dict]
get_orders(limit=...) Returns recent orders and their current state list[dict]
place_manual_order(...) Submits a market or priced order through the selected environment dict
get_symbols() Fetches available market symbols list[dict]
get_intraday(symbol, days=...) Retrieves recent intraday market data for a symbol list[dict]
get_historical(symbol, start=..., end=...) Retrieves historical daily bars for strategy research and analysis list[dict]
get_historical_intraday(symbols, start=..., end=..., interval=...) Retrieves multi-interval OHLCV candles (1m/5m/15m/1h) list[dict]
get_portfolio(bot_id=None) Raw portfolio dict for the current bot/account scope dict
get_account_config(account_id=None) Account-level configuration dict
get_fundamentals(symbol) pe_ratio, dividend_yield, market_cap, free_float, etc. for a symbol dict
get_dividends(symbol) Dividend history: year, amount, ex_date, payment_date, record_date list[dict]
get_commission_rate() The account's commission rate percentage (cached after first call) float
add_funds(amount, account_id=None, bot_id=None) Add paper cash to an account dict
get_performance(bot_id=None, limit=100) Historical performance snapshots for a bot dict
get_trades(bot_id=None, limit=100) Executed trade history for a bot dict
get_logs(bot_id=None, limit=200) Bot run logs dict
list_bots() List all bots registered under the account list[dict]
create_bot(bot_id, bot_label=None, strategy_name=None, symbols=None, cycle_minutes=None) Register a new cloud bot dict
place_bracket_order(symbol, side, quantity, stop_loss_price, take_profit_price, entry_type="MARKET", ...) Entry order plus a linked stop-loss/take-profit exit pair dict
place_oco_order(symbol, quantity, stop_loss_price, take_profit_price, ...) Attach a linked stop-loss/take-profit pair to an existing position dict
place_stop_order(symbol, quantity, trigger_price, limit_price=None, ...) Standalone stop order dict
get_order_executions(since=None, limit=1000) Raw fill/execution records for the current bot scope list[dict]
close() Closes the underlying HTTP client cleanly None

Examples

Paper Trading

import os
from pypsx import TradingClient

client = TradingClient(
    api_key=os.getenv("PYPSX_API_KEY_ID"),
    secret_key=os.getenv("PYPSX_API_SECRET_KEY"),
    paper=True,
)

valuation = client.get_portfolio_valuation()
positions = client.get_positions()
orders = client.get_orders(limit=25)

print("Equity:", valuation["equity"])
print("Positions:", len(positions))
print("Orders:", len(orders))

Simple Bot Pattern

from pypsx import TradingClient

SYMBOL = "OGDC"

client = TradingClient(
    api_key="PK_xxxxxxxxxxxx",
    secret_key="your_secret_key",
    paper=True,
)

positions = client.get_positions()
already_holding = any(
    position["symbol"] == SYMBOL and float(position["qty"]) > 0
    for position in positions
)

if not already_holding:
    client.place_manual_order(
        symbol=SYMBOL,
        side="BUY",
        quantity=10,
        order_type="MARKET",
    )

Best Practices

  • Use .env files or a secrets manager for credentials. Do not hardcode production keys into source control.
  • Start every new strategy with paper=True.
  • Treat paper trading as your pre-flight checklist before switching to live.
  • Run execution scripts when the market is open so fills, liquidity, and dashboard feedback reflect real conditions.
  • Add explicit guards in your code for position sizing, duplicate orders, and risk limits.
  • Close clients cleanly with client.close() in longer-running scripts or services.

Raw HTTP Example

If you are not using the SDK, this is the equivalent request format:

curl -X POST "$PYPSX_API_BASE_URL/orders" \
  -H "Content-Type: application/json" \
  -H "PYPSX-API-KEY-ID: $PYPSX_API_KEY_ID" \
  -H "PYPSX-API-SECRET-KEY: $PYPSX_API_SECRET_KEY" \
  -d "{\"symbol\":\"OGDC\",\"side\":\"BUY\",\"quantity\":10,\"order_type\":\"MARKET\",\"mode\":\"PAPER\",\"commission_rate\":0.02}"

Set commission_rate only when you want to override the default fee behavior for a specific order. The value is a percentage, so 0.02 means 0.02%.

Additional Examples

  • examples/pypsx_client_example.py
  • examples/example_bot.py

Download files

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

Source Distribution

pypsx-2.5.1.tar.gz (42.4 kB view details)

Uploaded Source

Built Distributions

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

pypsx-2.5.1-cp314-cp314-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.14Windows x86-64

pypsx-2.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (26.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pypsx-2.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (25.5 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pypsx-2.5.1-cp313-cp313-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.13Windows x86-64

pypsx-2.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (26.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pypsx-2.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (25.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pypsx-2.5.1-cp312-cp312-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.12Windows x86-64

pypsx-2.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (26.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pypsx-2.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (25.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pypsx-2.5.1-cp311-cp311-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.11Windows x86-64

pypsx-2.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (23.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pypsx-2.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (23.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pypsx-2.5.1-cp310-cp310-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.10Windows x86-64

pypsx-2.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (22.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pypsx-2.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (22.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

File details

Details for the file pypsx-2.5.1.tar.gz.

File metadata

  • Download URL: pypsx-2.5.1.tar.gz
  • Upload date:
  • Size: 42.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1.tar.gz
Algorithm Hash digest
SHA256 00da55774e81e34a80a1a514f6f445f934584703a77dd86c3c17755003c5627a
MD5 ebf481baf8e656b60d62316ed4e45136
BLAKE2b-256 e569241d7a8beef9f31ba4adfed562c867ae48f7b7a43d975f29c3b3f1253534

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: pypsx-2.5.1-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 764e5703454bd46e3598f0041187a8c3d5babe1849e7fa63b82b85660bc30ecd
MD5 7eb8a66c7a47b0acaefbb2ef0559f5cc
BLAKE2b-256 5a6af23aaff71d00f496ed04b6496e05d8c5d6be0703985217aeb68bc3590df8

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a5a346539d43466463242f81c238db02321f983e7f11777f84b6c5b607095fcd
MD5 2941f4bd47d606e736dae97a9bcc6b4f
BLAKE2b-256 a64896dd42e8856b745520017b3f73647dc33b750504ef17d9968d3901e04645

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 661822d8bfb35436e4f1187c53e59b48daa83d8bec41765fcb6726fe92bcd830
MD5 f497e104f8788d96d218b82ff8a0d428
BLAKE2b-256 7735b8bf977ff463d813c1633845eece764eabcc15946aa3eddad52b7a08d522

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pypsx-2.5.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 801625bcb9c20c45879b5a0136a10d58c30b6c37e73719bbf8eec4b356c87209
MD5 84cc4e14aa6ce721a926d4b63eb319e3
BLAKE2b-256 c7a6abadb79dafde9da59f4a2fd7d0cc0aabbb387b3c6f95f80f5d6c48ccf331

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 19be4a9d0c3ac7704584d102b4a06d822fa4853d71fd701d9cf32e537bd8eb5c
MD5 f249756759d52b3b22d8c87716cf2d0b
BLAKE2b-256 c2c149f6eed7359691b03c2f68395bc334cb927012f5e99081490be40d78b602

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 af52f5bbd4ec9151b6b95f5dc7cfbafac84a5197543ddc286751e088a815d98e
MD5 8d88ace50b63fe0438d3bc6d63895722
BLAKE2b-256 3fd8f40d1eca802193fac610092baa9328d60b95f4fb9b64aa6b265ea91820d3

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pypsx-2.5.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 dde44bae2bc787b474248b73c60770dc5ab0294e4e9fa12daad5f1b48c653afd
MD5 82fb4643a708887e607d8cd6ef9238e0
BLAKE2b-256 08063068c9d748a4b713c5079e766378e1ad9f3a1ecd4642cedddf3c785543e4

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a45dfe3f05901a6ab868c1e76095786ae70b8af20131431d013ac6abd28f121a
MD5 fe8627fbe9109a955d470dcf5c6c4782
BLAKE2b-256 1ba04d4f5ef92afb89a7be0f3f51b670bd74bf47ad662ea451a62ee0b2bb7a91

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 88667b1c43ef7e19f4bbbfea95c61edf9c32ce6472be5042a4bde2cd6a139618
MD5 dcb7bffa6c535e59d1280485cdde66c0
BLAKE2b-256 bade7d8d2769610d7a9e3eee7a14901c73a84e2d7210205fe4fa3f7afd9024ea

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pypsx-2.5.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 249ae19a1a9117236332ddb749f94aa1257658123d87e5be577de5f0e506713a
MD5 2f90dc81d8ecf67ac351979c7b4c4761
BLAKE2b-256 e43916ef90017282087d36e19bcc91c20c1fcc08ee41e3f78da48d806604ed33

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41b20ab030cfb0cad4f6a4450c2ee53a663bdc8fed9b489e962d9ef13d0e2461
MD5 9e5b135e8d7531fa5950495664784816
BLAKE2b-256 62377d6b03ad9feda7a6e123425d68435db35fef8ff7f9c705fa08334416dbb4

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e92ef13061fcf0462515ab0cdd8e25d260bc52c1f38e44f20745b74c866ab501
MD5 a1198d12cd6ee7a8f0ae7f87cec1a6e9
BLAKE2b-256 3b978adbde06295e55cf8fe2e5a0cc7e3e72ad11ef51425467a49dea187e06d9

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pypsx-2.5.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for pypsx-2.5.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 d09d6cc6fde14f3f05ce0c008f0b713fc146d70b4226892195a598fbe81abf21
MD5 ccae5906904f2bef40971c6d26db1edf
BLAKE2b-256 629d0b0d722d0a56941d27a6bf355b8e8a9f7a3dc1419c0a9b0c7b7612a37d21

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7aad07b68ba26e56ff2adbb52c17a275a3caa54370900b5a800d58e29ee2bb5b
MD5 880db944c99bf493d92bbbd261a63074
BLAKE2b-256 42cf95844d5d131a73c9a74de58d23a4194a6fb96d146dbc23f8a426fbaa66fc

See more details on using hashes here.

File details

Details for the file pypsx-2.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypsx-2.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9cc2015ab85776e75f8ed6e64e8c771672762a54016abf1ffb14d2825621a8c5
MD5 97cacbd587a25abdd1a36310972933a9
BLAKE2b-256 941a546b1ba77e0ba8528cf88f2b82228615591ec6d359ad487282503ec5606d

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 Sentry Error logging StatusPage Status page