Algorithmic trading SDK for PSX — paper trading, live trading, backtesting, cloud bots
Project description
PyPSX SDK
API-first trading infrastructure for the Pakistan Stock Exchange.
Installation
pip install pytrader
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 pytrader 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 pytrader 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 And Live Modes
The SDK automatically routes traffic based on one flag:
paper=Truesends requests to the paper trading environment athttps://paper-api.pypsx.pkpaper=Falsesends requests to the live trading environment athttps://api.pypsx.pk
This keeps your code identical across testing and production. Change the credentials, switch the flag, and keep your trading logic the same.
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
- Sign in to the PyPSX dashboard.
- Open
Settings. - Select the account you want to trade.
- Click
Generate Paper KeyorGenerate Live Key. - Copy the
Public Key IDandSecret Key.
How The SDK Uses Them
Use the credentials directly in TradingClient(...):
from pytrader 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_config() |
Fetches trading permissions and account-level configuration | dict |
get_portfolio_valuation() |
Returns the latest equity, cash, positions value, and pricing snapshot | dict |
get_positions() |
Returns open positions for the selected paper or live 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 bars for strategy research and analysis | list[dict] |
close() |
Closes the underlying HTTP client cleanly | None |
Examples
Paper Trading
from pytrader 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))
Live Trading
from pytrader import TradingClient
client = TradingClient(
api_key="PK-LIVE-ABC123456789",
secret_key="pypsx-secret-live-replace-me",
paper=False,
)
order = client.place_manual_order(
symbol="OGDC",
side="BUY",
quantity=100,
order_type="MARKET",
)
print(order)
Simple Bot Pattern
from pytrader import TradingClient
SYMBOL = "OGDC"
client = TradingClient(
api_key="PK-PAPER-123456",
secret_key="pypsx-secret-paper-replace-me",
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
.envfiles 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.pk/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/pytrader_client_example.pyexamples/example_bot.py
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytrader_sdk-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pytrader_sdk-1.0.1-py3-none-any.whl
- Upload date:
- Size: 211.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64a0033ea6929b622c52ccd8ba76acd36f51f66f760f228fc1f056d2bff19bc5
|
|
| MD5 |
eaf40a80772a5822b8dbc0e8017a5d5a
|
|
| BLAKE2b-256 |
310d043eb4eaf5293e373e98f38992e612200f979eb886947da1a5a4928d3a78
|
Provenance
The following attestation bundles were made for pytrader_sdk-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on ahmerhkhan/libraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytrader_sdk-1.0.1-py3-none-any.whl -
Subject digest:
64a0033ea6929b622c52ccd8ba76acd36f51f66f760f228fc1f056d2bff19bc5 - Sigstore transparency entry: 1829098923
- Sigstore integration time:
-
Permalink:
ahmerhkhan/libraries@b81e336284ea1df6040ce51461349b59a03f9df6 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/ahmerhkhan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b81e336284ea1df6040ce51461349b59a03f9df6 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pytrader_sdk-1.0.1-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: pytrader_sdk-1.0.1-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 10.2 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
881533edf7aeab768af4d538929bab8cab7f85ad516449b25ff3f78ebae49bf5
|
|
| MD5 |
10dda6d3644299727c7d976caf80dc9e
|
|
| BLAKE2b-256 |
9080383ad9702bdf0dc0727ee4b9f132716c87af3688f25c426ba0bf21b5753a
|
Provenance
The following attestation bundles were made for pytrader_sdk-1.0.1-cp312-cp312-win_amd64.whl:
Publisher:
publish.yml on ahmerhkhan/libraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytrader_sdk-1.0.1-cp312-cp312-win_amd64.whl -
Subject digest:
881533edf7aeab768af4d538929bab8cab7f85ad516449b25ff3f78ebae49bf5 - Sigstore transparency entry: 1831140794
- Sigstore integration time:
-
Permalink:
ahmerhkhan/libraries@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/ahmerhkhan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pytrader_sdk-1.0.1-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: pytrader_sdk-1.0.1-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 10.2 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a82d4d8f122e8e0143e203a61fe35fa99ecb87f2f06033ab614985ee51820701
|
|
| MD5 |
cd6a443dfcdd44aeee45ed79f056437d
|
|
| BLAKE2b-256 |
64e26bd61a50fc2a22eaf7ffe534196ba1519693a0481857beadcb756765f4e3
|
Provenance
The following attestation bundles were made for pytrader_sdk-1.0.1-cp311-cp311-win_amd64.whl:
Publisher:
publish.yml on ahmerhkhan/libraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytrader_sdk-1.0.1-cp311-cp311-win_amd64.whl -
Subject digest:
a82d4d8f122e8e0143e203a61fe35fa99ecb87f2f06033ab614985ee51820701 - Sigstore transparency entry: 1831140656
- Sigstore integration time:
-
Permalink:
ahmerhkhan/libraries@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/ahmerhkhan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pytrader_sdk-1.0.1-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: pytrader_sdk-1.0.1-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 10.2 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cced435ac1ba2f33718193a590bcc0c00c2be407b21e65acc5dbcbeddb2e49b2
|
|
| MD5 |
8872cea2c196836d9f7c8d474213137a
|
|
| BLAKE2b-256 |
2f9ece5e409e400ae0ab82792fdfc5f8425a64a59b4a64c3387074ee04ee19f5
|
Provenance
The following attestation bundles were made for pytrader_sdk-1.0.1-cp310-cp310-win_amd64.whl:
Publisher:
publish.yml on ahmerhkhan/libraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytrader_sdk-1.0.1-cp310-cp310-win_amd64.whl -
Subject digest:
cced435ac1ba2f33718193a590bcc0c00c2be407b21e65acc5dbcbeddb2e49b2 - Sigstore transparency entry: 1831140473
- Sigstore integration time:
-
Permalink:
ahmerhkhan/libraries@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/ahmerhkhan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5eec71eb0fcd515b98b197b3712c455eb8f6fb9 -
Trigger Event:
workflow_dispatch
-
Statement type: