Skip to main content

Python SDK for Delta Exchange India — perpetual futures broker with bracket orders and OHLCV candle history

Project description

deltain

PyPI version Python License: MIT

Python SDK for Delta Exchange India — the INR-settled perpetual futures exchange. Built from scratch with a clean abstract broker interface, automatic retry logic, and a full live integration test suite verified against the Delta Exchange testnet.

pip install deltain

Features

Capability Details
Market & Limit Orders IOC market orders, GTC limit orders
Stop-Loss Orders Standalone stop-loss with close_on_trigger
Bracket Orders Entry + SL + TP in a single atomic API call
OHLCV Candle History 1-minute candles, auto-paginated across any date range
Bracket Support Check is_bracket_order_supported() per symbol
Order Status & Cancel Query by client_order_id, idempotent cancel
Auto-reconnect Retries on 502 Bad Gateway and connection errors
Testnet / Mainnet Single flag to switch environments
Abstract Base Class Broker ABC so you can swap exchanges without changing strategy code

Installation

pip install deltain

Requirements: Python >= 3.10, requests >= 2.28

Or install from source:

git clone https://github.com/friendmanjur/delta-exchange-india-sdk.git
cd delta-exchange-india-sdk
pip install .

Quick Start

from deltain import DeltaBroker

broker = DeltaBroker(
    api_key    = "YOUR_KEY",
    api_secret = "YOUR_SECRET",
    testnet    = True,   # flip to False for live trading
)
broker.login()

# Live price
price = broker.get_price("BTCUSD")
print(f"BTCUSD: {price:.2f}")

# Market order
fill = broker.place_market_order("BTCUSD", "buy", qty=1)

# Bracket order - entry + stop-loss + take-profit in one call
broker.place_bracket_order(
    symbol            = "BTCUSD",
    side              = "buy",
    qty               = 1,
    limit_price       = price,
    stop_loss_price   = round(price * 0.95, 1),
    take_profit_price = round(price * 1.05, 1),
    oid               = "my-signal-001",
)

# 1-minute candles - auto-paginated, any range
import time
now = (int(time.time()) // 60) * 60
candles = broker.get_one_minute_candles(
    exchange    = "delta_india",
    symbol      = "BTCUSD",
    start_epoch = now - 7 * 24 * 3600,   # 7 days
    end_epoch   = now,
)
print(f"Fetched {len(candles)} candles")

API Reference

DeltaBroker(api_key, api_secret, testnet=False, timeout=10, retry_delay=1.0)

Method Description
login() Verify credentials against /v2/profile. Must be called first.
get_price(symbol) Returns the current mark price as a float.
place_market_order(symbol, side, qty, oid=None) IOC market order. Returns average fill price.
place_stoploss_order(symbol, side, qty, price, oid) GTC stop-loss market order.
place_target_order(symbol, side, qty, price, oid) GTC reduce-only limit order.
place_bracket_order(symbol, side, qty, limit_price, stop_loss_price, take_profit_price, ...) Atomic bracket order. Returns {"delta_id", "avg_fill", "status"}.
get_order_status(oid) Returns {"status", "price", "raw_state"}. Status: OPEN TRIGGERED CANCELLED UNKNOWN.
cancel_order(oid) Idempotent cancel - safe to call on already-closed orders.
is_bracket_order_supported(symbol) True for perpetual/dated futures. Never raises.
get_one_minute_candles(exchange, symbol, start_epoch, end_epoch) Paginated 1-min OHLCV. Returns list of {"time", "open", "high", "low", "close", "volume"}.
is_connected() Ping - returns True if credentials are valid and exchange is reachable.
relogin() Re-authenticate without creating a new broker instance.

place_bracket_order full signature

broker.place_bracket_order(
    symbol                  = "BTCUSD",
    side                    = "buy",               # "buy" or "sell"
    qty                     = 1,
    limit_price             = 67000.0,             # entry limit price
    stop_loss_price         = 63650.0,             # SL trigger price
    take_profit_price       = 70350.0,             # TP trigger price
    stop_loss_limit_price   = None,                # optional - market SL if omitted
    take_profit_limit_price = None,                # optional - market TP if omitted
    stop_trigger_method     = "last_traded_price", # or "mark_price" / "index_price"
    oid                     = "signal-btc-001",    # optional client_order_id
)

get_one_minute_candles boundary alignment rule

Delta Exchange applies an asymmetric rounding rule to timestamps, discovered and verified via 32 live boundary tests:

aligned_start = ceil(start / 60) * 60   <- CEILING
aligned_end   = floor(end   / 60) * 60  <- FLOOR

Always align your timestamps to minute boundaries for predictable results:

# Correct - always align first
start = (your_epoch // 60) * 60
end   = (your_epoch // 60) * 60
Start offset End offset Candles returned
:00 :00 to :59 1 candle (the :00 candle)
:00 :60 2 candles
:01 to :59 less than :60 0 candles - start ceils past end
:01 to :59 :60 to :119 1 candle (only the :60 candle)

Abstract Broker Interface

Write strategy code once, swap the exchange later:

from deltain import Broker

class MyOtherBroker(Broker):
    def get_price(self, symbol): ...
    def place_market_order(self, symbol, side, qty): ...
    def place_stoploss_order(self, symbol, side, qty, price, oid): ...
    def place_target_order(self, symbol, side, qty, price, oid): ...
    def place_bracket_order(self, symbol, side, qty, limit_price,
                            stop_loss_price, take_profit_price, ...): ...
    def get_order_status(self, oid): ...
    def cancel_order(self, oid): ...
    # is_bracket_order_supported() defaults to True
    # get_one_minute_candles() raises NotImplementedError until overridden

Tests

All tests run against testnet only - no live funds are ever used.

export DELTA_API_KEY="your_testnet_key"
export DELTA_API_SECRET="your_testnet_secret"

# Bracket order tests
python3 tests/test_bracket_order.py

# Candle stress tests
python3 tests/stress_test_candles.py

# Run specific groups
python3 tests/stress_test_candles.py single multi
python3 tests/stress_test_candles.py pagination
python3 tests/stress_test_candles.py edge
Test file Assertions What is covered
test_bracket_order.py 24 Login guard, position pre-flight, bracket lifecycle, SL/TP child visibility, idempotent cancel
stress_test_candles.py 400+ Schema, OHLC sanity, pagination up to 30 days, multi-symbol, 32 second-boundary combinations

Project Structure

delta-exchange-india-sdk/
├── deltain/
│   ├── __init__.py
│   └── broker.py              <- Broker ABC + DeltaBroker (820 lines)
├── tests/
│   ├── test_bracket_order.py
│   └── stress_test_candles.py
├── examples/
│   └── quickstart.py
├── pyproject.toml
├── CHANGELOG.md
├── LICENSE
└── README.md

Environment Variables

Variable Description
DELTA_API_KEY Your Delta Exchange India API key
DELTA_API_SECRET Your Delta Exchange India API secret

Get testnet credentials at testnet.delta.exchange.


Security

  • Never commit credentials. Use environment variables or a secrets manager.
  • .gitignore excludes .env and secrets.py.
  • All tests are hard-coded to testnet=True.

Changelog

See CHANGELOG.md.


License

MIT - see LICENSE.


Acknowledgements

Built on the Delta Exchange India REST API. Retry and connection patterns ported from the Shoonya C++ trading system.

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

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

deltain-1.0.0-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

File details

Details for the file deltain-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: deltain-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 19.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.6

File hashes

Hashes for deltain-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 18cc43a296b689a6b3e1787264f2ff516b48b04a055d5c4c446cb9e3b406fb5e
MD5 1d241e7d2cb980a901c9a364311129ec
BLAKE2b-256 21f906de4884b6dcf30c885e8721a5ffed117dcdc6a52902b7e5873092f333d0

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