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. All requests go to https://paper-api.pypsx.com.

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 "https://paper-api.pypsx.com/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.0.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.0-cp314-cp314-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.14Windows x86-64

pypsx-2.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (26.2 MB view details)

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

pypsx-2.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (25.6 MB view details)

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

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

Uploaded CPython 3.13Windows x86-64

pypsx-2.5.0-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.0-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.0-cp312-cp312-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.12Windows x86-64

pypsx-2.5.0-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.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (25.9 MB view details)

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

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

Uploaded CPython 3.11Windows x86-64

pypsx-2.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (24.0 MB view details)

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

pypsx-2.5.0-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.0-cp310-cp310-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.10Windows x86-64

pypsx-2.5.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (23.0 MB view details)

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

pypsx-2.5.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (22.6 MB view details)

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

File details

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

File metadata

  • Download URL: pypsx-2.5.0.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.0.tar.gz
Algorithm Hash digest
SHA256 5d2e9ce1cf459f0a1762e82c9ec29894da0f37b43310370be1877a8bc3816d5c
MD5 6109a39a6ed9344b70e91d91f7b7d2df
BLAKE2b-256 4ddbfa6aaa0a5fbf2d327fc3717df64c2fc19ac08a031f90d68e231bef65872a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pypsx-2.5.0-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.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 385bc0d383af954a7cfe7fabf13c3be47d9e1d6168dbca195765f01d776278f1
MD5 b73a0cf21b298b983f977b2e3c7a0de2
BLAKE2b-256 b70e987fec2300c87bc15bdb55471f027300983bb58ca957e67f8c72d1e9c3ad

See more details on using hashes here.

File details

Details for the file pypsx-2.5.0-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.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 af4b1cf3e9537fb861c2624d9ca28a44747f91fb8993608bfa62edd948faaa5f
MD5 faec51435d723f509b4de19acc290899
BLAKE2b-256 1647d3b0911240341cd32e4a723db9fbeab93ec3a4c4f3c76523e1d4bb03a52c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pypsx-2.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 19158799740f649d646f87131f2317aba08d19ec4c9221b59aa659ab715399cc
MD5 70b1edc4bccf48c90244adee55d43490
BLAKE2b-256 d3516f518495f9d7576c0a1a3d4ae634df59ee0293c33a5a43462bc34bd424df

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pypsx-2.5.0-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.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1d59cbb6eb6b0b93eaccebb0464ecdc8daa89b9d44204674e188dc087b217034
MD5 bdd87310ece83223f83991dcfa989213
BLAKE2b-256 fa945e523c339c36d675eae64629d2dcc97b9c54a38e716cab6f3ae5cd8a120e

See more details on using hashes here.

File details

Details for the file pypsx-2.5.0-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.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0fae436dad08deb2326cd1686c4dc2835f5a59bc27661f1f406cb2520ab7b8b3
MD5 b0d5c952406eea953da6a0007badc3bd
BLAKE2b-256 d9a0c44c0384d7791e98530c8abd402a9f0c0f5c54dc25675239ff52416c142e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pypsx-2.5.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cda8e33c59a1fbc51921d7979b69ecada0ea45e7105b3c953de2280e44709d52
MD5 8dc0e47ecff9ee7871e0ed1f2c09bee4
BLAKE2b-256 0ed8dca93e570ead22e5614b433f15bc7995397dde9962a6e5f1b1133d39a2ef

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pypsx-2.5.0-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.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2fc88a6f632756d5cbd79b76dc2801587f512458404f5879a2f2c1b7265dda5c
MD5 33aa52dcd41dc6e4866bd6cde22aa4cc
BLAKE2b-256 052ae498614da055f4d6c1f21f39c0e3f3985e8329c0fb495f7c8ab2dc9747e9

See more details on using hashes here.

File details

Details for the file pypsx-2.5.0-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.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 883355b97352c5d744436ae9b8cf576c8b52bfb74ea9c633aa0ba18c80b6ca1c
MD5 f1b208f1fb192de3989aef6260471772
BLAKE2b-256 c1c6695698ab0954c2c9c16bc47955d1d87b8227e05b698710cd001de8d42207

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pypsx-2.5.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 71ecf4d93f4d33a56f9f760e7cf1d6c834d6cd1e51cadc8acdc1713274e640e3
MD5 db21fa216eca652cf2d85bca2194486b
BLAKE2b-256 74fd2bd3a9d3cae7571384347f1e5ca890157cf274d3766f62b044a78825218c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pypsx-2.5.0-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.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 df649693c572fcfede45167f9abff7494c3ea74f6ca149ca5302288239018271
MD5 991188aaaa8e7b39a31d070492aec950
BLAKE2b-256 05fff52d9f1c9b5984f13d6e95989b2dedc3d73a48bb8cde9915d24f251a4300

See more details on using hashes here.

File details

Details for the file pypsx-2.5.0-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.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d519ff55b1b0b59a1f6551064ead9b4f95ce4deb7227c1b7b7aaada9d9ab0aa0
MD5 91cc4046c791c9d40cb38ea2b68404e2
BLAKE2b-256 0af3b13413a4f4efa0761692712587dfaee2f83897c678710e64852ef5114c10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pypsx-2.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ef0b431f3398fbcf55d2988698ac18efa30045ee37abc678e824dff5e7ce419a
MD5 15eae1f0e00561262242057fba297393
BLAKE2b-256 69c79231f3f19cdc758988a1f83318bb378629e3a79d14d1b778608038e4a81c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pypsx-2.5.0-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.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 2a9df0e4719a0c9b1e0e37470d9aab7d730da77e003f49852e6b81966534be0d
MD5 d64a3f9a4433a39bbdbaf16391e22764
BLAKE2b-256 198a57b31b8756e604ef4f90f00b930e2c000f27a6bf51eac1fd66eb84891f65

See more details on using hashes here.

File details

Details for the file pypsx-2.5.0-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.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8de69fa8b07448e655651dca8dfe02e587961b01a07692e89b1a8dc783e19111
MD5 a497374a2f3543541c33e6cb5d68afef
BLAKE2b-256 3b3f29273a42d9e588e10fe9f62622c870ad8c7111277effa2380641a01dfc93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pypsx-2.5.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4997b1ab2f7cc5e4e38de1d8a4db1233393980421a5aa231c6878fcea3cfa2ed
MD5 c7b6448d7b4cf6ef95b60774817a1a93
BLAKE2b-256 a7fcd80d576b5b0147b7270999349d371eacc9aef1ccba0abd370303ee5f2ea4

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