Fyers Market-Data Adapter for NinjaTrader 8
A custom NT8 data connection that streams live and historical NSE data from the Fyers API through a Python bridge, with OAuth login, licensing and an installer.

The problem
NinjaTrader 8 has no connection to Fyers, so Indian traders couldn’t chart NSE cash equities and indexes in NT8. The client wanted to hand out a free connector. Exchange rules forbid redistributing the data, so each end user had to log in with their own Fyers API app. The product also had to pass NinjaTrader’s vendor review.
What I built
- NT8 adapter built on NinjaTrader’s OpenConnect SDK (
AdapterBase,IAdapter). It supports Level 1 quotes, market depth, and daily and 1-minute history. - Python bridge that holds the Fyers WebSocket and REST sessions through the official SDK. It talks to the adapter over a localhost TCP socket using a small JSON command protocol (status, authenticate, subscribe, unsubscribe).
- OAuth login: the browser opens the Fyers login page, a local listener catches the redirect, and the auth code is exchanged for access and refresh tokens. Credentials are encrypted at rest with Windows DPAPI.
- History in NT8’s format: bars are written in NT8’s ASCII layout, and a symbol master is parsed from the NSE cash-market instrument file.
- Reconnect handling: the C# client reconnects with a retry counter. When the WebSocket layer reports that the stream came back, NT8 reloads the gap.
- Desktop app: Tkinter screens for the EULA, first-run setup, authentication and a status dashboard, with a single-instance lock. Packaged with PyInstaller.
- Distribution: an Inno Setup installer that checks for NT8, installs the adapter DLL, adds shortcuts and can remove saved credentials on uninstall.
- Licensing and protection: NT8 vendor licensing with a free trial, and an obfuscated release build of the adapter.
Details
- NT8 only checks the vendor licence when a connection is opened. A small add-on also calls the check at NT8 startup, so the trial starts without the user having to connect first.
- The login callback and the bridge use separate localhost ports, so a stuck OAuth listener can’t block market data.
- Found and fixed a DPAPI bug where decryption was called with the wrong argument count and failed silently. The only symptom was that saved credentials never auto-filled.