Skip to content

TheHardeep/fenix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

141 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Fenix

Fenix

Change one word. Trade any broker.
One unified Python API across 15 Indian brokers β€” authentication, instrument tokens, orders, positions, and account data, all returned in one consistent shape.

License PyPI Python Docs

Install Β· Quickstart Β· Features Β· Brokers Β· Constants Β· Paper Mode Β· Documentation


Every Indian broker ships its own REST API with its own URLs, field names, constants for order side and product type, error envelope, and rate limits. Writing a strategy against one broker means re-learning all of that for the next. Fenix is an adapter library: each broker is a class that implements the same methods and returns the same dictionaries β€” a single unified interface purpose-built for the Indian markets (NSE, BSE, NFO, BFO, MCX, CDS).

# swap one word β€” the rest never changes
from fenix import Zerodha
from fenix import Side, Product

broker = Zerodha()
broker.authenticate(params=creds)
broker.market_order(token_dict=contract, quantity=1, side=Side.BUY, product=Product.MIS, unique_id="entry-1")

It is built for coders, quant developers, technically-skilled traders, and data scientists building algorithmic trading systems on top of one stable API.

Why Fenix

  • Learn it once, ship everywhere. The same method names, parameters, and return shapes work across every adapter. Porting a strategy to a new broker is a one-line change β€” not a rewrite.
  • One vocabulary, not fifteen. Your code speaks in Fenix constants β€” Side.BUY, Product.MIS, OrderType.SLM β€” and each adapter translates to its broker's dialect, with validation.
  • Backtest with paper mode. Flip one flag and the same strategy runs against a built-in matching engine β€” realistic fills, positions, and PnL, with no credentials and zero live calls.
  • Safe by default. Token-bucket rate limiting per endpoint, structured errors with HTTP-status mapping, and automatic redaction of secrets from every log line.

Install

Fenix 2.0 requires Python 3.10 or newer and runs on Windows, macOS, and Linux.

pip install fenix

To install a specific release:

pip install fenix==2.0.0

Verify the installation and inspect the broker registry:

import fenix

print(fenix.__version__)   # 2.0.0
print(fenix.brokers)       # ['AliceBlue', 'AngelOne', 'AnandRathi', ...]

Quickstart

Instantiate a broker, authenticate, download instrument tokens, place an order, and read it back β€” all through the unified API. The same code runs against any broker.

from fenix import Zerodha, Side, Validity

# 1 Β· Instantiate
broker = Zerodha()

# 2 Β· Authenticate β€” each broker declares the credentials it needs in `tokenParams`
creds = {
    "user_id":    "YOUR_USER_ID",
    "password":   "YOUR_PASSWORD",
    "totpstr":    "YOUR_TOTP_SECRET",   # the TOTP *seed*, not a 6-digit code
    "api_key":    "YOUR_API_KEY",
    "api_secret": "YOUR_API_SECRET",
}
broker.authenticate(params=creds)

# 3 Β· Download instrument tokens (reshaped into a standardized lookup)
fno, _ = broker.load_fno_tokens()
contract = fno["Options"]["NFO"]["NIFTY"][0]

# 4 Β· Place an order β€” returns a unified order record (same keys for every broker)
order = broker.limit_order(
    token_dict=contract,
    side=Side.BUY,
    price=152.0,
    quantity=75,
    unique_id="entry-1",
)

# 5 Β· Read it back, then modify or cancel
detail = broker.fetch_order(order["id"])
broker.modify_order(order_id=order["id"], price=151.5, quantity=75)
broker.cancel_order(order_id=order["id"])

# 6 Β· Inspect positions and account
positions = broker.fetch_net_positions()
holdings  = broker.fetch_holdings()
margins   = broker.fetch_margin_limits()   # unified RMS record
profile   = broker.fetch_profile()

See the Quickstart guide for the full walkthrough, including reusing an authenticated session across runs.

Order & account methods

Order entry Account & order reads
place_order, modify_order, cancel_order fetch_orderbook, fetch_tradebook
market_order, limit_order, sl_order, slm_order fetch_order, fetch_order_history
market_buy_order, market_sell_order fetch_net_positions, fetch_day_positions
limit_buy_order, limit_sell_order fetch_holdings, fetch_margin_limits
sl_buy_order, slm_sell_order, … fetch_profile

Features

Fenix 2.0 is a ground-up refactor of the broker layer. Highlights:

  • πŸ” Unified, one-line broker swap. Identical method names, parameters, and return shapes across all 15 adapters β€” port a strategy by changing a single class name.
  • 🧱 One shared base class. Every adapter subclasses fenix.base.broker.Broker, which owns the HTTP session, request wrapper, URL building, constant translation, and error mapping. New brokers stay thin and consistent.
  • πŸ“„ Built-in paper-mode engine. An in-process matching engine simulates fills, positions, and PnL with no credentials and zero live calls β€” flip paper_mode and the same code runs.
  • πŸ—£οΈ One vocabulary. Fenix constants (Side, Product, OrderType, Validity, Variety, Status) are translated per broker with validation β€” see Constants.
  • 🚦 Per-endpoint rate limiting. Token-bucket throttling defined in each adapter's rateLimits; requests self-throttle before hitting the broker.
  • πŸ” Secret redaction. Passwords, tokens, API keys, authorization headers, and TOTP values are automatically scrubbed from every log line.
  • 🧾 Structured errors. Broker error envelopes are mapped to typed Fenix exceptions with HTTP-status context.
  • 🩺 Request/response diagnostics. Every broker keeps the latest HTTP snapshots (last_request_*, last_response_*) β€” plus paper-mode equivalents.
  • ⌨️ Typed. Ships a PEP 561 py.typed marker so downstream type checkers pick up Fenix's annotations.

Supported Brokers

Fenix 2.0 exposes 15 broker adapters. Each has its own reference page documenting every method it supports.

The Class name is the public identifier β€” it is exactly what fenix.brokers lists and what broker.describe()["id"] returns.

Broker Class
AliceBlue AliceBlue AliceBlue
Angel One Angel One AngelOne
Anand Rathi Anand Rathi AnandRathi
Dhan Dhan Dhan
Finvasia Finvasia / Shoonya Finvasia
5paisa 5paisa FivePaisa
Fyers Fyers Fyers
Groww Groww Groww
IIFL IIFL Iifl
Kotak Neo Kotak Neo KotakNeo
Master Trust Master Trust MasterTrust
Motilal Oswal Motilal Oswal MotilalOswal
Symphony Symphony Symphony
Upstox Upstox Upstox
Zerodha Zerodha Zerodha
import fenix
print(fenix.brokers)   # always reflects exactly what your installed version supports

The deprecated v1 modules choice, kotak, kunjee, and vpc were removed in v2.0.

Unified Vocabulary

Your strategy speaks Fenix constants; each adapter translates them to its broker's dialect and validates them. The constant classes are top-level exports (from fenix import Side, Product, …).

Constant Common values
Side BUY, SELL
OrderType MARKET, LIMIT, SL, SLM
Product MIS, NRML, CNC, MARGIN, MTF, BO, CO
Validity DAY, IOC, GTD, GTC, FOK, TTL
Variety REGULAR, STOPLOSS, AMO, BO, CO, ICEBERG, AUCTION
Status PENDING, OPEN, PARTIALLY_FILLED, FILLED, REJECTED, CANCELLED
ExchangeCode NSE, NFO, BSE, BFO, MCX, CDS, …
Root NIFTY, BANKNIFTY, FINNIFTY, SENSEX, CRUDEOIL, …
Option CE, PE

Returned records also use a fixed key set (Order, Position, Profile, RMS), so the same parsing code works for every broker. Full reference at fenix.hardeep.tech.

Paper Trading

Paper mode routes supported order entry and account reads through Fenix's in-process matching engine instead of live broker endpoints β€” no credentials, zero live calls. Flip one flag and the exact same code runs against the simulator.

from fenix import AliceBlue, Side, UniqueID

broker = AliceBlue({"paper_mode": True})
broker.authenticate()                      # no-op in paper mode

token = {"Token": 12345, "Symbol": "TESTSTOCK", "Exchange": "NSE"}

order = broker.market_order(
    token_dict=token, quantity=1, side=Side.BUY, unique_id=UniqueID.MARKET_ORDER,
)

broker.on_tick(token=12345, ltp=2500.0)    # feed prices to drive fills

print(broker.fetch_orderbook())
print(broker.fetch_positions())

Paper mode supports order books, trade books, order history, positions, holdings, margin limits, profile data, stop-order validation, and square-off validation.

How it fits together

Every adapter β€” Zerodha, AngelOne, Fyers, … β€” subclasses fenix.base.broker.Broker. The base class owns everything identical across brokers (HTTP session, throttling, the fetch() request wrapper, URL building, constant translation, logging/redaction, error mapping, and the embedded paper engine), while each subclass supplies only what is broker-specific.

  Your strategy            Fenix Β· Unified API           Brokers
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                β”‚          β”‚  authenticate Β· login    β”‚          β”‚  Zerodha Β· Angel One     β”‚
β”‚  one codebase  β”‚  ──────▢ β”‚  orders Β· positions      β”‚  ──────▢ β”‚  Fyers Β· Upstox Β· Dhan   β”‚
β”‚                β”‚   call   β”‚  account Β· paper mode    β”‚   REST   β”‚  … + 10 more brokers     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Operational features

  • Rate limits. Adapters define token-bucket buckets in rateLimits; requests throttle automatically before hitting endpoints. Configure with enableRateLimit and rate_limit_padding.
  • Logging & redaction. Pass a logger or verbose=True to inspect request/response flow. Fenix redacts passwords, tokens, API keys, authorization headers, and TOTP values.
  • Diagnostics. Every broker keeps the latest HTTP snapshots (last_request_*, last_response_*) β€” and in paper mode, last_paper_request / last_paper_response / last_paper_interaction.
  • Typed. Ships a PEP 561 py.typed marker so downstream type checkers pick up Fenix's annotations.

Fenix-Pro β€” real-time market data

Fenix-Pro is the paid, real-time companion to Fenix. It hides each broker's WebSocket transport, payload format, and subscription conventions behind a unified, callback-oriented interface β€” LTP, market depth, and order updates, normalized into one TickData / Order shape across 15 live-feed adapters. It shares Fenix's broker roster and instrument-token shapes, so the two compose cleanly.

Documentation

Full developer documentation β€” guides, architecture, the unified API reference, paper mode, constants, and a reference page per broker β€” lives at fenix.hardeep.tech.

License

Fenix is released under the GNU General Public License v3.0. See LICENSE for details.


Fenix
Built for the Indian markets Β· fenix.hardeep.tech