├── icon.png ├── Documentation ├── docs │ ├── assets │ │ ├── class.jpg │ │ ├── event.jpg │ │ ├── method.jpg │ │ ├── constant.jpg │ │ ├── favicon.png │ │ ├── property.jpg │ │ ├── pubfield.jpg │ │ ├── logo.svg │ │ └── style.css │ ├── license.md │ ├── quickstart.md │ ├── changelog.md │ └── index.md ├── mkdocs.yml └── process.py ├── KiteConnectTest ├── responses │ ├── error.json │ ├── ltp.json │ ├── mf_holdings.json │ ├── order_margins_compact.json │ ├── trades.json │ ├── mf_sip.json │ ├── equity_margins.json │ ├── ohlc.json │ ├── commodity_margins.json │ ├── historical.json │ ├── mf_sips.json │ ├── profile.json │ ├── mf_order.json │ ├── mf_orders.json │ ├── basket_margins_compact.json │ ├── margins.json │ ├── order_margins.json │ ├── holdings.json │ ├── gtt_get_order.json │ ├── orderinfo.json │ ├── quote.json │ ├── basket_margins.json │ ├── auction_instruments.json │ ├── gtt_get_orders.json │ ├── orders.json │ ├── positions.json │ ├── instruments_nse.csv │ ├── instruments_all.csv │ └── mf_instruments.csv ├── MockServer.cs ├── KiteConnectTest.csproj └── KiteTest.cs ├── KiteConnectSample ├── KiteConnectSample.csproj └── Program.cs ├── Makefile ├── KiteConnect ├── IWebSocket.cs ├── KiteConnect.csproj ├── ExceptionMessages.cs ├── Exceptions.cs ├── Constants.cs ├── Enums.cs ├── WebSocket.cs ├── Utils.cs └── Ticker.cs ├── LICENSE ├── KiteConnect.sln ├── README.md ├── CHANGELOG.md └── .gitignore /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/icon.png -------------------------------------------------------------------------------- /Documentation/docs/assets/class.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/class.jpg -------------------------------------------------------------------------------- /Documentation/docs/assets/event.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/event.jpg -------------------------------------------------------------------------------- /Documentation/docs/assets/method.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/method.jpg -------------------------------------------------------------------------------- /Documentation/docs/assets/constant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/constant.jpg -------------------------------------------------------------------------------- /Documentation/docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/favicon.png -------------------------------------------------------------------------------- /Documentation/docs/assets/property.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/property.jpg -------------------------------------------------------------------------------- /Documentation/docs/assets/pubfield.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodha/dotnetkiteconnect/HEAD/Documentation/docs/assets/pubfield.jpg -------------------------------------------------------------------------------- /KiteConnectTest/responses/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "error", 3 | "message": "Generic error message", 4 | "data": null, 5 | "error_type": "GeneralException" 6 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/ltp.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "NSE:INFY": { 5 | "instrument_token": 408065, 6 | "last_price": 989.2 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Documentation/docs/assets/logo.svg: -------------------------------------------------------------------------------- 1 | Kite logo trimmed -------------------------------------------------------------------------------- /KiteConnectSample/KiteConnectSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_holdings.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "folio": "123123/123", 6 | "fund": "Kotak Select Focus Fund - Direct Plan", 7 | "tradingsymbol": "INF174K01LS2", 8 | "average_price": 30.729, 9 | "last_price": 33.014, 10 | "pnl": 594.769, 11 | "last_price_date": "2016-11-11", 12 | "quantity": 260.337 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | @dotnet build -c Release KiteConnect/KiteConnect.csproj 4 | 5 | pack: 6 | @dotnet pack -c Release KiteConnect/KiteConnect.csproj 7 | 8 | clean: 9 | @rm -rf KiteConnect/bin 10 | @dotnet clean 11 | 12 | docs: 13 | @cp KiteConnect/bin/Release/net6.0/KiteConnect.xml Documentation/kiteconnect.xml 14 | cd Documentation; python3 process.py 15 | cp CHANGELOG.md Documentation/docs/changelog.md 16 | 17 | test: 18 | @dotnet test -------------------------------------------------------------------------------- /KiteConnectTest/responses/order_margins_compact.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "type": "equity", 6 | "tradingsymbol": "ASHOKLEY21JULFUT", 7 | "exchange": "NFO", 8 | "total": 30.2280825 9 | }, 10 | { 11 | "type": "equity", 12 | "tradingsymbol": "NIFTY21JUL15000PE", 13 | "exchange": "NFO", 14 | "total": 22500 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/trades.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "trade_id": "159918", 6 | "order_id": "151220000000000", 7 | "exchange_order_id": "511220371736111", 8 | "tradingsymbol": "ACC", 9 | "exchange": "NSE", 10 | "instrument_token": "22", 11 | "transaction_type": "BUY", 12 | "product": "MIS", 13 | "average_price": 100.98, 14 | "quantity": 10, 15 | "fill_timestamp": "2015-12-20 15:01:44", 16 | "exchange_timestamp": "2015-12-20 15:01:43" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_sip.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "sip_id": "1234", 5 | "tradingsymbol": "INF090I01239", 6 | "fund": "Franklin India Prima Plus", 7 | "dividend_type": "growth", 8 | "transaction_type": "BUY", 9 | "status": "ACTIVE", 10 | "created": "2016-01-01 13:00:00", 11 | "frequency": "monthly", 12 | "instalment_amount": 1000, 13 | "instalments": -1, 14 | "last_instalment": "2017-07-05 07:33:32", 15 | "pending_instalments": -1, 16 | "instalment_date": 5, 17 | "tag": "" 18 | } 19 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/equity_margins.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "enabled": true, 5 | "net": 1812.3535, 6 | "available": { 7 | "adhoc_margin": 0, 8 | "cash": 1927.505, 9 | "collateral": 0, 10 | "intraday_payin": 0 11 | }, 12 | "utilised": { 13 | "debits": 115.1515, 14 | "exposure": 0, 15 | "m2m_realised": 0, 16 | "m2m_unrealised": 0, 17 | "option_premium": 0, 18 | "payout": 0, 19 | "span": 0, 20 | "holding_sales": 0, 21 | "turnover": 0 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/ohlc.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "408065": { 5 | "instrument_token": 408065, 6 | "last_price": 966.8, 7 | "ohlc": { 8 | "open": 966.6, 9 | "high": 971.05, 10 | "low": 964.25, 11 | "close": 966.25 12 | } 13 | }, 14 | "NSE:INFY": { 15 | "instrument_token": 408065, 16 | "last_price": 966.8, 17 | "ohlc": { 18 | "open": 966.6, 19 | "high": 971.05, 20 | "low": 964.25, 21 | "close": 966.25 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/commodity_margins.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "enabled": true, 5 | "net": 1812.3535, 6 | "available": { 7 | "adhoc_margin": 0, 8 | "cash": 1927.505, 9 | "collateral": 0, 10 | "intraday_payin": 0 11 | }, 12 | "utilised": { 13 | "debits": 115.1515, 14 | "exposure": 0, 15 | "m2m_realised": 0, 16 | "m2m_unrealised": 0, 17 | "option_premium": 0, 18 | "payout": 0, 19 | "span": 0, 20 | "holding_sales": 0, 21 | "turnover": 0 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/historical.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "candles": [ 5 | [ "2017-09-08T13:00:00+0530", 886.7, 886.9, 886.5, 886.9, 2603 ], 6 | [ "2017-09-08T13:01:00+0530", 886.9, 886.95, 886.45, 886.45, 7547 ], 7 | [ "2017-09-08T13:02:00+0530", 886.45, 886.8, 886.3, 886.75, 4856 ], 8 | [ "2017-09-08T13:03:00+0530", 886.65, 887, 886.6, 886.75, 9102 ], 9 | [ "2017-09-08T13:04:00+0530", 886.75, 886.8, 886.55, 886.8, 9414 ], 10 | [ "2017-09-08T13:05:00+0530", 886.6, 886.95, 886.55, 886.9, 7469 ] 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /KiteConnect/IWebSocket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace KiteConnect 8 | { 9 | public interface IWebSocket 10 | { 11 | event OnConnectHandler OnConnect; 12 | event OnCloseHandler OnClose; 13 | event OnDataHandler OnData; 14 | event OnErrorHandler OnError; 15 | bool IsConnected(); 16 | void Connect(string Url, Dictionary headers = null); 17 | void Send(string Message); 18 | void Close(bool Abort = false); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_sips.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "sip_id": "1234", 6 | "tradingsymbol": "INF090I01239", 7 | "fund": "Franklin India Prima Plus", 8 | "dividend_type": "growth", 9 | "transaction_type": "BUY", 10 | "status": "ACTIVE", 11 | "created": "2016-01-01 13:00:00", 12 | "frequency": "monthly", 13 | "instalment_amount": 1000, 14 | "instalments": -1, 15 | "last_instalment": "2017-07-05 07:33:32", 16 | "pending_instalments": -1, 17 | "instalment_date": 5, 18 | "tag": "" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/profile.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "user_type": "investor", 5 | "email": "xxxyyy@gmail.com", 6 | "user_name": "AxAx Bxx", 7 | "user_shortname": "abc", 8 | "avatar_url": "http://zerodha.com", 9 | "broker": "ZERODHA", 10 | "exchanges": [ 11 | "BSE", 12 | "BFO", 13 | "NFO", 14 | "MCX", 15 | "CDS", 16 | "NSE" 17 | ], 18 | "products": [ 19 | "BO", 20 | "CNC", 21 | "CO", 22 | "MIS", 23 | "NRML" 24 | ], 25 | "order_types": [ 26 | "LIMIT", 27 | "MARKET", 28 | "SL", 29 | "SL-M" 30 | ] 31 | } 32 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "order_id": "123123", 5 | "exchange_order_id": "12341234", 6 | "tradingsymbol": "INF090I01239", 7 | "status": "COMPLETE", 8 | "status_message": "", 9 | "amount": 100, 10 | "folio": "1234ABC/123", 11 | "fund": "Franklin India Prima Plus", 12 | "order_timestamp": "2016-07-05 13:38", 13 | "exchange_timestamp": "2016-07-06", 14 | "settlement_id": "1617100", 15 | "transaction_type": "BUY", 16 | "variety": "regular", 17 | "purchase_type": "FRESH", 18 | "quantity": 10, 19 | "price": 0, 20 | "last_price": 580, 21 | "average_price": 500.4463, 22 | "placed_by": "AB0012", 23 | "tag": "" 24 | } 25 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_orders.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "order_id": "123123", 6 | "exchange_order_id": "12341234", 7 | "tradingsymbol": "INF090I01239", 8 | "status": "COMPLETE", 9 | "status_message": "", 10 | "amount": 100, 11 | "folio": "1234ABC/123", 12 | "fund": "Franklin India Prima Plus", 13 | "order_timestamp": "2016-07-05 13:38", 14 | "exchange_timestamp": "2016-07-06", 15 | "settlement_id": "1617100", 16 | "transaction_type": "BUY", 17 | "variety": "regular", 18 | "purchase_type": "FRESH", 19 | "quantity": 10, 20 | "price": 0, 21 | "last_price": 580, 22 | "last_price_date": "2016-07-10", 23 | "average_price": 500.4463, 24 | "placed_by": "AB0012", 25 | "tag": "" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /Documentation/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: KiteConnect .Net Docs 2 | nav: 3 | - Introduction: index.md 4 | - Quickstart: quickstart.md 5 | - Reference: reference.md 6 | - Changelog: changelog.md 7 | - License: license.md 8 | theme: 9 | palette: 10 | primary: 'white' 11 | accent: 'red' 12 | name: 'material' 13 | logo: 'assets/logo.svg' 14 | favicon: 'assets/favicon.png' 15 | 16 | repo_name: 'zerodhatech/dotnetkiteconnect' 17 | repo_url: 'https://github.com/zerodhatech/dotnetkiteconnect' 18 | 19 | copyright: 'Copyright © 2019 Zerodha Technology Pvt. Ltd.' 20 | 21 | extra_css: 22 | - assets/style.css 23 | 24 | extra: 25 | social: 26 | - type: 'github' 27 | link: 'https://github.com/zerodhatech/dotnetkiteconnect' 28 | 29 | markdown_extensions: 30 | - codehilite: 31 | guess_lang: false 32 | - toc: 33 | permalink: true -------------------------------------------------------------------------------- /KiteConnectTest/responses/basket_margins_compact.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "initial": { 5 | "type": "", 6 | "tradingsymbol": "", 7 | "exchange": "", 8 | "total": 22530.2280825 9 | }, 10 | "final": { 11 | "type": "", 12 | "tradingsymbol": "", 13 | "exchange": "", 14 | "total": 22530.2280825 15 | }, 16 | "orders": [ 17 | { 18 | "type": "equity", 19 | "tradingsymbol": "ASHOKLEY21JULFUT", 20 | "exchange": "NFO", 21 | "total": 30.2280825 22 | }, 23 | { 24 | "type": "equity", 25 | "tradingsymbol": "NIFTY21JUL15000PE", 26 | "exchange": "NFO", 27 | "total": 22500 28 | } 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Zerodha Technology Pvt. Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Documentation/docs/license.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | **The MIT License (MIT)** 4 | 5 | Copyright © 2018 Zerodha Technology Pvt. Ltd. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/margins.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "equity": { 5 | "enabled": true, 6 | "net": 1697.7, 7 | "available": { 8 | "adhoc_margin": 0, 9 | "cash": 1697.7, 10 | "collateral": 0, 11 | "intraday_payin": 0 12 | }, 13 | "utilised": { 14 | "debits": 0, 15 | "exposure": 0, 16 | "m2m_realised": 0, 17 | "m2m_unrealised": 0, 18 | "option_premium": 0, 19 | "payout": 0, 20 | "span": 0, 21 | "holding_sales": 0, 22 | "turnover": 0 23 | } 24 | }, 25 | "commodity": { 26 | "enabled": true, 27 | "net": -8676.296, 28 | "available": { 29 | "adhoc_margin": 0, 30 | "cash": -8676.296, 31 | "collateral": 0, 32 | "intraday_payin": 0 33 | }, 34 | "utilised": { 35 | "debits": 0, 36 | "exposure": 0, 37 | "m2m_realised": 0, 38 | "m2m_unrealised": 0, 39 | "option_premium": 0, 40 | "payout": 0, 41 | "span": 0, 42 | "holding_sales": 0, 43 | "turnover": 0 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/order_margins.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "type": "equity", 6 | "tradingsymbol": "ASHOKLEY20NOVFUT", 7 | "exchange": "NFO", 8 | "span": 5.408, 9 | "exposure": 0, 10 | "option_premium": 0, 11 | "additional": 0, 12 | "bo": 0, 13 | "cash": 0, 14 | "var": 1280, 15 | "pnl": { 16 | "realised": 0, 17 | "unrealised": 0 18 | }, 19 | "leverage": 5, 20 | "charges": { 21 | "transaction_tax": 0.5, 22 | "transaction_tax_type": "stt", 23 | "exchange_turnover_charge": 0.2208, 24 | "sebi_turnover_charge": 0.0063999999999999994, 25 | "brokerage": 1.92, 26 | "stamp_duty": 0.19, 27 | "gst": { 28 | "igst": 0.386496, 29 | "cgst": 0.1, 30 | "sgst": 0.2, 31 | "total": 0.386496 32 | }, 33 | "total": 2.723696 34 | }, 35 | "total": 8.36025 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /KiteConnectTest/MockServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace KiteConnectTest 9 | { 10 | 11 | class MockServer 12 | { 13 | readonly HttpListener httpListener = new(); 14 | string contentType = ""; 15 | string responseString = ""; 16 | int statusCode = 200; 17 | 18 | public MockServer(string url) 19 | { 20 | 21 | httpListener.Prefixes.Add(url); 22 | httpListener.Start(); 23 | Task.Run(() => HandleRequest()); 24 | } 25 | 26 | public void SetStatusCode(int code) { 27 | statusCode = code; 28 | } 29 | 30 | public void SetResponse(string contentType, string responseString) 31 | { 32 | this.contentType = contentType; 33 | this.responseString = responseString; 34 | } 35 | 36 | public void HandleRequest() 37 | { 38 | var context = httpListener.GetContext(); 39 | var response = context.Response; 40 | response.StatusCode = statusCode; 41 | response.ContentType = contentType; 42 | 43 | var buffer = System.Text.Encoding.UTF8.GetBytes(responseString); 44 | response.ContentLength64 = buffer.Length; 45 | response.Close(buffer, true); 46 | } 47 | 48 | public void Stop() 49 | { 50 | httpListener.Stop(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /KiteConnect/KiteConnect.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | Ajin Asokan 6 | Zerodha Technology Pvt. Ltd. 7 | Tech.Zerodha.KiteConnect 8 | 4.3.0 9 | 4.3.0 10 | 4.3.0 11 | The official .Net client for communicating with Kite Connect API. 12 | Copyright 2024 13 | MIT 14 | https://github.com/zerodhatech/dotnetkiteconnect 15 | https://kite.zerodha.com/static/images/kite-logo.svg 16 | icon.png 17 | https://github.com/zerodhatech/dotnetkiteconnect 18 | git 19 | zerodha kite connect client library 20 | Release 21 | 22 | true 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/holdings.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "tradingsymbol": "GOLDBEES", 6 | "exchange": "BSE", 7 | "instrument_token": 151064324, 8 | "isin": "INF204KB17I5", 9 | "product": "CNC", 10 | "price": 0, 11 | "quantity": 2, 12 | "used_quantity": 0, 13 | "t1_quantity": 0, 14 | "realised_quantity": 2, 15 | "authorised_quantity": 0, 16 | "authorised_date": "2021-06-08 00:00:00", 17 | "opening_quantity": 2, 18 | "collateral_quantity": 0, 19 | "collateral_type": "", 20 | "discrepancy": false, 21 | "average_price": 40.67, 22 | "last_price": 42.47, 23 | "close_price": 42.28, 24 | "pnl": 3.5999999999999943, 25 | "day_change": 0.18999999999999773, 26 | "day_change_percentage": 0.44938505203405327 27 | }, 28 | { 29 | "tradingsymbol": "IDEA", 30 | "exchange": "NSE", 31 | "instrument_token": 3677697, 32 | "isin": "INE669E01016", 33 | "product": "CNC", 34 | "price": 0, 35 | "quantity": 5, 36 | "used_quantity": 0, 37 | "t1_quantity": 0, 38 | "realised_quantity": 5, 39 | "authorised_quantity": 0, 40 | "authorised_date": "2021-06-08 00:00:00", 41 | "opening_quantity": 5, 42 | "collateral_quantity": 0, 43 | "collateral_type": "", 44 | "discrepancy": false, 45 | "average_price": 8.466, 46 | "last_price": 10, 47 | "close_price": 10.1, 48 | "pnl": 7.6700000000000035, 49 | "day_change": -0.09999999999999964, 50 | "day_change_percentage": -0.9900990099009866 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /KiteConnect/ExceptionMessages.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace System 6 | { 7 | internal static partial class ExceptionExtensions 8 | { 9 | 10 | /// 11 | /// Returns a list of all the exception messages from the top-level 12 | /// exception down through all the inner exceptions. Useful for making 13 | /// logs and error pages easier to read when dealing with exceptions. 14 | /// Usage: Exception.Messages() 15 | /// 16 | public static IEnumerable Messages(this Exception ex) 17 | { 18 | // return an empty sequence if the provided exception is null 19 | if (ex == null) { yield break; } 20 | // first return THIS exception's message at the beginning of the list 21 | yield return ex.Message; 22 | // then get all the lower-level exception messages recursively (if any) 23 | IEnumerable innerExceptions = Enumerable.Empty(); 24 | 25 | if (ex is AggregateException && (ex as AggregateException).InnerExceptions.Any()) 26 | { 27 | innerExceptions = (ex as AggregateException).InnerExceptions; 28 | } 29 | else if (ex.InnerException != null) 30 | { 31 | innerExceptions = new Exception[] { ex.InnerException }; 32 | } 33 | 34 | foreach (var innerEx in innerExceptions) 35 | { 36 | foreach (string msg in innerEx.Messages()) 37 | { 38 | yield return msg; 39 | } 40 | } 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /Documentation/docs/assets/style.css: -------------------------------------------------------------------------------- 1 | body[data-md-color-primary="white"] .md-header[data-md-state="shadow"] { 2 | background: #fff; 3 | box-shadow: none; 4 | color: #333; 5 | 6 | box-shadow: 1px 1px 3px #ddd; 7 | } 8 | 9 | .md-typeset .md-typeset__table table { 10 | border: 1px solid #ddd; 11 | box-shadow: 2px 2px 0 #f3f3f3; 12 | overflow: inherit; 13 | } 14 | 15 | body[data-md-color-primary="white"] .md-search__input { 16 | background: #f6f6f6; 17 | color: #333; 18 | } 19 | 20 | body[data-md-color-primary="white"] .md-sidebar--secondary .md-sidebar__scrollwrap { 21 | background: #f6f6f6; 22 | padding: 10px 0; 23 | } 24 | 25 | body[data-md-color-primary="white"] .md-header-nav__title { 26 | font-size: 0.75rem; 27 | line-height: 2.4rem; 28 | } 29 | 30 | body[data-md-color-primary="white"] .md-nav.md-nav--primary .md-nav__item { 31 | margin-bottom: 0.75rem; 32 | } 33 | 34 | body[data-md-color-primary="white"] .md-nav__item--active { 35 | font-weight: 600; 36 | color: inherit; 37 | } 38 | body[data-md-color-primary="white"] .md-nav__item--active a { 39 | color: #EF5350; 40 | } 41 | 42 | body[data-md-color-primary="white"] thead, 43 | body[data-md-color-primary="white"] .md-typeset table:not([class]) th { 44 | background: #f6f6f6; 45 | border: 0; 46 | color: inherit; 47 | font-weight: 600; 48 | } 49 | table td span { 50 | font-size: .85em; 51 | color: #bbb; 52 | display: block; 53 | } 54 | 55 | body[data-md-color-primary="white"] .md-typeset h1 { 56 | margin: 2rem 0 0 0; 57 | color: inherit; 58 | border-top: 1px solid #ddd; 59 | padding-top: 1rem; 60 | } 61 | body[data-md-color-primary="white"] .md-typeset h2 { 62 | border-top: 1px solid #eee; 63 | padding-top: 1rem; 64 | } 65 | 66 | body[data-md-color-primary="white"] .md-content h1:first-child { 67 | margin: 0 0 1.5rem 0; 68 | padding: 0; 69 | border: 0; 70 | } 71 | 72 | body[data-md-color-primary="white"] .md-typeset code { 73 | word-break: normal; 74 | } 75 | 76 | /* This hack places the #anchor-links correctly 77 | by accommodating for the fixed-header's height */ 78 | :target:before { 79 | content: ""; 80 | display: block; 81 | height: 120px; 82 | margin-top: -120px; 83 | } -------------------------------------------------------------------------------- /KiteConnect/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | 8 | namespace KiteConnect 9 | { 10 | public class KiteException : Exception 11 | { 12 | HttpStatusCode Status; 13 | public KiteException(string Message, HttpStatusCode HttpStatus, Exception innerException = null) : base(Message, innerException) { Status = HttpStatus; } 14 | } 15 | 16 | public class GeneralException : KiteException 17 | { 18 | public GeneralException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.InternalServerError, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 19 | } 20 | 21 | public class TokenException : KiteException 22 | { 23 | public TokenException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.Forbidden, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 24 | } 25 | 26 | 27 | public class PermissionException : KiteException 28 | { 29 | public PermissionException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.Forbidden, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 30 | } 31 | 32 | public class OrderException : KiteException 33 | { 34 | public OrderException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.BadRequest, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 35 | } 36 | 37 | public class InputException : KiteException 38 | { 39 | public InputException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.BadRequest, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 40 | } 41 | 42 | public class DataException : KiteException 43 | { 44 | public DataException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.BadGateway, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 45 | } 46 | 47 | public class NetworkException : KiteException 48 | { 49 | public NetworkException(string Message, HttpStatusCode HttpStatus = HttpStatusCode.ServiceUnavailable, Exception innerException = null) : base(Message, HttpStatus, innerException) { } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/gtt_get_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "id": 123, 5 | "user_id": "PH2965", 6 | "parent_trigger": null, 7 | "type": "two-leg", 8 | "created_at": "2019-09-09 17:13:26", 9 | "updated_at": "2019-09-09 17:13:26", 10 | "expires_at": "2020-09-09 17:13:26", 11 | "status": "active", 12 | "condition": { 13 | "exchange": "NSE", 14 | "last_price": 278, 15 | "tradingsymbol": "SBIN", 16 | "trigger_values": [ 17 | 264.1, 18 | 291.9 19 | ], 20 | "instrument_token": 779521 21 | }, 22 | "orders": [ 23 | { 24 | "account_id": "", 25 | "parent_order_id": "", 26 | "exchange": "NSE", 27 | "tradingsymbol": "SBIN", 28 | "validity": "", 29 | "product": "CNC", 30 | "order_type": "LIMIT", 31 | "transaction_type": "SELL", 32 | "quantity": 1, 33 | "disclosed_quantity": 0, 34 | "price": 264.1, 35 | "trigger_price": 0, 36 | "ltp_atp": "", 37 | "squareoff_abs_tick": "", 38 | "stoploss_abs_tick": "", 39 | "squareoff": 0, 40 | "stoploss": 0, 41 | "trailing_stoploss": 0, 42 | "meta": "", 43 | "guid": "", 44 | "result": null 45 | }, 46 | { 47 | "account_id": "", 48 | "parent_order_id": "", 49 | "exchange": "NSE", 50 | "tradingsymbol": "SBIN", 51 | "validity": "", 52 | "product": "CNC", 53 | "order_type": "LIMIT", 54 | "transaction_type": "SELL", 55 | "quantity": 1, 56 | "disclosed_quantity": 0, 57 | "price": 291.9, 58 | "trigger_price": 0, 59 | "ltp_atp": "", 60 | "squareoff_abs_tick": "", 61 | "stoploss_abs_tick": "", 62 | "squareoff": 0, 63 | "stoploss": 0, 64 | "trailing_stoploss": 0, 65 | "meta": "", 66 | "guid": "", 67 | "result": null 68 | } 69 | ], 70 | "meta": {} 71 | } 72 | } -------------------------------------------------------------------------------- /Documentation/process.py: -------------------------------------------------------------------------------- 1 | import re 2 | import xmltodict 3 | 4 | DOC_XML = './kiteconnect.xml' 5 | OUT_MD = './docs/reference.md' 6 | 7 | 8 | def xml_to_map(xml_file): 9 | with open(xml_file, "rb") as f: # notice the "rb" mode 10 | d = xmltodict.parse(f, xml_attribs=True) 11 | return d 12 | 13 | 14 | md = open(OUT_MD, 'w') 15 | xml = xml_to_map(DOC_XML) 16 | 17 | for member in xml['doc']['members']['member']: 18 | # member has a format like "M:KiteConnect.Kite.CancelMFOrder(System.String)" 19 | # mtype is a single char that is defined as: 20 | # M -> method - function 21 | # T -> type - class 22 | # P -> public field 23 | # E -> event 24 | mtype, mname = member['@name'].split(':') 25 | argtypes = [] 26 | 27 | # Hide delegates from docs. We will show only events 28 | if 'Handler' in mname and 'On' in mname: 29 | continue 30 | 31 | # remove namespace 32 | mname = mname.replace('KiteConnect.', '') 33 | mname = mname.split('(') 34 | 35 | # M means a function. collect argument types 36 | if mtype == 'M' and len(mname) > 1: 37 | mname[1] = re.sub( 38 | r'\Dictionary{(.*?),(.*?)\}', r'Dictionary{\1:\2}', mname[1]) 39 | argtypes = mname[1].replace('System.', '').rstrip(')').split(',') 40 | 41 | # clean the name 42 | mname = mname[0] 43 | mname = mname.replace('.#ctor', ' Constructor') 44 | 45 | # write to markdown file 46 | if mtype == 'M': 47 | md.write( 48 | '### ![Method](/assets/method.jpg)   ' + mname + '\n\n') 49 | elif mtype == 'T': 50 | md.write( 51 | '## ![Class](/assets/class.jpg)   ' + mname + ' Class\n\n') 52 | elif mtype == 'P': 53 | md.write( 54 | '### ![Field](/assets/pubfield.jpg)   ' + mname + '\n\n') 55 | elif mtype == 'E': 56 | md.write( 57 | '### ![Event](/assets/event.jpg)   ' + mname + '\n\n') 58 | 59 | # write explanation 60 | md.write(member['summary'] + '\n\n') 61 | 62 | # if it is function and has params print as table 63 | if 'param' in member: 64 | md.write('| Argument | Type | Description |\n') 65 | md.write('| --- | --- | --- |\n') 66 | 67 | if type(member['param']) == list: 68 | for i in range(len(member['param'])): 69 | param = member['param'][i] 70 | md.write('| ' + param['@name'] + ' | ' + argtypes[i] + 71 | ' | ' + param['#text'].replace('\n', '') + ' |\n') 72 | else: 73 | md.write('| ' + member['param']['@name'] + ' | ' + argtypes[0] + 74 | ' | ' + member['param']['#text'].replace('\n', '') + ' |\n') 75 | 76 | md.write('\n') 77 | 78 | # write return param 79 | if 'returns' in member: 80 | md.write('**Returns:** ' + member['returns'] + '\n\n') 81 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/orderinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "average_price": 0, 6 | "cancelled_quantity": 0, 7 | "disclosed_quantity": 0, 8 | "exchange": "BSE", 9 | "exchange_order_id": null, 10 | "exchange_timestamp": null, 11 | "filled_quantity": 0, 12 | "instrument_token": 4, 13 | "market_protection": 0, 14 | "order_id": "171124000819854", 15 | "order_timestamp": "2017-11-24 13:00:17", 16 | "order_type": "LIMIT", 17 | "parent_order_id": null, 18 | "pending_quantity": 100, 19 | "placed_by": "ZR0000", 20 | "price": 90, 21 | "product": "CNC", 22 | "quantity": 100, 23 | "status": "PUT ORDER REQ RECEIVED", 24 | "status_message": null, 25 | "tag": null, 26 | "tradingsymbol": "ASHOKLEY", 27 | "transaction_type": "BUY", 28 | "trigger_price": 0, 29 | "validity": "DAY", 30 | "variety": "regular" 31 | }, 32 | { 33 | "average_price": 0, 34 | "cancelled_quantity": 0, 35 | "disclosed_quantity": 0, 36 | "exchange": "BSE", 37 | "exchange_order_id": null, 38 | "exchange_timestamp": null, 39 | "filled_quantity": 0, 40 | "instrument_token": 128122116, 41 | "market_protection": 0, 42 | "order_id": "171124000819854", 43 | "order_timestamp": "2017-11-24 13:00:17", 44 | "order_type": "LIMIT", 45 | "parent_order_id": null, 46 | "pending_quantity": 100, 47 | "placed_by": "ZR0000", 48 | "price": 90, 49 | "product": "CNC", 50 | "quantity": 100, 51 | "status": "VALIDATION PENDING", 52 | "status_message": null, 53 | "tag": null, 54 | "tradingsymbol": "ASHOKLEY", 55 | "transaction_type": "BUY", 56 | "trigger_price": 0, 57 | "validity": "DAY", 58 | "variety": "regular" 59 | }, 60 | { 61 | "average_price": 0, 62 | "cancelled_quantity": 0, 63 | "disclosed_quantity": 0, 64 | "exchange": "BSE", 65 | "exchange_order_id": null, 66 | "exchange_timestamp": null, 67 | "filled_quantity": 0, 68 | "instrument_token": 128122116, 69 | "market_protection": 0, 70 | "order_id": "171124000819854", 71 | "order_timestamp": "2017-11-24 13:00:17", 72 | "order_type": "LIMIT", 73 | "parent_order_id": null, 74 | "pending_quantity": 0, 75 | "placed_by": "ZR0000", 76 | "price": 90, 77 | "product": "CNC", 78 | "quantity": 100, 79 | "status": "REJECTED", 80 | "status_message": "RMS:Rule: Check circuit limit including square off order exceeds for entity account-DH0490 across exchange across segment across product ", 81 | "tag": null, 82 | "tradingsymbol": "ASHOKLEY", 83 | "transaction_type": "BUY", 84 | "trigger_price": 0, 85 | "validity": "DAY", 86 | "variety": "regular" 87 | } 88 | ] 89 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/quote.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "NSE:ASHOKLEY": { 5 | "instrument_token": 54273, 6 | "timestamp": "2019-12-06 15:20:12", 7 | "last_trade_time": "2019-12-06 15:20:12", 8 | "last_price": 76.6, 9 | "last_quantity": 44, 10 | "buy_quantity": 1280874, 11 | "sell_quantity": 1190458, 12 | "volume": 12995404, 13 | "average_price": 76.35, 14 | "oi": 0, 15 | "oi_day_high": 0, 16 | "oi_day_low": 0, 17 | "net_change": 0, 18 | "lower_circuit_limit": 68.85, 19 | "upper_circuit_limit": 84.05, 20 | "ohlc": { 21 | "open": 76.9, 22 | "high": 77.2, 23 | "low": 75.65, 24 | "close": 76.45 25 | }, 26 | "depth": { 27 | "buy": [ 28 | { 29 | "price": 76.5, 30 | "quantity": 14620, 31 | "orders": 12 32 | }, 33 | { 34 | "price": 76.45, 35 | "quantity": 16931, 36 | "orders": 31 37 | }, 38 | { 39 | "price": 76.4, 40 | "quantity": 109466, 41 | "orders": 32 42 | }, 43 | { 44 | "price": 76.35, 45 | "quantity": 13664, 46 | "orders": 24 47 | }, 48 | { 49 | "price": 76.3, 50 | "quantity": 14116, 51 | "orders": 33 52 | } 53 | ], 54 | "sell": [ 55 | { 56 | "price": 76.6, 57 | "quantity": 54310, 58 | "orders": 50 59 | }, 60 | { 61 | "price": 76.65, 62 | "quantity": 13405, 63 | "orders": 24 64 | }, 65 | { 66 | "price": 76.7, 67 | "quantity": 13549, 68 | "orders": 28 69 | }, 70 | { 71 | "price": 76.75, 72 | "quantity": 17646, 73 | "orders": 29 74 | }, 75 | { 76 | "price": 76.8, 77 | "quantity": 11477, 78 | "orders": 24 79 | } 80 | ] 81 | } 82 | }, 83 | "NSE:NIFTY 50": { 84 | "instrument_token": 256265, 85 | "tradingsymbol": "NIFTY 50", 86 | "timestamp": "2019-12-06 15:20:12", 87 | "last_price": 11917.6, 88 | "net_change": -100.8, 89 | "ohlc": { 90 | "open": 12047.35, 91 | "high": 12057.05, 92 | "low": 11888.85, 93 | "close": 12018.4 94 | } 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /KiteConnectTest/responses/basket_margins.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "initial": { 5 | "type": "", 6 | "tradingsymbol": "", 7 | "exchange": "", 8 | "span": 0, 9 | "exposure": 0, 10 | "option_premium": 112.5, 11 | "additional": 0, 12 | "bo": 0, 13 | "cash": 0, 14 | "var": 0, 15 | "pnl": { 16 | "realised": 0, 17 | "unrealised": 0 18 | }, 19 | "leverage": 0, 20 | "charges": { 21 | "transaction_tax": 0, 22 | "transaction_tax_type": "", 23 | "exchange_turnover_charge": 0, 24 | "sebi_turnover_charge": 0, 25 | "brokerage": 0, 26 | "stamp_duty": 0, 27 | "gst": { 28 | "igst": 0, 29 | "cgst": 0, 30 | "sgst": 0, 31 | "total": 0 32 | }, 33 | "total": 0 34 | }, 35 | "total": 112.5 36 | }, 37 | "final": { 38 | "type": "", 39 | "tradingsymbol": "", 40 | "exchange": "", 41 | "span": 26.9577, 42 | "exposure": 0, 43 | "option_premium": 112.5, 44 | "additional": 0, 45 | "bo": 0, 46 | "cash": 0, 47 | "var": 0, 48 | "pnl": { 49 | "realised": 0, 50 | "unrealised": 0 51 | }, 52 | "leverage": 0, 53 | "charges": { 54 | "transaction_tax": 0, 55 | "transaction_tax_type": "", 56 | "exchange_turnover_charge": 0, 57 | "sebi_turnover_charge": 0, 58 | "brokerage": 0, 59 | "stamp_duty": 0, 60 | "gst": { 61 | "igst": 0, 62 | "cgst": 0, 63 | "sgst": 0, 64 | "total": 0 65 | }, 66 | "total": 0 67 | }, 68 | "total": 22530.221345 69 | }, 70 | "orders": [ 71 | { 72 | "type": "equity", 73 | "tradingsymbol": "NIFTY23JAN14750PE", 74 | "exchange": "NFO", 75 | "span": 0, 76 | "exposure": 0, 77 | "option_premium": 112.5, 78 | "additional": 0, 79 | "bo": 0, 80 | "cash": 0, 81 | "var": 0, 82 | "pnl": { 83 | "realised": 0, 84 | "unrealised": 0 85 | }, 86 | "leverage": 1, 87 | "charges": { 88 | "transaction_tax": 0, 89 | "transaction_tax_type": "", 90 | "exchange_turnover_charge": 0, 91 | "sebi_turnover_charge": 0, 92 | "brokerage": 0, 93 | "stamp_duty": 0, 94 | "gst": { 95 | "igst": 0, 96 | "cgst": 0, 97 | "sgst": 0, 98 | "total": 0 99 | }, 100 | "total": 0 101 | }, 102 | "total": 112.5 103 | } 104 | ] 105 | } 106 | } -------------------------------------------------------------------------------- /KiteConnect/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace KiteConnect 8 | { 9 | public class Constants 10 | { 11 | 12 | // Products 13 | public const string PRODUCT_MIS = "MIS"; 14 | public const string PRODUCT_CNC = "CNC"; 15 | public const string PRODUCT_NRML = "NRML"; 16 | 17 | // Order types 18 | public const string ORDER_TYPE_MARKET = "MARKET"; 19 | public const string ORDER_TYPE_LIMIT = "LIMIT"; 20 | public const string ORDER_TYPE_SLM = "SL-M"; 21 | public const string ORDER_TYPE_SL = "SL"; 22 | 23 | // Order status 24 | public const string ORDER_STATUS_COMPLETE = "COMPLETE"; 25 | public const string ORDER_STATUS_CANCELLED = "CANCELLED"; 26 | public const string ORDER_STATUS_REJECTED = "REJECTED"; 27 | 28 | // Varities 29 | public const string VARIETY_REGULAR = "regular"; 30 | public const string VARIETY_BO = "bo"; 31 | public const string VARIETY_CO = "co"; 32 | public const string VARIETY_AMO = "amo"; 33 | public const string VARIETY_ICEBERG = "iceberg"; 34 | public const string VARIETY_AUCTION = "auction"; 35 | 36 | // Transaction type 37 | public const string TRANSACTION_TYPE_BUY = "BUY"; 38 | public const string TRANSACTION_TYPE_SELL = "SELL"; 39 | 40 | // Validity 41 | public const string VALIDITY_DAY = "DAY"; 42 | public const string VALIDITY_IOC = "IOC"; 43 | public const string VALIDITY_TTL = "TTL"; 44 | 45 | // Exchanges 46 | public const string EXCHANGE_NSE = "NSE"; 47 | public const string EXCHANGE_BSE = "BSE"; 48 | public const string EXCHANGE_NFO = "NFO"; 49 | public const string EXCHANGE_CDS = "CDS"; 50 | public const string EXCHANGE_BFO = "BFO"; 51 | public const string EXCHANGE_MCX = "MCX"; 52 | 53 | // Margins segments 54 | public const string MARGIN_EQUITY = "equity"; 55 | public const string MARGIN_COMMODITY = "commodity"; 56 | 57 | // Margin modes 58 | public const string MARGIN_MODE_COMPACT = "compact"; 59 | 60 | // Ticker modes 61 | public const string MODE_FULL = "full"; 62 | public const string MODE_QUOTE = "quote"; 63 | public const string MODE_LTP = "ltp"; 64 | 65 | // Positions 66 | public const string POSITION_DAY = "day"; 67 | public const string POSITION_OVERNIGHT = "overnight"; 68 | 69 | // Historical intervals 70 | public const string INTERVAL_MINUTE = "minute"; 71 | public const string INTERVAL_3MINUTE = "3minute"; 72 | public const string INTERVAL_5MINUTE = "5minute"; 73 | public const string INTERVAL_10MINUTE = "10minute"; 74 | public const string INTERVAL_15MINUTE = "15minute"; 75 | public const string INTERVAL_30MINUTE = "30minute"; 76 | public const string INTERVAL_60MINUTE = "60minute"; 77 | public const string INTERVAL_DAY = "day"; 78 | 79 | // GTT status 80 | public const string GTT_ACTIVE = "active"; 81 | public const string GTT_TRIGGERED = "triggered"; 82 | public const string GTT_DISABLED = "disabled"; 83 | public const string GTT_EXPIRED = "expired"; 84 | public const string GTT_CANCELLED = "cancelled"; 85 | public const string GTT_REJECTED = "rejected"; 86 | public const string GTT_DELETED = "deleted"; 87 | 88 | 89 | // GTT trigger type 90 | public const string GTT_TRIGGER_OCO = "two-leg"; 91 | public const string GTT_TRIGGER_SINGLE = "single"; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/auction_instruments.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "tradingsymbol": "ITC", 6 | "exchange": "NSE", 7 | "instrument_token": 424970, 8 | "isin": "INE154A01025", 9 | "product": "CNC", 10 | "price": 0, 11 | "quantity": 8, 12 | "t1_quantity": 0, 13 | "realised_quantity": 8, 14 | "authorised_quantity": 0, 15 | "authorised_date": "2023-01-13 00:00:00", 16 | "opening_quantity": 8, 17 | "collateral_quantity": 0, 18 | "collateral_type": "", 19 | "discrepancy": false, 20 | "average_price": 258, 21 | "last_price": 328.6, 22 | "close_price": 329.85, 23 | "pnl": 564.8000000000002, 24 | "day_change": -1.25, 25 | "day_change_percentage": -0.37896013339396695, 26 | "auction_number": "2568" 27 | }, 28 | { 29 | "tradingsymbol": "NCC", 30 | "exchange": "NSE", 31 | "instrument_token": 593674, 32 | "isin": "INE868B01028", 33 | "product": "CNC", 34 | "price": 0, 35 | "quantity": 1, 36 | "t1_quantity": 0, 37 | "realised_quantity": 1, 38 | "authorised_quantity": 0, 39 | "authorised_date": "2023-01-13 00:00:00", 40 | "opening_quantity": 1, 41 | "collateral_quantity": 0, 42 | "collateral_type": "", 43 | "discrepancy": false, 44 | "average_price": 100.15, 45 | "last_price": 92.7, 46 | "close_price": 93.4, 47 | "pnl": -7.450000000000003, 48 | "day_change": -0.7000000000000028, 49 | "day_change_percentage": -0.7494646680942214, 50 | "auction_number": "5049" 51 | }, 52 | { 53 | "tradingsymbol": "NILASPACES", 54 | "exchange": "NSE", 55 | "instrument_token": 1897226, 56 | "isin": "INE00S901012", 57 | "product": "CNC", 58 | "price": 0, 59 | "quantity": 1, 60 | "t1_quantity": 0, 61 | "realised_quantity": 1, 62 | "authorised_quantity": 0, 63 | "authorised_date": "2023-01-13 00:00:00", 64 | "opening_quantity": 1, 65 | "collateral_quantity": 0, 66 | "collateral_type": "", 67 | "discrepancy": false, 68 | "average_price": 2.45, 69 | "last_price": 3.55, 70 | "close_price": 3.52, 71 | "pnl": 1.0999999999999996, 72 | "day_change": 0.029999999999999805, 73 | "day_change_percentage": 0.8522727272727216, 74 | "auction_number": "5053" 75 | }, 76 | { 77 | "tradingsymbol": "UCOBANK", 78 | "exchange": "NSE", 79 | "instrument_token": 2873098, 80 | "isin": "INE691A01018", 81 | "product": "CNC", 82 | "price": 0, 83 | "quantity": 1, 84 | "t1_quantity": 0, 85 | "realised_quantity": 1, 86 | "authorised_quantity": 0, 87 | "authorised_date": "2023-01-13 00:00:00", 88 | "opening_quantity": 1, 89 | "collateral_quantity": 0, 90 | "collateral_type": "", 91 | "discrepancy": false, 92 | "average_price": 32.9, 93 | "last_price": 30.05, 94 | "close_price": 29.9, 95 | "pnl": -2.849999999999998, 96 | "day_change": 0.15000000000000213, 97 | "day_change_percentage": 0.5016722408026827, 98 | "auction_number": "7558" 99 | } 100 | ] 101 | } -------------------------------------------------------------------------------- /KiteConnect/Enums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace KiteConnect 8 | { 9 | //public enum Segments 10 | // { 11 | // Equity, 12 | // Commodity, 13 | // Futures, 14 | // Currency 15 | // } 16 | 17 | // public enum TransactionTypes 18 | // { 19 | // Buy, 20 | // Sell 21 | // } 22 | 23 | // public enum OrderTypes 24 | // { 25 | // MARKET, 26 | // LIMIT, 27 | // SL, 28 | // SLM 29 | // } 30 | 31 | // public enum ProductTypes 32 | // { 33 | // MIS, 34 | // CNC, 35 | // NRML 36 | // } 37 | 38 | // public enum VarietyTypes 39 | // { 40 | // Regular, 41 | // BO, 42 | // CO, 43 | // AMO 44 | // } 45 | 46 | // public enum TickerModes 47 | // { 48 | // Full, 49 | // Quote, 50 | // LTP 51 | // } 52 | 53 | // public enum PositionTypes 54 | // { 55 | // Day, 56 | // Overnight 57 | // } 58 | 59 | // public enum ValidityTypes 60 | // { 61 | // DAY, 62 | // IOC, 63 | // AMO 64 | // } 65 | 66 | // public enum Exchanges 67 | // { 68 | // NSE, 69 | // BSE, 70 | // NFO, 71 | // CDS, 72 | // MCX 73 | // } 74 | 75 | // public enum CandleIntervals 76 | // { 77 | // Minute, 78 | // ThreeMinute, 79 | // FiveMinute, 80 | // TenMinute, 81 | // FifteenMinute, 82 | // ThirtyMinute, 83 | // SixtyMinute, 84 | // Day 85 | // } 86 | 87 | // public enum SIPFrequency 88 | // { 89 | // Weekly, 90 | // Monthly, 91 | // Quarterly 92 | // } 93 | 94 | // public enum SIPStatus 95 | // { 96 | // Active, 97 | // Paused 98 | // } 99 | 100 | // public class Constants 101 | // { 102 | // static Dictionary> values = new Dictionary> 103 | // { 104 | // [typeof(Segments).Name] = new List { "equity", "commodity", "futures", "currency" }, 105 | // [typeof(TransactionTypes).Name] = new List { "BUY", "SELL" }, 106 | // [typeof(OrderTypes).Name] = new List { "MARKET", "LIMIT", "SL", "SL-M" }, 107 | // [typeof(ProductTypes).Name] = new List { "MIS", "CNC", "NRML" }, 108 | // [typeof(VarietyTypes).Name] = new List { "regular", "bo", "co", "amo" }, 109 | // [typeof(TickerModes).Name] = new List { "full", "quote", "ltp" }, 110 | // [typeof(PositionTypes).Name] = new List { "day", "overnight" }, 111 | // [typeof(ValidityTypes).Name] = new List { "DAY", "IOC", "AMO" }, 112 | // [typeof(Exchanges).Name] = new List { "NSE", "BSE", "NFO", "CDS", "MCX"}, 113 | // [typeof(CandleIntervals).Name] = new List { "minute", "3minute", "5minute", "10minute", "15minute", "30minute", "60minute", "day" }, 114 | // [typeof(SIPFrequency).Name] = new List { "weekly", "monthly", "quarterly" }, 115 | // [typeof(SIPStatus).Name] = new List { "active", "paused" }, 116 | // }; 117 | 118 | // public static T ToEnum(string value) 119 | // { 120 | // return (T)(object) values[typeof(T).Name].IndexOf(value); 121 | // } 122 | 123 | // public static string ToValue(T enumValue) 124 | // { 125 | // if(enumValue == null) 126 | // return ""; 127 | // var index = Enum.GetNames(typeof(T)).ToList().IndexOf(enumValue.ToString()); 128 | // return values[typeof(T).Name][index]; 129 | // } 130 | //} 131 | } 132 | -------------------------------------------------------------------------------- /Documentation/docs/quickstart.md: -------------------------------------------------------------------------------- 1 | 2 | Once you complete your installation process you can try out some following examples to verify that everything works fine. 3 | 4 | ## Authentication 5 | ```csharp 6 | // Import library 7 | using KiteConnect; 8 | 9 | // Initialize Kiteconnect using apiKey. Enabling Debug will give logs of requests and responses 10 | Kite kite = new Kite(MyAPIKey, Debug: true); 11 | 12 | // Collect login url to authenticate user. Load this URL in browser or WebView. 13 | // After successful authentication this will redirect to your redirect url with request token. 14 | kite.GetLoginURL(); 15 | 16 | // Collect tokens and user details using the request token 17 | User user = kite.RequestAccessToken(RequestToken, MySecret); 18 | 19 | // Persist these tokens in database or settings 20 | string MyAccessToken = user.AccessToken; 21 | string MyPublicToken = user.PublicToken; 22 | 23 | // Initialize Kite APIs with access token 24 | kite.SetAccessToken(MyAccessToken); 25 | 26 | // Set session expiry callback. Method can be separate function also. 27 | kite.SetSessionExpiryHook(() => Console.WriteLine("Need to login again")); 28 | ``` 29 | 30 | ## Placing order 31 | ```csharp 32 | // Example call for functions like "PlaceOrder" that returns Dictionary 33 | Dictionary response = kite.PlaceOrder( 34 | Exchange: Constants.EXCHANGE_CDS, 35 | TradingSymbol: "USDINR17AUGFUT", 36 | TransactionType: Constants.TRANSACTION_TYPE_SELL, 37 | Quantity: 1, 38 | Price: 64.0000m, 39 | OrderType: Constants.ORDER_TYPE_MARKET, 40 | Product: Constants.PRODUCT_MIS 41 | ); 42 | Console.WriteLine("Order Id: " + response["data"]["order_id"]); 43 | ``` 44 | 45 | ## Fetch holdings 46 | ```csharp 47 | // Example call for functions like "GetHoldings" that returns a data structure 48 | List holdings = kite.GetHoldings(); 49 | Console.WriteLine(holdings[0].AveragePrice); 50 | ``` 51 | 52 | For more examples, take a look at [Program.cs](https://github.com/rainmattertech/dotnetkiteconnect/blob/master/KiteConnect%20Sample/Program.cs) of **KiteConnect Sample** project. 53 | 54 | ## WebSocket live streaming example 55 | 56 | This library uses Events to get ticks. These events are non blocking and can be used without additional threads. Create event handlers and attach it to Ticker instance as shown in the example below. 57 | 58 | ```csharp 59 | /* 60 | To get live price use KiteTicker websocket connection. 61 | It is recommended to use only one websocket connection at any point of time and make sure you stop connection, 62 | once user goes out of app. 63 | */ 64 | 65 | // Create a new Ticker instance 66 | Ticker ticker = new Ticker(MyAPIKey, MyUserId, MyAccessToken, Root: "wss://websocket.kite.trade/v3"); 67 | 68 | // Add handlers to events 69 | ticker.OnTick += onTick; 70 | ticker.OnOrderUpdate += OnOrderUpdate; 71 | ticker.OnReconnect += onReconnect; 72 | ticker.OnNoReconnect += oNoReconnect; 73 | ticker.OnError += onError; 74 | ticker.OnClose += onClose; 75 | ticker.OnConnect += onConnect; 76 | 77 | // Engage reconnection mechanism and connect to ticker 78 | ticker.EnableReconnect(Interval: 5,Retries: 50); 79 | ticker.Connect(); 80 | 81 | // Subscribing to NIFTY50 and setting mode to LTP 82 | ticker.Subscribe(Tokens: new string[] { "256265" }); 83 | ticker.SetMode(Tokens: new string[] { "256265" }, Mode: Constants.MODE_LTP); 84 | 85 | // Example onTick handler 86 | private static void onTick(Tick TickData) 87 | { 88 | Console.WriteLine("LTP: " + TickData.LastPrice); 89 | } 90 | 91 | private static void OnOrderUpdate(Order OrderData) 92 | { 93 | Console.WriteLine("OrderUpdate " + Utils.JsonSerialize(OrderData)); 94 | } 95 | 96 | // Disconnect ticker before closing the application 97 | ticker.Close(); 98 | ``` 99 | 100 | For more details about different mode of quotes and subscribing for them, take a look at [Sample projct](https://github.com/zerodhatech/dotnetkiteconnect/tree/master/KiteConnectSample) and [HTTP API documentation](https://kite.trade/docs/connect/). -------------------------------------------------------------------------------- /KiteConnect.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiteConnect", "KiteConnect\KiteConnect.csproj", "{30701F40-E1C3-4D08-AD21-08E3849C0A8C}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiteConnectSample", "KiteConnectSample\KiteConnectSample.csproj", "{EEF93ADC-0258-45C7-B3CD-1B37615D2779}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiteConnectTest", "KiteConnectTest\KiteConnectTest.csproj", "{78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|x64.ActiveCfg = Debug|Any CPU 28 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|x64.Build.0 = Debug|Any CPU 29 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|x86.ActiveCfg = Debug|Any CPU 30 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Debug|x86.Build.0 = Debug|Any CPU 31 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|x64.ActiveCfg = Release|Any CPU 34 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|x64.Build.0 = Release|Any CPU 35 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|x86.ActiveCfg = Release|Any CPU 36 | {30701F40-E1C3-4D08-AD21-08E3849C0A8C}.Release|x86.Build.0 = Release|Any CPU 37 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|x64.ActiveCfg = Debug|Any CPU 40 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|x64.Build.0 = Debug|Any CPU 41 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|x86.ActiveCfg = Debug|Any CPU 42 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Debug|x86.Build.0 = Debug|Any CPU 43 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|x64.ActiveCfg = Release|Any CPU 46 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|x64.Build.0 = Release|Any CPU 47 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|x86.ActiveCfg = Release|Any CPU 48 | {EEF93ADC-0258-45C7-B3CD-1B37615D2779}.Release|x86.Build.0 = Release|Any CPU 49 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|x64.ActiveCfg = Debug|Any CPU 52 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|x64.Build.0 = Debug|Any CPU 53 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|x86.ActiveCfg = Debug|Any CPU 54 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Debug|x86.Build.0 = Debug|Any CPU 55 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|x64.ActiveCfg = Release|Any CPU 58 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|x64.Build.0 = Release|Any CPU 59 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|x86.ActiveCfg = Release|Any CPU 60 | {78D389D0-E1A4-4A8E-BC7E-4662D8BE2B2D}.Release|x86.Build.0 = Release|Any CPU 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/gtt_get_orders.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "id": 105099, 6 | "user_id": "PH2965", 7 | "parent_trigger": null, 8 | "type": "two-leg", 9 | "created_at": "2019-09-09 15:13:22", 10 | "updated_at": "2019-09-09 15:15:08", 11 | "expires_at": "2020-01-01 12:00:00", 12 | "status": "triggered", 13 | "condition": { 14 | "exchange": "NSE", 15 | "last_price": 102.6, 16 | "tradingsymbol": "RAIN", 17 | "trigger_values": [ 18 | 102, 19 | 103.7 20 | ], 21 | "instrument_token": 3926273 22 | }, 23 | "orders": [ 24 | { 25 | "account_id": "", 26 | "parent_order_id": "", 27 | "exchange": "NSE", 28 | "tradingsymbol": "RAIN", 29 | "validity": "", 30 | "product": "CNC", 31 | "order_type": "LIMIT", 32 | "transaction_type": "SELL", 33 | "quantity": 1, 34 | "disclosed_quantity": 0, 35 | "price": 1, 36 | "trigger_price": 0, 37 | "ltp_atp": "", 38 | "squareoff_abs_tick": "", 39 | "stoploss_abs_tick": "", 40 | "squareoff": 0, 41 | "stoploss": 0, 42 | "trailing_stoploss": 0, 43 | "meta": "", 44 | "guid": "", 45 | "result": null 46 | }, 47 | { 48 | "account_id": "", 49 | "parent_order_id": "", 50 | "exchange": "NSE", 51 | "tradingsymbol": "RAIN", 52 | "validity": "", 53 | "product": "CNC", 54 | "order_type": "LIMIT", 55 | "transaction_type": "SELL", 56 | "quantity": 1, 57 | "disclosed_quantity": 0, 58 | "price": 1, 59 | "trigger_price": 0, 60 | "ltp_atp": "", 61 | "squareoff_abs_tick": "", 62 | "stoploss_abs_tick": "", 63 | "squareoff": 0, 64 | "stoploss": 0, 65 | "trailing_stoploss": 0, 66 | "meta": "", 67 | "guid": "", 68 | "result": { 69 | "account_id": "PH2965", 70 | "parent_order_id": "", 71 | "exchange": "NSE", 72 | "tradingsymbol": "RAIN", 73 | "validity": "DAY", 74 | "product": "CNC", 75 | "order_type": "LIMIT", 76 | "transaction_type": "SELL", 77 | "quantity": 1, 78 | "disclosed_quantity": 0, 79 | "price": 1, 80 | "trigger_price": 0, 81 | "ltp_atp": "LTP", 82 | "squareoff_abs_tick": "absolute", 83 | "stoploss_abs_tick": "absolute", 84 | "squareoff": 0, 85 | "stoploss": 0, 86 | "trailing_stoploss": 0, 87 | "meta": "{\"app_id\":12617,\"gtt\":105099}", 88 | "guid": "", 89 | "timestamp": "2019-09-09 15:15:08", 90 | "triggered_at": 103.7, 91 | "order_result": { 92 | "status": "failed", 93 | "order_id": "", 94 | "rejection_reason": "Your order price is lower than the current lower circuit limit of 70.65. Place an order within the daily range." 95 | } 96 | } 97 | } 98 | ], 99 | "meta": null 100 | } 101 | ] 102 | } -------------------------------------------------------------------------------- /KiteConnectTest/KiteConnectTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Always 21 | 22 | 23 | Always 24 | 25 | 26 | Always 27 | 28 | 29 | Always 30 | 31 | 32 | Always 33 | 34 | 35 | Always 36 | 37 | 38 | Always 39 | 40 | 41 | Always 42 | 43 | 44 | Always 45 | 46 | 47 | Always 48 | 49 | 50 | Always 51 | 52 | 53 | Always 54 | 55 | 56 | Always 57 | 58 | 59 | Always 60 | 61 | 62 | Always 63 | 64 | 65 | Always 66 | 67 | 68 | Always 69 | 70 | 71 | Always 72 | 73 | 74 | Always 75 | 76 | 77 | Always 78 | 79 | 80 | Always 81 | 82 | 83 | Always 84 | 85 | 86 | Always 87 | 88 | 89 | Always 90 | 91 | 92 | Always 93 | 94 | 95 | Always 96 | 97 | 98 | Always 99 | 100 | 101 | Always 102 | 103 | 104 | Always 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kite Connect .Net library 2 | The official .Net client for communicating with [Kite Connect API](https://kite.trade). 3 | 4 | Kite Connect is a set of REST-like APIs that expose many capabilities required to build a complete investment and trading platform. Execute orders in real time, manage user portfolio, stream live market data (WebSockets), and more, with the simple HTTP API collection. 5 | 6 | [Zerodha Technology Pvt. Ltd.](http://zerodha.com) © 2023. Licensed under the [MIT License](/license/). 7 | 8 | ## Documentation 9 | 10 | * [.Net Library](https://kite.trade/docs/kiteconnectdotnet/) 11 | * [HTTP API](https://kite.trade/docs/connect/) 12 | 13 | ## Install Client Library 14 | 15 | 16 | ### Using NuGet 17 | 18 | Execute in **Tools** » **NuGet Package Manager** » **Package Manager Console** 19 | 20 | ``` 21 | Install-Package Tech.Zerodha.KiteConnect 22 | ``` 23 | ### Using .Net CLI 24 | 25 | ``` 26 | dotnet add package Tech.Zerodha.KiteConnect 27 | ``` 28 | 29 | ## Getting started 30 | ```csharp 31 | // Import library 32 | using KiteConnect; 33 | 34 | // Initialize Kiteconnect using apiKey. Enabling Debug will give logs of requests and responses 35 | Kite kite = new Kite(MyAPIKey, Debug: true); 36 | 37 | // Collect login url to authenticate user. Load this URL in browser or WebView. 38 | // After successful authentication this will redirect to your redirect url with request token. 39 | kite.GetLoginURL(); 40 | 41 | // Collect tokens and user details using the request token 42 | User user = kite.GenerateSession(RequestToken, MySecret); 43 | 44 | // Persist these tokens in database or settings 45 | string MyAccessToken = user.AccessToken; 46 | string MyPublicToken = user.PublicToken; 47 | 48 | // Initialize Kite APIs with access token 49 | kite.SetAccessToken(MyAccessToken); 50 | 51 | // Set session expiry callback. Method can be separate function also. 52 | kite.SetSessionExpiryHook(() => Console.WriteLine("Need to login again")); 53 | 54 | // Example call for functions like "PlaceOrder" that returns Dictionary 55 | Dictionary response = kite.PlaceOrder( 56 | Exchange: Constants.EXCHANGE_CDS, 57 | TradingSymbol: "USDINR17AUGFUT", 58 | TransactionType: Constants.TRANSACTION_TYPE_SELL, 59 | Quantity: 1, 60 | Price: 64.0000m, 61 | OrderType: Constants.ORDER_TYPE_MARKET, 62 | Product: Constants.PRODUCT_MIS 63 | ); 64 | Console.WriteLine("Order Id: " + response["data"]["order_id"]); 65 | 66 | // Example call for functions like "GetHoldings" that returns a data structure 67 | List holdings = kite.GetHoldings(); 68 | Console.WriteLine(holdings[0].AveragePrice); 69 | 70 | ``` 71 | For more examples, take a look at [Program.cs](https://github.com/zerodhatech/dotnetkiteconnect/blob/kite3/KiteConnectSample/Program.cs) of **KiteConnect Sample** project in this repository. 72 | 73 | ## WebSocket live streaming data 74 | 75 | This library uses Events to get ticks. These events are non blocking and can be used without additional threads. Create event handlers and attach it to Ticker instance as shown in the example below. 76 | 77 | ```csharp 78 | /* 79 | To get live price use KiteTicker websocket connection. 80 | It is recommended to use only one websocket connection at any point of time and make sure you stop connection, 81 | once user goes out of app. 82 | */ 83 | 84 | // Create a new Ticker instance 85 | Ticker ticker = new Ticker(MyAPIKey, MyAccessToken); 86 | 87 | // Add handlers to events 88 | ticker.OnTick += onTick; 89 | ticker.OnOrderUpdate += OnOrderUpdate; 90 | ticker.OnReconnect += onReconnect; 91 | ticker.OnNoReconnect += oNoReconnect; 92 | ticker.OnError += onError; 93 | ticker.OnClose += onClose; 94 | ticker.OnConnect += onConnect; 95 | 96 | // Engage reconnection mechanism and connect to ticker 97 | ticker.EnableReconnect(Interval: 5,Retries: 50); 98 | ticker.Connect(); 99 | 100 | // Subscribing to NIFTY50 and setting mode to LTP 101 | ticker.Subscribe(Tokens: new UInt32[] { 256265 }); 102 | ticker.SetMode(Tokens: new UInt32[] { 256265 }, Mode: Constants.MODE_LTP); 103 | 104 | // Example onTick handler 105 | private static void onTick(Tick TickData) 106 | { 107 | Console.WriteLine("LTP: " + TickData.LastPrice); 108 | } 109 | 110 | private static void OnOrderUpdate(Order OrderData) 111 | { 112 | Console.WriteLine("OrderUpdate " + Utils.JsonSerialize(OrderData)); 113 | } 114 | 115 | // Disconnect ticker before closing the application 116 | ticker.Close(); 117 | ``` 118 | 119 | For more details about different mode of quotes and subscribing for them, take a look at **KiteConnect Sample** project in this repository and [Kite Connect HTTP API documentation](https://kite.trade/docs/connect/v3). 120 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.3.0 2 | 3 | * Using HttpClient for HTTP requests. Fixes #36 and #39. 4 | * Using SHA256.HashData instead of SHA256Managed. Fixes #41. 5 | 6 | ## 4.2.1 7 | 8 | * Fixed Tick.Change value for MODE_FULL 9 | 10 | ## 4.2.0 11 | 12 | * New API to get Virtual contract notes 13 | 14 | ## 4.1.1 15 | 16 | * AuctionNumber param in PlaceOrder 17 | 18 | ## 4.1.0 19 | 20 | * .NET target is now `net6.0`. Previous target `netstandard2.0` has reached end-of-life as of Dec 2022. 21 | * Charges data in the `GetMargins` API. 22 | * New API to get Auctions data - `GetAuctionInstruments`. 23 | * New variety `VARIETY_AUCTION` supported in `PlaceOrder`. 24 | * New fields in `Holding` struct. 25 | 26 | ## 4.0.1 27 | 28 | * Updated login URL to https://kite.zerodha.com 29 | 30 | ## 4.0.0-pre 31 | 32 | * Changed data type of Volume, OI fields in Historical to UInt64 33 | 34 | ## 3.1.0 35 | 36 | * Added TTL validity for orders 37 | * Added support for Iceberg orders 38 | 39 | ## 3.0.9 40 | 41 | * Fix price conversion for BCD in ticker 42 | 43 | ## 3.0.8 44 | 45 | * Added basket margins API 46 | * Added response mode for both basket & order margins APIs 47 | * Better exception messages for DataExceptions 48 | 49 | ## 3.0.7 50 | 51 | * Added order margins API 52 | 53 | ## 3.0.6 54 | 55 | * Fixed an exception caused by missing `instrument_token` field in GTT response 56 | 57 | ## 3.0.5 58 | 59 | * .Net Standard migration 60 | * Culture invariant parsing of decimals 61 | * Changed GTTCondition.InstrumentToken type to UInt32 62 | * Changed GTTParams.InstrumentToken type to UInt32 63 | 64 | ## 3.0.4 65 | 66 | * Fixed parsing of doubles with scientific notations 67 | 68 | ## 3.0.3 69 | 70 | * Added Circuit limits to quote 71 | * Added Open Interest to Historical data 72 | 73 | ## 3.0.2 74 | 75 | * Added GTT support 76 | * Fixed issue in parsing quote data of index instruments 77 | 78 | **New APIs:** 79 | 80 | * GetGTTs 81 | * GetGTT 82 | * PlaceGTT 83 | * ModifyGTT 84 | * CancelGTT 85 | 86 | ## 3.0.1 87 | 88 | * Disabled sending mode updates if the given list of tokens is empty 89 | 90 | ## 3.0.0 91 | 92 | **New APIs:** 93 | 94 | * GetInstrumentsMargins 95 | * GetQuote 96 | * GetOHLC 97 | * GetLTP 98 | * GetHistoricalData with timestamps 99 | * GetProfile 100 | 101 | **Changes in Ticker:** 102 | 103 | * Use Access Token to authenticate instead of Public Token 104 | 105 | ```csharp 106 | Ticker ticker = new Ticker(MyAPIKey, MyUserId, MyPublicToken); 107 | ``` 108 | 109 | becomes, 110 | 111 | ```csharp 112 | Ticker ticker = new Ticker(MyAPIKey, MyUserId, MyAccessToken, Root: "wss://websocket.kite.trade/v3"); 113 | ``` 114 | 115 | * Ticker now streams order updates 116 | * New fields in Ticks 117 | 118 | **Changes in function names:** 119 | 120 | | Verion 2 | Version 3 | 121 | | :-------------: | :-------------------: | 122 | | SetSessionHook | SetSessionExpiryHook | 123 | | InvalidateToken | InvalidateAccessToken | 124 | | Margins | GetMargins | 125 | | GetOrder | GetOrderHistory | 126 | | GetTrades | GetOrderTrades | 127 | | ModifyProduct | ConvertPosition | 128 | | GetHistorical | GetHistoricalData | 129 | | GetMFOrder | GetMFOrders | 130 | | GetMFSIP | GetMFSIPs | 131 | 132 | **Changes in User structure:** 133 | 134 | | Verion 2 | Version 3 | 135 | | :-----------: | :--------: | 136 | | _ | APIKey | 137 | | PasswordReset | _ | 138 | | MemberId | _ | 139 | | OrderType | OrderTypes | 140 | | Exchange | Exchanges | 141 | | Product | Products | 142 | 143 | **Changes in Position structure:** 144 | 145 | | Verion 2 | Version 3 | 146 | | :--------------: | :-------------: | 147 | | _ | DayBuyQuantity | 148 | | _ | DayBuyPrice | 149 | | _ | DaySellQuantity | 150 | | _ | DaySellPrice | 151 | | NetBuyAmountM2M | _ | 152 | | NetSellAmountM2M | _ | 153 | | BuyM2M | BuyM2MValue | 154 | | SellM2M | SellM2MValue | 155 | 156 | **Changes in Quote structure:** 157 | 158 | | Verion 2 | Version 3 | 159 | | :-----------: | :-----------------: | 160 | | _ | InstrumentToken | 161 | | _ | Timestamp | 162 | | _ | AveragePrice | 163 | | _ | DayHighOpenInterest | 164 | | _ | DayLowOpenInterest | 165 | | ChangePercent | _ | 166 | | LastTime | LastTradeTime | 167 | 168 | 169 | **Changes in Tick structure:** 170 | 171 | | Verion 2 | Version 3 | 172 | | :------: | :-----------------: | 173 | | _ | LastTradeTime | 174 | | _ | OpenInterest | 175 | | _ | DayHighOpenInterest | 176 | | _ | DayLowOpenInterest | 177 | | _ | Timestamp | 178 | -------------------------------------------------------------------------------- /Documentation/docs/changelog.md: -------------------------------------------------------------------------------- 1 | ## 4.3.0 2 | 3 | * Using HttpClient for HTTP requests. Fixes #36 and #39. 4 | * Using SHA256.HashData instead of SHA256Managed. Fixes #41. 5 | 6 | ## 4.2.1 7 | 8 | * Fixed Tick.Change value for MODE_FULL 9 | 10 | ## 4.2.0 11 | 12 | * New API to get Virtual contract notes 13 | 14 | ## 4.1.1 15 | 16 | * AuctionNumber param in PlaceOrder 17 | 18 | ## 4.1.0 19 | 20 | * .NET target is now `net6.0`. Previous target `netstandard2.0` has reached end-of-life as of Dec 2022. 21 | * Charges data in the `GetMargins` API. 22 | * New API to get Auctions data - `GetAuctionInstruments`. 23 | * New variety `VARIETY_AUCTION` supported in `PlaceOrder`. 24 | * New fields in `Holding` struct. 25 | 26 | ## 4.0.1 27 | 28 | * Updated login URL to https://kite.zerodha.com 29 | 30 | ## 4.0.0-pre 31 | 32 | * Changed data type of Volume, OI fields in Historical to UInt64 33 | 34 | ## 3.1.0 35 | 36 | * Added TTL validity for orders 37 | * Added support for Iceberg orders 38 | 39 | ## 3.0.9 40 | 41 | * Fix price conversion for BCD in ticker 42 | 43 | ## 3.0.8 44 | 45 | * Added basket margins API 46 | * Added response mode for both basket & order margins APIs 47 | * Better exception messages for DataExceptions 48 | 49 | ## 3.0.7 50 | 51 | * Added order margins API 52 | 53 | ## 3.0.6 54 | 55 | * Fixed an exception caused by missing `instrument_token` field in GTT response 56 | 57 | ## 3.0.5 58 | 59 | * .Net Standard migration 60 | * Culture invariant parsing of decimals 61 | * Changed GTTCondition.InstrumentToken type to UInt32 62 | * Changed GTTParams.InstrumentToken type to UInt32 63 | 64 | ## 3.0.4 65 | 66 | * Fixed parsing of doubles with scientific notations 67 | 68 | ## 3.0.3 69 | 70 | * Added Circuit limits to quote 71 | * Added Open Interest to Historical data 72 | 73 | ## 3.0.2 74 | 75 | * Added GTT support 76 | * Fixed issue in parsing quote data of index instruments 77 | 78 | **New APIs:** 79 | 80 | * GetGTTs 81 | * GetGTT 82 | * PlaceGTT 83 | * ModifyGTT 84 | * CancelGTT 85 | 86 | ## 3.0.1 87 | 88 | * Disabled sending mode updates if the given list of tokens is empty 89 | 90 | ## 3.0.0 91 | 92 | **New APIs:** 93 | 94 | * GetInstrumentsMargins 95 | * GetQuote 96 | * GetOHLC 97 | * GetLTP 98 | * GetHistoricalData with timestamps 99 | * GetProfile 100 | 101 | **Changes in Ticker:** 102 | 103 | * Use Access Token to authenticate instead of Public Token 104 | 105 | ```csharp 106 | Ticker ticker = new Ticker(MyAPIKey, MyUserId, MyPublicToken); 107 | ``` 108 | 109 | becomes, 110 | 111 | ```csharp 112 | Ticker ticker = new Ticker(MyAPIKey, MyUserId, MyAccessToken, Root: "wss://websocket.kite.trade/v3"); 113 | ``` 114 | 115 | * Ticker now streams order updates 116 | * New fields in Ticks 117 | 118 | **Changes in function names:** 119 | 120 | | Verion 2 | Version 3 | 121 | | :-------------: | :-------------------: | 122 | | SetSessionHook | SetSessionExpiryHook | 123 | | InvalidateToken | InvalidateAccessToken | 124 | | Margins | GetMargins | 125 | | GetOrder | GetOrderHistory | 126 | | GetTrades | GetOrderTrades | 127 | | ModifyProduct | ConvertPosition | 128 | | GetHistorical | GetHistoricalData | 129 | | GetMFOrder | GetMFOrders | 130 | | GetMFSIP | GetMFSIPs | 131 | 132 | **Changes in User structure:** 133 | 134 | | Verion 2 | Version 3 | 135 | | :-----------: | :--------: | 136 | | _ | APIKey | 137 | | PasswordReset | _ | 138 | | MemberId | _ | 139 | | OrderType | OrderTypes | 140 | | Exchange | Exchanges | 141 | | Product | Products | 142 | 143 | **Changes in Position structure:** 144 | 145 | | Verion 2 | Version 3 | 146 | | :--------------: | :-------------: | 147 | | _ | DayBuyQuantity | 148 | | _ | DayBuyPrice | 149 | | _ | DaySellQuantity | 150 | | _ | DaySellPrice | 151 | | NetBuyAmountM2M | _ | 152 | | NetSellAmountM2M | _ | 153 | | BuyM2M | BuyM2MValue | 154 | | SellM2M | SellM2MValue | 155 | 156 | **Changes in Quote structure:** 157 | 158 | | Verion 2 | Version 3 | 159 | | :-----------: | :-----------------: | 160 | | _ | InstrumentToken | 161 | | _ | Timestamp | 162 | | _ | AveragePrice | 163 | | _ | DayHighOpenInterest | 164 | | _ | DayLowOpenInterest | 165 | | ChangePercent | _ | 166 | | LastTime | LastTradeTime | 167 | 168 | 169 | **Changes in Tick structure:** 170 | 171 | | Verion 2 | Version 3 | 172 | | :------: | :-----------------: | 173 | | _ | LastTradeTime | 174 | | _ | OpenInterest | 175 | | _ | DayHighOpenInterest | 176 | | _ | DayLowOpenInterest | 177 | | _ | Timestamp | 178 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/orders.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": [ 4 | { 5 | "placed_by": "XXXXXX", 6 | "order_id": "100000000000000", 7 | "exchange_order_id": "200000000000000", 8 | "parent_order_id": null, 9 | "status": "CANCELLED", 10 | "status_message": null, 11 | "status_message_raw": null, 12 | "order_timestamp": "2021-05-31 09:18:57", 13 | "exchange_update_timestamp": "2021-05-31 09:18:58", 14 | "exchange_timestamp": "2021-05-31 09:15:38", 15 | "variety": "regular", 16 | "exchange": "CDS", 17 | "tradingsymbol": "USDINR21JUNFUT", 18 | "instrument_token": 412675, 19 | "order_type": "LIMIT", 20 | "transaction_type": "BUY", 21 | "validity": "DAY", 22 | "product": "NRML", 23 | "quantity": 1, 24 | "disclosed_quantity": 0, 25 | "price": 72, 26 | "trigger_price": 0, 27 | "average_price": 0, 28 | "filled_quantity": 0, 29 | "pending_quantity": 1, 30 | "cancelled_quantity": 1, 31 | "market_protection": 0, 32 | "meta": {}, 33 | "tag": null, 34 | "guid": "XXXXX", 35 | "auction_number": 10 36 | }, 37 | { 38 | "placed_by": "XXXXXX", 39 | "order_id": "700000000000000", 40 | "exchange_order_id": "800000000000000", 41 | "parent_order_id": null, 42 | "status": "COMPLETE", 43 | "status_message": null, 44 | "status_message_raw": null, 45 | "order_timestamp": "2021-05-31 16:00:36", 46 | "exchange_update_timestamp": "2021-05-31 16:00:36", 47 | "exchange_timestamp": "2021-05-31 16:00:36", 48 | "variety": "regular", 49 | "exchange": "MCX", 50 | "tradingsymbol": "GOLDPETAL21JUNFUT", 51 | "instrument_token": 58424839, 52 | "order_type": "LIMIT", 53 | "transaction_type": "BUY", 54 | "validity": "DAY", 55 | "product": "NRML", 56 | "quantity": 1, 57 | "disclosed_quantity": 0, 58 | "price": 4854, 59 | "trigger_price": 0, 60 | "average_price": 4852, 61 | "filled_quantity": 1, 62 | "pending_quantity": 0, 63 | "cancelled_quantity": 0, 64 | "market_protection": 0, 65 | "meta": {}, 66 | "tag": "connect test order1", 67 | "tags": [ 68 | "connect test order1" 69 | ], 70 | "guid": "XXXXXXX" 71 | }, 72 | { 73 | "placed_by": "XXXXXX", 74 | "order_id": "9000000000000000", 75 | "exchange_order_id": "1000000000000000", 76 | "parent_order_id": null, 77 | "status": "COMPLETE", 78 | "status_message": null, 79 | "status_message_raw": null, 80 | "order_timestamp": "2021-05-31 16:08:40", 81 | "exchange_update_timestamp": "2021-05-31 16:08:41", 82 | "exchange_timestamp": "2021-05-31 16:08:41", 83 | "variety": "regular", 84 | "exchange": "MCX", 85 | "tradingsymbol": "GOLDPETAL21JUNFUT", 86 | "instrument_token": 58424839, 87 | "order_type": "LIMIT", 88 | "transaction_type": "BUY", 89 | "validity": "DAY", 90 | "product": "NRML", 91 | "quantity": 1, 92 | "disclosed_quantity": 0, 93 | "price": 4854, 94 | "trigger_price": 0, 95 | "average_price": 4852, 96 | "filled_quantity": 1, 97 | "pending_quantity": 0, 98 | "cancelled_quantity": 0, 99 | "market_protection": 0, 100 | "meta": {}, 101 | "tag": "connect test order2", 102 | "tags": [ 103 | "connect test order2", 104 | "XXXXX" 105 | ], 106 | "guid": "XXXXXX" 107 | }, 108 | { 109 | "placed_by": "XXXXXX", 110 | "order_id": "220524001859672", 111 | "exchange_order_id": null, 112 | "parent_order_id": null, 113 | "status": "REJECTED", 114 | "status_message": "Insufficient funds. Required margin is 95417.84 but available margin is 74251.80. Check the orderbook for open orders.", 115 | "status_message_raw": "RMS:Margin Exceeds,Required:95417.84, Available:74251.80 for entity account-XXXXX across exchange across segment across product ", 116 | "order_timestamp": "2022-05-24 12:26:52", 117 | "exchange_update_timestamp": null, 118 | "exchange_timestamp": null, 119 | "variety": "iceberg", 120 | "modified": false, 121 | "exchange": "NSE", 122 | "tradingsymbol": "SBIN", 123 | "instrument_token": 779521, 124 | "order_type": "LIMIT", 125 | "transaction_type": "BUY", 126 | "validity": "TTL", 127 | "validity_ttl": 2, 128 | "product": "CNC", 129 | "quantity": 200, 130 | "disclosed_quantity": 0, 131 | "price": 463, 132 | "trigger_price": 0, 133 | "average_price": 0, 134 | "filled_quantity": 0, 135 | "pending_quantity": 0, 136 | "cancelled_quantity": 0, 137 | "market_protection": 0, 138 | "meta": { 139 | "iceberg": { 140 | "leg": 1, 141 | "legs": 5, 142 | "leg_quantity": 200, 143 | "total_quantity": 1000, 144 | "remaining_quantity": 800 145 | } 146 | }, 147 | "tag": "icebergord", 148 | "tags": [ 149 | "icebergord" 150 | ], 151 | "guid": "XXXXXX" 152 | } 153 | ] 154 | } -------------------------------------------------------------------------------- /Documentation/docs/index.md: -------------------------------------------------------------------------------- 1 | # Kite Connect .Net library 2 | The official .Net client for communicating with [Kite Connect API](https://kite.trade). 3 | 4 | Kite Connect is a set of REST-like APIs that expose many capabilities required to build a complete investment and trading platform. Execute orders in real time, manage user portfolio, stream live market data (WebSockets), and more, with the simple HTTP API collection. 5 | 6 | [Zerodha Technology Pvt. Ltd.](http://zerodha.com) © 2019. Licensed under the [MIT License](/license/). 7 | 8 | ## Requirements 9 | 10 | **.Net Framework**: 4.5 11 | 12 | **Visual Studio**: Visual Studio 2012 and onwards 13 | 14 | **Windows**: Limited support on Windows 7. Full support on Windows 8 and onwards. 15 | 16 | *Note: Ticker will not work in Windows 7 due to absense of support for WebSockets in .Net framework.* 17 | 18 | ## Documentation 19 | 20 | * [.Net Library](https://kite.trade/docs/kiteconnectdotnet/) 21 | * [HTTP API](https://kite.trade/docs/connect/) 22 | 23 | ## Install Client Library 24 | 25 | 26 | ### Using NuGet 27 | 28 | Execute in **Tools** » **NuGet Package Manager** » **Package Manager Console** 29 | 30 | ``` 31 | Install-Package Tech.Zerodha.KiteConnect 32 | ``` 33 | ### Using .Net CLI 34 | 35 | ``` 36 | dotnet add package Tech.Zerodha.KiteConnect 37 | ``` 38 | 39 | ### Manual Install 40 | 41 | - Download DLL from [releases](https://github.com/zerodhatech/dotnetkiteconnect/releases) 42 | - Right click on your project » **Add** » **Reference** » Click **Browse** » Select **KiteConnect.dll** 43 | 44 | ## Getting started 45 | ```csharp 46 | // Import library 47 | using KiteConnect; 48 | 49 | // Initialize Kiteconnect using apiKey. Enabling Debug will give logs of requests and responses 50 | Kite kite = new Kite(MyAPIKey, Debug: true); 51 | 52 | // Collect login url to authenticate user. Load this URL in browser or WebView. 53 | // After successful authentication this will redirect to your redirect url with request token. 54 | kite.GetLoginURL(); 55 | 56 | // Collect tokens and user details using the request token 57 | User user = kite.GenerateSession(RequestToken, MySecret); 58 | 59 | // Persist these tokens in database or settings 60 | string MyAccessToken = user.AccessToken; 61 | string MyPublicToken = user.PublicToken; 62 | 63 | // Initialize Kite APIs with access token 64 | kite.SetAccessToken(MyAccessToken); 65 | 66 | // Set session expiry callback. Method can be separate function also. 67 | kite.SetSessionExpiryHook(() => Console.WriteLine("Need to login again")); 68 | 69 | // Example call for functions like "PlaceOrder" that returns Dictionary 70 | Dictionary response = kite.PlaceOrder( 71 | Exchange: Constants.EXCHANGE_CDS, 72 | TradingSymbol: "USDINR17AUGFUT", 73 | TransactionType: Constants.TRANSACTION_TYPE_SELL, 74 | Quantity: 1, 75 | Price: 64.0000m, 76 | OrderType: Constants.ORDER_TYPE_MARKET, 77 | Product: Constants.PRODUCT_MIS 78 | ); 79 | Console.WriteLine("Order Id: " + response["data"]["order_id"]); 80 | 81 | // Example call for functions like "GetHoldings" that returns a data structure 82 | List holdings = kite.GetHoldings(); 83 | Console.WriteLine(holdings[0].AveragePrice); 84 | 85 | ``` 86 | For more examples, take a look at [Program.cs](https://github.com/zerodhatech/dotnetkiteconnect/blob/kite3/KiteConnectSample/Program.cs) of **KiteConnect Sample** project in this repository. 87 | 88 | ## WebSocket live streaming data 89 | 90 | This library uses Events to get ticks. These events are non blocking and can be used without additional threads. Create event handlers and attach it to Ticker instance as shown in the example below. 91 | 92 | ```csharp 93 | /* 94 | To get live price use KiteTicker websocket connection. 95 | It is recommended to use only one websocket connection at any point of time and make sure you stop connection, 96 | once user goes out of app. 97 | */ 98 | 99 | // Create a new Ticker instance 100 | Ticker ticker = new Ticker(MyAPIKey, MyAccessToken); 101 | 102 | // Add handlers to events 103 | ticker.OnTick += onTick; 104 | ticker.OnOrderUpdate += OnOrderUpdate; 105 | ticker.OnReconnect += onReconnect; 106 | ticker.OnNoReconnect += oNoReconnect; 107 | ticker.OnError += onError; 108 | ticker.OnClose += onClose; 109 | ticker.OnConnect += onConnect; 110 | 111 | // Engage reconnection mechanism and connect to ticker 112 | ticker.EnableReconnect(Interval: 5,Retries: 50); 113 | ticker.Connect(); 114 | 115 | // Subscribing to NIFTY50 and setting mode to LTP 116 | ticker.Subscribe(Tokens: new UInt32[] { 256265 }); 117 | ticker.SetMode(Tokens: new UInt32[] { 256265 }, Mode: Constants.MODE_LTP); 118 | 119 | // Example onTick handler 120 | private static void onTick(Tick TickData) 121 | { 122 | Console.WriteLine("LTP: " + TickData.LastPrice); 123 | } 124 | 125 | private static void OnOrderUpdate(Order OrderData) 126 | { 127 | Console.WriteLine("OrderUpdate " + Utils.JsonSerialize(OrderData)); 128 | } 129 | 130 | // Disconnect ticker before closing the application 131 | ticker.Close(); 132 | ``` 133 | 134 | For more details about different mode of quotes and subscribing for them, take a look at **KiteConnect Sample** project in this repository and [Kite Connect HTTP API documentation](https://kite.trade/docs/connect/v3). 135 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/positions.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "success", 3 | "data": { 4 | "net": [ 5 | { 6 | "tradingsymbol": "LEADMINI17DECFUT", 7 | "exchange": "MCX", 8 | "instrument_token": 53496327, 9 | "product": "NRML", 10 | "quantity": 1, 11 | "overnight_quantity": 0, 12 | "multiplier": 1000, 13 | "average_price": 161.05, 14 | "close_price": 0, 15 | "last_price": 161.05, 16 | "value": -161050, 17 | "pnl": 0, 18 | "m2m": 0, 19 | "unrealised": 0, 20 | "realised": 0, 21 | "buy_quantity": 1, 22 | "buy_price": 161.05, 23 | "buy_value": 161050, 24 | "buy_m2m": 161050, 25 | "sell_quantity": 0, 26 | "sell_price": 0, 27 | "sell_value": 0, 28 | "sell_m2m": 0, 29 | "day_buy_quantity": 1, 30 | "day_buy_price": 161.05, 31 | "day_buy_value": 161050, 32 | "day_sell_quantity": 0, 33 | "day_sell_price": 0, 34 | "day_sell_value": 0 35 | }, 36 | { 37 | "tradingsymbol": "GOLDGUINEA17DECFUT", 38 | "exchange": "MCX", 39 | "instrument_token": 53505799, 40 | "product": "NRML", 41 | "quantity": 0, 42 | "overnight_quantity": 3, 43 | "multiplier": 1, 44 | "average_price": 0, 45 | "close_price": 23232, 46 | "last_price": 23355, 47 | "value": 801, 48 | "pnl": 801, 49 | "m2m": 276, 50 | "unrealised": 801, 51 | "realised": 0, 52 | "buy_quantity": 4, 53 | "buy_price": 23139.75, 54 | "buy_value": 92559, 55 | "buy_m2m": 93084, 56 | "sell_quantity": 4, 57 | "sell_price": 23340, 58 | "sell_value": 93360, 59 | "sell_m2m": 93360, 60 | "day_buy_quantity": 1, 61 | "day_buy_price": 23388, 62 | "day_buy_value": 23388, 63 | "day_sell_quantity": 4, 64 | "day_sell_price": 23340, 65 | "day_sell_value": 93360 66 | }, 67 | { 68 | "tradingsymbol": "SBIN", 69 | "exchange": "NSE", 70 | "instrument_token": 779521, 71 | "product": "CO", 72 | "quantity": 0, 73 | "overnight_quantity": 0, 74 | "multiplier": 1, 75 | "average_price": 0, 76 | "close_price": 0, 77 | "last_price": 308.4, 78 | "value": -2, 79 | "pnl": -2, 80 | "m2m": -2, 81 | "unrealised": -2, 82 | "realised": 0, 83 | "buy_quantity": 1, 84 | "buy_price": 311, 85 | "buy_value": 311, 86 | "buy_m2m": 311, 87 | "sell_quantity": 1, 88 | "sell_price": 309, 89 | "sell_value": 309, 90 | "sell_m2m": 309, 91 | "day_buy_quantity": 1, 92 | "day_buy_price": 311, 93 | "day_buy_value": 311, 94 | "day_sell_quantity": 1, 95 | "day_sell_price": 309, 96 | "day_sell_value": 309 97 | } 98 | ], 99 | "day": [ 100 | { 101 | "tradingsymbol": "GOLDGUINEA17DECFUT", 102 | "exchange": "MCX", 103 | "instrument_token": 53505799, 104 | "product": "NRML", 105 | "quantity": -3, 106 | "overnight_quantity": 0, 107 | "multiplier": 1, 108 | "average_price": 23340, 109 | "close_price": 23232, 110 | "last_price": 23355, 111 | "value": 69972, 112 | "pnl": -93, 113 | "m2m": -93, 114 | "unrealised": -93, 115 | "realised": 0, 116 | "buy_quantity": 1, 117 | "buy_price": 23388, 118 | "buy_value": 23388, 119 | "buy_m2m": 23388, 120 | "sell_quantity": 4, 121 | "sell_price": 23340, 122 | "sell_value": 93360, 123 | "sell_m2m": 93360, 124 | "day_buy_quantity": 1, 125 | "day_buy_price": 23388, 126 | "day_buy_value": 23388, 127 | "day_sell_quantity": 4, 128 | "day_sell_price": 23340, 129 | "day_sell_value": 93360 130 | }, 131 | { 132 | "tradingsymbol": "LEADMINI17DECFUT", 133 | "exchange": "MCX", 134 | "instrument_token": 53496327, 135 | "product": "NRML", 136 | "quantity": 1, 137 | "overnight_quantity": 0, 138 | "multiplier": 1000, 139 | "average_price": 161.05, 140 | "close_price": 0, 141 | "last_price": 161.05, 142 | "value": -161050, 143 | "pnl": 0, 144 | "m2m": 0, 145 | "unrealised": 0, 146 | "realised": 0, 147 | "buy_quantity": 1, 148 | "buy_price": 161.05, 149 | "buy_value": 161050, 150 | "buy_m2m": 161050, 151 | "sell_quantity": 0, 152 | "sell_price": 0, 153 | "sell_value": 0, 154 | "sell_m2m": 0, 155 | "day_buy_quantity": 1, 156 | "day_buy_price": 161.05, 157 | "day_buy_value": 161050, 158 | "day_sell_quantity": 0, 159 | "day_sell_price": 0, 160 | "day_sell_value": 0 161 | }, 162 | { 163 | "tradingsymbol": "SBIN", 164 | "exchange": "NSE", 165 | "instrument_token": 779521, 166 | "product": "CO", 167 | "quantity": 0, 168 | "overnight_quantity": 0, 169 | "multiplier": 1, 170 | "average_price": 0, 171 | "close_price": 0, 172 | "last_price": 308.4, 173 | "value": -2, 174 | "pnl": -2, 175 | "m2m": -2, 176 | "unrealised": -2, 177 | "realised": 0, 178 | "buy_quantity": 1, 179 | "buy_price": 311, 180 | "buy_value": 311, 181 | "buy_m2m": 311, 182 | "sell_quantity": 1, 183 | "sell_price": 309, 184 | "sell_value": 309, 185 | "sell_m2m": 309, 186 | "day_buy_quantity": 1, 187 | "day_buy_price": 311, 188 | "day_buy_value": 311, 189 | "day_sell_quantity": 1, 190 | "day_sell_price": 309, 191 | "day_sell_value": 309 192 | } 193 | ] 194 | } 195 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | Documentation/site 7 | KiteConnectTester/ 8 | 9 | # User-specific files 10 | *.suo 11 | *.user 12 | *.userosscache 13 | *.sln.docstates 14 | 15 | # User-specific files (MonoDevelop/Xamarin Studio) 16 | *.userprefs 17 | 18 | # Build results 19 | [Dd]ebug/ 20 | [Dd]ebugPublic/ 21 | [Rr]elease/ 22 | [Rr]eleases/ 23 | x64/ 24 | x86/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | *_i.c 58 | *_p.c 59 | *_i.h 60 | *.ilk 61 | *.meta 62 | *.obj 63 | *.pch 64 | *.pdb 65 | *.pgc 66 | *.pgd 67 | *.rsp 68 | *.sbr 69 | *.tlb 70 | *.tli 71 | *.tlh 72 | *.tmp 73 | *.tmp_proj 74 | *.log 75 | *.vspscc 76 | *.vssscc 77 | .builds 78 | *.pidb 79 | *.svclog 80 | *.scc 81 | 82 | # Chutzpah Test files 83 | _Chutzpah* 84 | 85 | # Visual C++ cache files 86 | ipch/ 87 | *.aps 88 | *.ncb 89 | *.opendb 90 | *.opensdf 91 | *.sdf 92 | *.cachefile 93 | *.VC.db 94 | *.VC.VC.opendb 95 | 96 | # Visual Studio profiler 97 | *.psess 98 | *.vsp 99 | *.vspx 100 | *.sap 101 | 102 | # TFS 2012 Local Workspace 103 | $tf/ 104 | 105 | # Guidance Automation Toolkit 106 | *.gpState 107 | 108 | # ReSharper is a .NET coding add-in 109 | _ReSharper*/ 110 | *.[Rr]e[Ss]harper 111 | *.DotSettings.user 112 | 113 | # JustCode is a .NET coding add-in 114 | .JustCode 115 | 116 | # TeamCity is a build add-in 117 | _TeamCity* 118 | 119 | # DotCover is a Code Coverage Tool 120 | *.dotCover 121 | 122 | # Visual Studio code coverage results 123 | *.coverage 124 | *.coveragexml 125 | 126 | # NCrunch 127 | _NCrunch_* 128 | .*crunch*.local.xml 129 | nCrunchTemp_* 130 | 131 | # MightyMoose 132 | *.mm.* 133 | AutoTest.Net/ 134 | 135 | # Web workbench (sass) 136 | .sass-cache/ 137 | 138 | # Installshield output folder 139 | [Ee]xpress/ 140 | 141 | # DocProject is a documentation generator add-in 142 | DocProject/buildhelp/ 143 | DocProject/Help/*.HxT 144 | DocProject/Help/*.HxC 145 | DocProject/Help/*.hhc 146 | DocProject/Help/*.hhk 147 | DocProject/Help/*.hhp 148 | DocProject/Help/Html2 149 | DocProject/Help/html 150 | 151 | # Click-Once directory 152 | publish/ 153 | 154 | # Publish Web Output 155 | *.[Pp]ublish.xml 156 | *.azurePubxml 157 | # Note: Comment the next line if you want to checkin your web deploy settings, 158 | # but database connection strings (with potential passwords) will be unencrypted 159 | *.pubxml 160 | *.publishproj 161 | 162 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 163 | # checkin your Azure Web App publish settings, but sensitive information contained 164 | # in these scripts will be unencrypted 165 | PublishScripts/ 166 | 167 | # NuGet Packages 168 | *.nupkg 169 | # The packages folder can be ignored because of Package Restore 170 | **/packages/* 171 | # except build/, which is used as an MSBuild target. 172 | !**/packages/build/ 173 | # Uncomment if necessary however generally it will be regenerated when needed 174 | #!**/packages/repositories.config 175 | # NuGet v3's project.json files produces more ignorable files 176 | *.nuget.props 177 | *.nuget.targets 178 | 179 | # Microsoft Azure Build Output 180 | csx/ 181 | *.build.csdef 182 | 183 | # Microsoft Azure Emulator 184 | ecf/ 185 | rcf/ 186 | 187 | # Windows Store app package directories and files 188 | AppPackages/ 189 | BundleArtifacts/ 190 | Package.StoreAssociation.xml 191 | _pkginfo.txt 192 | *.appx 193 | 194 | # Visual Studio cache files 195 | # files ending in .cache can be ignored 196 | *.[Cc]ache 197 | # but keep track of directories ending in .cache 198 | !*.[Cc]ache/ 199 | 200 | # Others 201 | ClientBin/ 202 | ~$* 203 | *~ 204 | *.dbmdl 205 | *.dbproj.schemaview 206 | *.jfm 207 | *.pfx 208 | *.publishsettings 209 | orleans.codegen.cs 210 | 211 | # Since there are multiple workflows, uncomment next line to ignore bower_components 212 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 213 | #bower_components/ 214 | 215 | # RIA/Silverlight projects 216 | Generated_Code/ 217 | 218 | # Backup & report files from converting an old project file 219 | # to a newer Visual Studio version. Backup files are not needed, 220 | # because we have git ;-) 221 | _UpgradeReport_Files/ 222 | Backup*/ 223 | UpgradeLog*.XML 224 | UpgradeLog*.htm 225 | 226 | # SQL Server files 227 | *.mdf 228 | *.ldf 229 | *.ndf 230 | 231 | # Business Intelligence projects 232 | *.rdl.data 233 | *.bim.layout 234 | *.bim_*.settings 235 | 236 | # Microsoft Fakes 237 | FakesAssemblies/ 238 | 239 | # GhostDoc plugin setting file 240 | *.GhostDoc.xml 241 | 242 | # Node.js Tools for Visual Studio 243 | .ntvs_analysis.dat 244 | node_modules/ 245 | 246 | # Typescript v1 declaration files 247 | typings/ 248 | 249 | # Visual Studio 6 build log 250 | *.plg 251 | 252 | # Visual Studio 6 workspace options file 253 | *.opt 254 | 255 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 256 | *.vbw 257 | 258 | # Visual Studio LightSwitch build output 259 | **/*.HTMLClient/GeneratedArtifacts 260 | **/*.DesktopClient/GeneratedArtifacts 261 | **/*.DesktopClient/ModelManifest.xml 262 | **/*.Server/GeneratedArtifacts 263 | **/*.Server/ModelManifest.xml 264 | _Pvt_Extensions 265 | 266 | # Paket dependency manager 267 | .paket/paket.exe 268 | paket-files/ 269 | 270 | # FAKE - F# Make 271 | .fake/ 272 | 273 | # JetBrains Rider 274 | .idea/ 275 | *.sln.iml 276 | 277 | # CodeRush 278 | .cr/ 279 | 280 | # Python Tools for Visual Studio (PTVS) 281 | __pycache__/ 282 | *.pyc 283 | 284 | # Cake - Uncomment if you are using it 285 | # tools/** 286 | # !tools/packages.config 287 | 288 | # Tabs Studio 289 | *.tss 290 | 291 | # Telerik's JustMock configuration file 292 | *.jmconfig 293 | 294 | # BizTalk build output 295 | *.btp.cs 296 | *.btm.cs 297 | *.odx.cs 298 | *.xsd.cs 299 | -------------------------------------------------------------------------------- /KiteConnect/WebSocket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net.WebSockets; 7 | using System.Threading; 8 | using System.Net; 9 | 10 | namespace KiteConnect 11 | { 12 | // Delegates for events 13 | public delegate void OnConnectHandler(); 14 | public delegate void OnCloseHandler(); 15 | public delegate void OnErrorHandler(string Message); 16 | public delegate void OnDataHandler(byte[] Data, int Count, string MessageType); 17 | 18 | /// 19 | /// A wrapper for .Net's ClientWebSocket with callbacks 20 | /// 21 | internal class WebSocket : IWebSocket 22 | { 23 | // Instance of built in ClientWebSocket 24 | ClientWebSocket _ws; 25 | string _url; 26 | int _bufferLength; // Length of buffer to keep binary chunk 27 | 28 | // Events that can be subscribed 29 | public event OnConnectHandler OnConnect; 30 | public event OnCloseHandler OnClose; 31 | public event OnDataHandler OnData; 32 | public event OnErrorHandler OnError; 33 | 34 | /// 35 | /// Initialize WebSocket class 36 | /// 37 | /// Size of buffer to keep byte stream chunk. 38 | public WebSocket(int BufferLength = 2000000) 39 | { 40 | _bufferLength = BufferLength; 41 | } 42 | 43 | /// 44 | /// Check if WebSocket is connected or not 45 | /// 46 | /// True if connection is live 47 | public bool IsConnected() 48 | { 49 | if(_ws is null) 50 | return false; 51 | 52 | return _ws.State == WebSocketState.Open; 53 | } 54 | 55 | /// 56 | /// Connect to WebSocket 57 | /// 58 | public void Connect(string Url, Dictionary headers = null) 59 | { 60 | _url = Url; 61 | try 62 | { 63 | // Initialize ClientWebSocket instance and connect with Url 64 | _ws = new ClientWebSocket(); 65 | if(headers != null) 66 | { 67 | foreach(string key in headers.Keys) 68 | { 69 | _ws.Options.SetRequestHeader(key, headers[key]); 70 | } 71 | } 72 | _ws.ConnectAsync(new Uri(_url), CancellationToken.None).Wait(); 73 | } 74 | catch (AggregateException e) 75 | { 76 | foreach (string ie in e.InnerException.Messages()) 77 | { 78 | OnError?.Invoke("Error while connecting. Message: " + ie); 79 | if(ie.Contains("Forbidden") && ie.Contains("403")) 80 | { 81 | OnClose?.Invoke(); 82 | } 83 | } 84 | return; 85 | } 86 | catch (Exception e) 87 | { 88 | OnError?.Invoke("Error while connecting. Message: " + e.Message); 89 | return; 90 | } 91 | OnConnect?.Invoke(); 92 | 93 | byte[] buffer = new byte[_bufferLength]; 94 | Action> callback = null; 95 | 96 | try 97 | { 98 | //Callback for receiving data 99 | callback = t => 100 | { 101 | try 102 | { 103 | byte[] tempBuff = new byte[_bufferLength]; 104 | int offset = t.Result.Count; 105 | bool endOfMessage = t.Result.EndOfMessage; 106 | // if chunk has even more data yet to recieve do that synchronously 107 | while (!endOfMessage) 108 | { 109 | WebSocketReceiveResult result = _ws.ReceiveAsync(new ArraySegment(tempBuff), CancellationToken.None).Result; 110 | Array.Copy(tempBuff, 0, buffer, offset, result.Count); 111 | offset += result.Count; 112 | endOfMessage = result.EndOfMessage; 113 | } 114 | // send data to process 115 | OnData?.Invoke(buffer, offset, t.Result.MessageType.ToString()); 116 | // Again try to receive data 117 | _ws.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None).ContinueWith(callback); 118 | }catch(Exception e) 119 | { 120 | if(IsConnected()) 121 | OnError?.Invoke("Error while recieving data. Message: " + e.Message); 122 | else 123 | OnError?.Invoke("Lost ticker connection."); 124 | } 125 | }; 126 | 127 | // To start the receive loop in the beginning 128 | _ws.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None).ContinueWith(callback); 129 | } 130 | catch (Exception e) 131 | { 132 | OnError?.Invoke("Error while recieving data. Message: " + e.Message); 133 | } 134 | } 135 | 136 | /// 137 | /// Send message to socket connection 138 | /// 139 | /// Message to send 140 | public void Send(string Message) 141 | { 142 | if (_ws.State == WebSocketState.Open) 143 | try 144 | { 145 | _ws.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(Message)), WebSocketMessageType.Text, true, CancellationToken.None).Wait(); 146 | } 147 | catch (Exception e) 148 | { 149 | OnError?.Invoke("Error while sending data. Message: " + e.Message); 150 | } 151 | } 152 | 153 | /// 154 | /// Close the WebSocket connection 155 | /// 156 | /// If true WebSocket will not send 'Close' signal to server. Used when connection is disconnected due to netork issues. 157 | public void Close(bool Abort = false) 158 | { 159 | if(_ws.State == WebSocketState.Open) 160 | { 161 | try 162 | { 163 | if (Abort) 164 | _ws.Abort(); 165 | else 166 | { 167 | _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None).Wait(); 168 | OnClose?.Invoke(); 169 | } 170 | } 171 | catch (Exception e) 172 | { 173 | OnError?.Invoke("Error while closing connection. Message: " + e.Message); 174 | } 175 | } 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/instruments_nse.csv: -------------------------------------------------------------------------------- 1 | instrument_token,exchange_token,tradingsymbol,name,last_price,expiry,strike,tick_size,lot_size,instrument_type,segment,exchange 2 | 3813889,14898,CENTRALBK-BE,CENTRAL BANK OF INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 3 | 4645121,18145,EMMBI-BL,EMMBI INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 4 | 4531969,17703,MIDCAPIWIN-BL,ICICI PRU MIDCAP IWIN ETF,0.0,,0.0,0.01,1,EQ,NSE,NSE 5 | 5533953,21617,ABCAPITAL-BL,ADITYA BIRLA CAPITAL,0.0,,0.0,0.05,1,EQ,NSE,NSE 6 | 3861249,15083,ADANIPORTS,ADANI PORT & SEZ,0.0,,0.0,0.05,1,EQ,NSE,NSE 7 | 4419329,17263,ARMANFIN,ARMAN FIN SERV,0.0,,0.0,0.05,1,EQ,NSE,NSE 8 | 3713281,14505,BALAMINES-BE,BALAJI AMINES,0.0,,0.0,0.05,1,EQ,NSE,NSE 9 | 1373441,5365,BATAINDIA-BE,BATA INDIA DEP RS,0.0,,0.0,0.05,1,EQ,NSE,NSE 10 | 5421569,21178,CDSL-BE,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 11 | 5421313,21177,CDSL-BL,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 12 | 1374209,5368,CHENNPETRO-BE,CHENNAI PETRO CORP DE,0.0,,0.0,0.05,1,EQ,NSE,NSE 13 | 3419393,13357,GANGOTRI,GANGOTRI TEXTILES,0.0,,0.0,0.05,1,EQ,NSE,NSE 14 | 2703361,10560,NAVKARCORP-BL,NAVKAR CORPORATION,0.0,,0.0,0.05,1,EQ,NSE,NSE 15 | 5001473,19537,PDPL,PARENTERAL DRUGS,0.0,,0.0,0.05,1,EQ,NSE,NSE 16 | 5420545,21174,CDSL,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 17 | 3370497,13166,CELEBRITY-BL,CELEBRITY FASHIONS,0.0,,0.0,0.05,1,EQ,NSE,NSE 18 | 3146497,12291,CENTEXT-BL,CENTURY EXTRUSIONS,0.0,,0.0,0.05,1,EQ,NSE,NSE 19 | 4550145,17774,GROBTEA-BE,THE GROB TEA COMPANY,0.0,,0.0,0.05,1,EQ,NSE,NSE 20 | 6938881,27105,CHROMATIC-BE,CHROMATIC INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 21 | 4578305,17884,DBCORP-BL,D.B.CORP,0.0,,0.0,0.05,1,EQ,NSE,NSE 22 | 3155457,12326,DCW-BL,DCW,0.0,,0.0,0.05,1,EQ,NSE,NSE 23 | 5101569,19928,HUDCO-N8,7.64% TAX FREETRI SR2B,0.0,,0.0,0.01,1,EQ,NSE,NSE 24 | 1707521,6670,INFARINDIA,INFAR (INDIA),0.0,,0.0,0.05,1,EQ,NSE,NSE 25 | 1219329,4763,BANKBARODA-BE,BOB - DEPO SETT,0.0,,0.0,0.05,1,EQ,NSE,NSE 26 | 2928385,11439,BANKBEES,RELIANCE ETF BANK BEES,0.0,,0.0,0.01,1,EQ,NSE,NSE 27 | 3715841,14515,BANSWRAS-BE,BANSWARA SYNTEX,0.0,,0.0,0.05,1,EQ,NSE,NSE 28 | 3137281,12255,BERGEPAINT-BL,BERGER PAINTS (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 29 | 3901185,15239,BIRLAMONEY,ADITYA BIRLA MONEY,0.0,,0.0,0.05,1,EQ,NSE,NSE 30 | 1789185,6989,CARRIERAIR-BE,CARRIER AIRCON DEPO,0.0,,0.0,0.05,1,EQ,NSE,NSE 31 | 3123713,12202,CASTEXTECH-BL,CASTEX TECHNOLOGIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 32 | 5534209,21618,ABCAPITAL-BE,ADITYA BIRLA CAPITAL,0.0,,0.0,0.05,1,EQ,NSE,NSE 33 | 3412225,13329,ERAINFRA-BL,ERA INFRA ENGINEERING,0.0,,0.0,0.05,1,EQ,NSE,NSE 34 | 1884161,7360,SETFNN50-BL,SBI-ETF NIFTY NEXT 50,0.0,,0.0,0.01,1,EQ,NSE,NSE 35 | 3028225,11829,SSWL,STEEL STRIPS WHEELS,0.0,,0.0,0.05,1,EQ,NSE,NSE 36 | 6128129,23938,ESSARPORTS-BE,ESSAR PORTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 37 | 4671233,18247,DEEPIND-BL,DEEP INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 38 | 6562305,25634,ESSARSHPNG,ESSAR SHIPPING,0.0,,0.0,0.05,1,EQ,NSE,NSE 39 | 3604481,14080,GODREJIND-BE,GODREJ INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 40 | 4527361,17685,GPTINFRA,GPT INFRAPROJECTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 41 | 211713,827,DEEPAKFERT,DEEPAK FERTILIZERS & PETR,0.0,,0.0,0.05,1,EQ,NSE,NSE 42 | 1256193,4907,ENGINERSIN,ENGINEERS INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 43 | 3449089,13473,GTNTEX,GTN TEXTILES,0.0,,0.0,0.05,1,EQ,NSE,NSE 44 | 5003009,19543,HDFCMFGETF,HDFC GOLD ETF,0.0,,0.0,0.05,1,EQ,NSE,NSE 45 | 2166273,8462,DUNCANSIND-BE,DUNCANS INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 46 | 3798529,14838,DECCANCE,DECCAN CEMENTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 47 | 212481,830,DEEPAKNITR,DEEPAK NITRITE,0.0,,0.0,0.05,1,EQ,NSE,NSE 48 | 3542273,13837,DONEAR-BL,DONEAR IND.,0.0,,0.0,0.05,1,EQ,NSE,NSE 49 | 3862529,15088,EDL,EMPEE DISTI.,0.0,,0.0,0.05,1,EQ,NSE,NSE 50 | 2389505,9334,RAVALSUGAR-BE,RAVALGAONSUGAR FARM,0.0,,0.0,0.05,1,EQ,NSE,NSE 51 | 7697153,30067,DUNCANSLTD-BE,DUNCANS INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 52 | 4818433,18822,ENDURANCE,ENDURANCE TECHNO.,0.0,,0.0,0.05,1,EQ,NSE,NSE 53 | 2683649,10483,ENTEGRA,ENTEGRA,0.0,,0.0,0.05,1,EQ,NSE,NSE 54 | 3411713,13327,ERAINFRA,ERA INFRA ENGINEERING,0.0,,0.0,0.05,1,EQ,NSE,NSE 55 | 6563329,25638,ESSARSHPNG-BE,ESSAR SHIPPING,0.0,,0.0,0.05,1,EQ,NSE,NSE 56 | 4352001,17000,GISOLUTION-BE,GI ENGINEERING SOLNS,0.0,,0.0,0.05,1,EQ,NSE,NSE 57 | 1934849,7558,GONTERPEIP-BE,GONTERMANN PEIPERS DEPO,0.0,,0.0,0.05,1,EQ,NSE,NSE 58 | 2185985,8539,GTNIND-BE,GTN INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 59 | 3179009,12418,GUFICBIO-BL,GUFIC BIOSCIENCES,0.0,,0.0,0.05,1,EQ,NSE,NSE 60 | 4915969,19203,SGBNOV24-GB,2.50% GOLDBONDS2024 TR-VI,0.0,,0.0,0.01,1,EQ,NSE,NSE 61 | 5401857,21101,STARCEMENT-BE,STAR CEMENT,0.0,,0.0,0.05,1,EQ,NSE,NSE 62 | 5533185,21614,ABCAPITAL,ADITYA BIRLA CAPITAL,0.0,,0.0,0.05,1,EQ,NSE,NSE 63 | 3372545,13174,BALKRISIND-BL,BALKRISHNA IND.,0.0,,0.0,0.05,1,EQ,NSE,NSE 64 | 2160129,8438,DATAPROINF-BE,DATAPROINFO - ROLL SETT,0.0,,0.0,0.05,1,EQ,NSE,NSE 65 | 7590401,29650,HUDCO-N7,BOND 7.19% PA TAX FREE S2,0.0,,0.0,0.01,1,EQ,NSE,NSE 66 | 3914497,15291,HERCULES-BL,HERCULES HOI.,0.0,,0.0,0.05,1,EQ,NSE,NSE 67 | 4365313,17052,HARITASEAT,HARITA SEATING SYS.,0.0,,0.0,0.05,1,EQ,NSE,NSE 68 | 3183361,12435,HERITGFOOD-BL,HERITAGE FOODS,0.0,,0.0,0.05,1,EQ,NSE,NSE 69 | 1806849,7058,HESTERBIO-BL,HESTER BIOSCIENCES,0.0,,0.0,0.05,1,EQ,NSE,NSE 70 | 4895233,19122,HIGHGROUND-BE,HIGH GROUND ENTP,0.0,,0.0,0.05,1,EQ,NSE,NSE 71 | 3508225,13704,HINDZINC-BL,HINDUSTAN ZINC,0.0,,0.0,0.05,1,EQ,NSE,NSE 72 | 1804289,7048,HESTERBIO,HESTER BIOSCIENCES,0.0,,0.0,0.05,1,EQ,NSE,NSE 73 | 4894977,19121,HIGHGROUND-BL,HIGH GROUND ENTP,0.0,,0.0,0.05,1,EQ,NSE,NSE 74 | 3188225,12454,HIL-BL,HIL,0.0,,0.0,0.05,1,EQ,NSE,NSE 75 | 3745537,14631,HILTON-BE,HILTON METAL FORGING,0.0,,0.0,0.05,1,EQ,NSE,NSE 76 | 4593409,17943,HINDCOPPER-BE,HINDUSTAN COPPER,0.0,,0.0,0.05,1,EQ,NSE,NSE 77 | 4364801,17050,HINDNATGLS-BE,HIND NATL GLASS & IND,0.0,,0.0,0.05,1,EQ,NSE,NSE 78 | 4767233,18622,IBULHSGFIN-N7,SEC RED NCD SR. IV,0.0,,0.0,0.01,1,EQ,NSE,NSE 79 | 7589889,29648,HUDCO-N6,BOND 7.03% PA TAX FREE S1,0.0,,0.0,0.01,1,EQ,NSE,NSE 80 | 5110273,19962,HUDCO-NA,8.14% TAX FREETRI SR1A,0.0,,0.0,0.01,1,EQ,NSE,NSE 81 | 3790593,14807,HDIL-BE,HOUSING DEV & INFRA,0.0,,0.0,0.05,1,EQ,NSE,NSE 82 | 3914753,15292,HERCULES-BE,HERCULES HOI.,0.0,,0.0,0.05,1,EQ,NSE,NSE 83 | 4774913,18652,ICICIPRULI,ICICI PRU LIFE INS CO,0.0,,0.0,0.05,1,EQ,NSE,NSE 84 | 3607041,14090,IGPL-BE,I G PETROCHEMICALS,0.0,,0.0,0.05,1,EQ,NSE,NSE 85 | 3606017,14086,IGPL,I G PETROCHEMICALS,0.0,,0.0,0.05,1,EQ,NSE,NSE 86 | 3718401,14525,ICRA-BL,ICRA,0.0,,0.0,0.05,1,EQ,NSE,NSE 87 | 3489793,13632,ICSA,ICSA (INDIA),0.0,,0.0,0.05,1,EQ,NSE,NSE 88 | 3189761,12460,IDBI-BL,IDBI BANK,0.0,,0.0,0.05,1,EQ,NSE,NSE 89 | 2795521,10920,IDFCBANK-NE,BOND 0% 2022 TR-3 SR-II,0.0,,0.0,0.01,1,EQ,NSE,NSE 90 | 2883073,11262,IGL,INDRAPRASTHA GAS,0.0,,0.0,0.05,1,EQ,NSE,NSE 91 | 5357825,20929,JALAN-SM,JALAN TRANSOLU. INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 92 | 1388801,5425,JBFIND-BE,JBF INDUS -DEP-LS ML,0.0,,0.0,0.05,1,EQ,NSE,NSE 93 | 3083265,12044,JCHAC-BL,JOHNSON CONTROLS HITACHI,0.0,,0.0,0.05,1,EQ,NSE,NSE 94 | 3857153,15067,JCTEL-BL,JCT ELE.,0.0,,0.0,0.05,1,EQ,NSE,NSE 95 | 2997505,11709,JETAIRWAYS,JET AIRWAYS (INDIA),0.0,,0.0,0.05,1,EQ,NSE,NSE 96 | 3513089,13723,JHS-BE,JHS SVEND. LAB.,0.0,,0.0,0.05,1,EQ,NSE,NSE 97 | 3006209,11743,JINDALPHOT,JINDAL PHOTO,0.0,,0.0,0.05,1,EQ,NSE,NSE 98 | 4400641,17190,SHRIPISTON-BE,SHRIRAM PIST. & RING,0.0,,0.0,0.05,1,EQ,NSE,NSE 99 | 2122497,8291,SHRIYAMSEC-BE,SHRIYAM SEC & FIN,0.0,,0.0,0.05,1,EQ,NSE,NSE 100 | 510209,1993,IRFC-ND,BOND 8.44% PA TF TII-SIB,0.0,,0.0,0.01,1,EQ,NSE,NSE 101 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/instruments_all.csv: -------------------------------------------------------------------------------- 1 | instrument_token,exchange_token,tradingsymbol,name,last_price,expiry,strike,tick_size,lot_size,instrument_type,segment,exchange 2 | 3813889,14898,WEIRDSTRIKE,WEIRD STRIKE,10.01,,1.314E+1,0.05,1,EQ,NSE,NSE 3 | 3813889,14898,CENTRALBK-BE,CENTRAL BANK OF INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 4 | 4645121,18145,EMMBI-BL,EMMBI INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 5 | 4531969,17703,MIDCAPIWIN-BL,ICICI PRU MIDCAP IWIN ETF,0.0,,0.0,0.01,1,EQ,NSE,NSE 6 | 5533953,21617,ABCAPITAL-BL,ADITYA BIRLA CAPITAL,0.0,,0.0,0.05,1,EQ,NSE,NSE 7 | 3861249,15083,ADANIPORTS,ADANI PORT & SEZ,0.0,,0.0,0.05,1,EQ,NSE,NSE 8 | 4419329,17263,ARMANFIN,ARMAN FIN SERV,0.0,,0.0,0.05,1,EQ,NSE,NSE 9 | 12073986,47164,BANKNIFTY18JAN23500CE,,2528.4,2018-01-25,23500.0,0.05,40,CE,NFO-OPT,NFO 10 | 13693186,53489,ADANIPORTS17DEC490PE,,80.65,2017-12-28,490.0,0.05,2500,PE,NFO-OPT,NFO 11 | 136483588,533139,FFTF16BGR,FORTIS FIXED TERM FUND - SERIE,0.0,,0.0,0.01,1,EQ,BSE,BSE 12 | 3713281,14505,BALAMINES-BE,BALAJI AMINES,0.0,,0.0,0.05,1,EQ,NSE,NSE 13 | 1373441,5365,BATAINDIA-BE,BATA INDIA DEP RS,0.0,,0.0,0.05,1,EQ,NSE,NSE 14 | 5421569,21178,CDSL-BE,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 15 | 5421313,21177,CDSL-BL,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 16 | 1374209,5368,CHENNPETRO-BE,CHENNAI PETRO CORP DE,0.0,,0.0,0.05,1,EQ,NSE,NSE 17 | 3419393,13357,GANGOTRI,GANGOTRI TEXTILES,0.0,,0.0,0.05,1,EQ,NSE,NSE 18 | 2703361,10560,NAVKARCORP-BL,NAVKAR CORPORATION,0.0,,0.0,0.05,1,EQ,NSE,NSE 19 | 5001473,19537,PDPL,PARENTERAL DRUGS,0.0,,0.0,0.05,1,EQ,NSE,NSE 20 | 12074242,47165,BANKNIFTY18JAN23500PE,,35.15,2018-01-25,23500.0,0.05,40,PE,NFO-OPT,NFO 21 | 12074498,47166,BANKNIFTY18JAN23600CE,,2435.55,2018-01-25,23600.0,0.05,40,CE,NFO-OPT,NFO 22 | 5420545,21174,CDSL,CENTRAL DEPO SER (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 23 | 3370497,13166,CELEBRITY-BL,CELEBRITY FASHIONS,0.0,,0.0,0.05,1,EQ,NSE,NSE 24 | 12074754,47167,BANKNIFTY18JAN23600PE,,41.25,2018-01-25,23600.0,0.05,40,PE,NFO-OPT,NFO 25 | 3146497,12291,CENTEXT-BL,CENTURY EXTRUSIONS,0.0,,0.0,0.05,1,EQ,NSE,NSE 26 | 4550145,17774,GROBTEA-BE,THE GROB TEA COMPANY,0.0,,0.0,0.05,1,EQ,NSE,NSE 27 | 21227266,82919,INDIACEM17DEC220PE,,43.45,2017-12-28,220.0,0.05,3500,PE,NFO-OPT,NFO 28 | 6938881,27105,CHROMATIC-BE,CHROMATIC INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 29 | 4578305,17884,DBCORP-BL,D.B.CORP,0.0,,0.0,0.05,1,EQ,NSE,NSE 30 | 3155457,12326,DCW-BL,DCW,0.0,,0.0,0.05,1,EQ,NSE,NSE 31 | 5101569,19928,HUDCO-N8,7.64% TAX FREETRI SR2B,0.0,,0.0,0.01,1,EQ,NSE,NSE 32 | 1707521,6670,INFARINDIA,INFAR (INDIA),0.0,,0.0,0.05,1,EQ,NSE,NSE 33 | 21227522,82920,INDIACEM17DEC225CE,,0.4,2017-12-28,225.0,0.05,3500,CE,NFO-OPT,NFO 34 | 21228290,82923,INDIACEM17DEC230PE,,53.1,2017-12-28,230.0,0.05,3500,PE,NFO-OPT,NFO 35 | 136484868,533144,COX&KINGS,COX & KINGS,0.0,,0.0,0.05,1,EQ,BSE,BSE 36 | 12072962,47160,BANKNIFTY18JAN23400CE,,2622.0,2018-01-25,23400.0,0.05,40,CE,NFO-OPT,NFO 37 | 12073474,47162,BANKNIFTY18JAN23400PE,,29.85,2018-01-25,23400.0,0.05,40,PE,NFO-OPT,NFO 38 | 12075010,47168,BANKNIFTY18JAN23700CE,,2343.55,2018-01-25,23700.0,0.05,40,CE,NFO-OPT,NFO 39 | 21227778,82921,INDIACEM17DEC225PE,,48.25,2017-12-28,225.0,0.05,3500,PE,NFO-OPT,NFO 40 | 21228034,82922,INDIACEM17DEC230CE,,0.25,2017-12-28,230.0,0.05,3500,CE,NFO-OPT,NFO 41 | 112655620,440061,828GOI27-ML,828GOI2027,0.0,,0.0,0.25,500000,EQ,BSE,BSE 42 | 136441604,532975,AISHWARYA,AISHWARYA TELECOM,0.0,,0.0,0.01,1,EQ,BSE,BSE 43 | 136483076,533137,DEN,DEN NETWORKS,0.0,,0.0,0.05,1,EQ,BSE,BSE 44 | 136483332,533138,ASTEC,ASTEC LIFESCIENCES,0.0,,0.0,0.05,1,EQ,BSE,BSE 45 | 136485380,533146,DLINKINDIA,D-LINK (INDIA),0.0,,0.0,0.05,1,EQ,BSE,BSE 46 | 1219329,4763,BANKBARODA-BE,BOB - DEPO SETT,0.0,,0.0,0.05,1,EQ,NSE,NSE 47 | 2928385,11439,BANKBEES,RELIANCE ETF BANK BEES,0.0,,0.0,0.01,1,EQ,NSE,NSE 48 | 3715841,14515,BANSWRAS-BE,BANSWARA SYNTEX,0.0,,0.0,0.05,1,EQ,NSE,NSE 49 | 3137281,12255,BERGEPAINT-BL,BERGER PAINTS (I),0.0,,0.0,0.05,1,EQ,NSE,NSE 50 | 3901185,15239,BIRLAMONEY,ADITYA BIRLA MONEY,0.0,,0.0,0.05,1,EQ,NSE,NSE 51 | 1789185,6989,CARRIERAIR-BE,CARRIER AIRCON DEPO,0.0,,0.0,0.05,1,EQ,NSE,NSE 52 | 3123713,12202,CASTEXTECH-BL,CASTEX TECHNOLOGIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 53 | 136485892,533148,JSWENERGY,JSW ENERGY,0.0,,0.0,0.05,1,EQ,BSE,BSE 54 | 136486916,533152,MBLINFRA,MBL INFRASTRUCTURES,0.0,,0.0,0.05,1,EQ,BSE,BSE 55 | 136487172,533153,FDCLTDBBPH,FDC*,0.0,,0.0,0.05,1,EQ,BSE,BSE 56 | 138027524,539170,AXISHB23DD,AXIS MUTUAL FUND,0.0,,0.0,0.01,1,EQ,BSE,BSE 57 | 244332292,954423,RCL14JUL16B,RCL-NIFTY-14-1-19-PVT,0.0,,0.0,0.01,10,EQ,BSE,BSE 58 | 244352260,954501,8HDFCL18,HDFCL-8%-15-1-18-PVT,0.0,,0.0,0.01,1,EQ,BSE,BSE 59 | 244834820,956386,945SREI24,SREI-9.45%-26-5-24-PVT,0.0,,0.0,0.01,1,EQ,BSE,BSE 60 | 5534209,21618,ABCAPITAL-BE,ADITYA BIRLA CAPITAL,0.0,,0.0,0.05,1,EQ,NSE,NSE 61 | 3412225,13329,ERAINFRA-BL,ERA INFRA ENGINEERING,0.0,,0.0,0.05,1,EQ,NSE,NSE 62 | 1884161,7360,SETFNN50-BL,SBI-ETF NIFTY NEXT 50,0.0,,0.0,0.01,1,EQ,NSE,NSE 63 | 3028225,11829,SSWL,STEEL STRIPS WHEELS,0.0,,0.0,0.05,1,EQ,NSE,NSE 64 | 12075266,47169,BANKNIFTY18JAN23700PE,,48.15,2018-01-25,23700.0,0.05,40,PE,NFO-OPT,NFO 65 | 12525058,48926,BANKNIFTY17DEC22500PE,,8.0,2017-12-28,22500.0,0.05,40,PE,NFO-OPT,NFO 66 | 13842434,54072,BANKNIFTY17NOV23600PE,,3.0,2017-11-30,23600.0,0.05,40,PE,NFO-OPT,NFO 67 | 6128129,23938,ESSARPORTS-BE,ESSAR PORTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 68 | 21231874,82937,INDIANB17DEC160PE,,0.05,2017-12-28,160.0,0.05,2000,PE,NFO-OPT,NFO 69 | 136492036,533172,IVZINGOLD,INVESCO INDIA GOLD EXCHANGE TR,0.0,,0.0,0.01,1,EQ,BSE,BSE 70 | 21232386,82939,INDIANB17DEC170PE,,0.05,2017-12-28,170.0,0.05,2000,PE,NFO-OPT,NFO 71 | 13845506,54084,BANKNIFTY17NOV23900PE,,2.25,2017-11-30,23900.0,0.05,40,PE,NFO-OPT,NFO 72 | 136504580,533221,AHLWEST,ASIAN HOTELS (WEST),0.0,,0.0,0.05,1,EQ,BSE,BSE 73 | 4671233,18247,DEEPIND-BL,DEEP INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 74 | 6562305,25634,ESSARSHPNG,ESSAR SHIPPING,0.0,,0.0,0.05,1,EQ,NSE,NSE 75 | 136518404,533275,GAL,GYSCOAL ALLOYS,0.0,,0.0,0.01,1,EQ,BSE,BSE 76 | 3604481,14080,GODREJIND-BE,GODREJ INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 77 | 4527361,17685,GPTINFRA,GPT INFRAPROJECTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 78 | 13845762,54085,BANKNIFTY17NOV24000CE,,1776.2,2017-11-30,24000.0,0.05,40,CE,NFO-OPT,NFO 79 | 211713,827,DEEPAKFERT,DEEPAK FERTILIZERS & PETR,0.0,,0.0,0.05,1,EQ,NSE,NSE 80 | 1256193,4907,ENGINERSIN,ENGINEERS INDIA,0.0,,0.0,0.05,1,EQ,NSE,NSE 81 | 3449089,13473,GTNTEX,GTN TEXTILES,0.0,,0.0,0.05,1,EQ,NSE,NSE 82 | 5003009,19543,HDFCMFGETF,HDFC GOLD ETF,0.0,,0.0,0.05,1,EQ,NSE,NSE 83 | 2166273,8462,DUNCANSIND-BE,DUNCANS INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 84 | 21230850,82933,INDIANB17DEC140PE,,0.05,2017-12-28,140.0,0.05,2000,PE,NFO-OPT,NFO 85 | 21231106,82934,INDIANB17DEC150CE,,262.45,2017-12-28,150.0,0.05,2000,CE,NFO-OPT,NFO 86 | 21231362,82935,INDIANB17DEC150PE,,0.05,2017-12-28,150.0,0.05,2000,PE,NFO-OPT,NFO 87 | 136518660,533276,BSLIMITED,BS,0.0,,0.0,0.01,1,EQ,BSE,BSE 88 | 3798529,14838,DECCANCE,DECCAN CEMENTS,0.0,,0.0,0.05,1,EQ,NSE,NSE 89 | 212481,830,DEEPAKNITR,DEEPAK NITRITE,0.0,,0.0,0.05,1,EQ,NSE,NSE 90 | 3542273,13837,DONEAR-BL,DONEAR IND.,0.0,,0.0,0.05,1,EQ,NSE,NSE 91 | 3862529,15088,EDL,EMPEE DISTI.,0.0,,0.0,0.05,1,EQ,NSE,NSE 92 | 2389505,9334,RAVALSUGAR-BE,RAVALGAONSUGAR FARM,0.0,,0.0,0.05,1,EQ,NSE,NSE 93 | 21231618,82936,INDIANB17DEC160CE,,252.5,2017-12-28,160.0,0.05,2000,CE,NFO-OPT,NFO 94 | 21232130,82938,INDIANB17DEC170CE,,242.55,2017-12-28,170.0,0.05,2000,CE,NFO-OPT,NFO 95 | 112653060,440051,830GOI42-ML,830GOI2042,0.0,,0.0,0.25,500000,EQ,BSE,BSE 96 | 7697153,30067,DUNCANSLTD-BE,DUNCANS INDUSTRIES,0.0,,0.0,0.05,1,EQ,NSE,NSE 97 | 4818433,18822,ENDURANCE,ENDURANCE TECHNO.,0.0,,0.0,0.05,1,EQ,NSE,NSE 98 | 2683649,10483,ENTEGRA,ENTEGRA,0.0,,0.0,0.05,1,EQ,NSE,NSE 99 | 3411713,13327,ERAINFRA,ERA INFRA ENGINEERING,0.0,,0.0,0.05,1,EQ,NSE,NSE 100 | 6563329,25638,ESSARSHPNG-BE,ESSAR SHIPPING,0.0,,0.0,0.05,1,EQ,NSE,NSE 101 | 4352001,17000,GISOLUTION-BE,GI ENGINEERING SOLNS,0.0,,0.0,0.05,1,EQ,NSE,NSE 102 | -------------------------------------------------------------------------------- /KiteConnect/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using NotVisualBasic.FileIO; 6 | using System.Text; 7 | using System.IO; 8 | using System.Web; 9 | using System.Security.Cryptography; 10 | using System.Text.RegularExpressions; 11 | using System.Globalization; 12 | using System.Text.Json; 13 | 14 | namespace KiteConnect 15 | { 16 | public class Utils 17 | { 18 | /// 19 | /// Convert string to Date object 20 | /// 21 | /// Date string. 22 | /// Date object/ 23 | public static DateTime? StringToDate(string DateString) 24 | { 25 | if (String.IsNullOrEmpty(DateString)) 26 | return null; 27 | 28 | try 29 | { 30 | if (DateString.Length == 10) 31 | { 32 | return DateTime.ParseExact(DateString, "yyyy-MM-dd", null); 33 | } 34 | else 35 | { 36 | return DateTime.ParseExact(DateString, "yyyy-MM-dd HH:mm:ss", null); 37 | } 38 | } 39 | catch (Exception) 40 | { 41 | return null; 42 | } 43 | } 44 | 45 | /// 46 | /// Serialize C# object to JSON string. 47 | /// 48 | /// C# object to serialize. 49 | /// JSON string/ 50 | public static string JsonSerialize(object obj) 51 | { 52 | string json = JsonSerializer.Serialize(obj); 53 | MatchCollection mc = Regex.Matches(json, @"\\/Date\((\d*?)\)\\/"); 54 | foreach (Match m in mc) 55 | { 56 | UInt64 unix = UInt64.Parse(m.Groups[1].Value) / 1000; 57 | json = json.Replace(m.Groups[0].Value, UnixToDateTime(unix).ToString()); 58 | } 59 | return json; 60 | } 61 | 62 | /// 63 | /// Deserialize Json string to nested string dictionary. 64 | /// 65 | /// Json string to deserialize. 66 | /// Json in the form of nested string dictionary. 67 | public static Dictionary JsonDeserialize(string Json) 68 | { 69 | JsonElement elm = JsonSerializer.Deserialize(Json); 70 | // Replace double with decimal in the map 71 | Dictionary dict = ElementToDict(elm); 72 | return dict; 73 | } 74 | 75 | /// 76 | /// Recursively traverses an object and converts JsonElement objects to corresponding primitives. 77 | /// 78 | /// Input JsonElement object. 79 | /// Object with primitives 80 | public static dynamic ElementToDict(JsonElement obj) 81 | { 82 | if (obj.ValueKind == JsonValueKind.Number) 83 | { 84 | return StringToDecimal(obj.GetRawText()); 85 | } 86 | else if (obj.ValueKind == JsonValueKind.String) 87 | { 88 | return obj.GetString(); 89 | } 90 | else if (obj.ValueKind == JsonValueKind.True || obj.ValueKind == JsonValueKind.False) 91 | { 92 | return obj.GetBoolean(); 93 | } 94 | else if (obj.ValueKind == JsonValueKind.Object) 95 | { 96 | var map = obj.EnumerateObject().ToList(); 97 | var newMap = new Dictionary(); 98 | for (int i = 0; i < map.Count; i++) 99 | { 100 | newMap.Add(map[i].Name, ElementToDict(map[i].Value)); 101 | } 102 | return newMap; 103 | } 104 | else if (obj.ValueKind == JsonValueKind.Array) 105 | { 106 | var items = obj.EnumerateArray().ToList(); 107 | var newItems = new ArrayList(); 108 | for (int i = 0; i < items.Count; i++) 109 | { 110 | newItems.Add(ElementToDict(obj[i])); 111 | } 112 | return newItems; 113 | } 114 | else 115 | { 116 | return null; 117 | } 118 | } 119 | 120 | /// 121 | /// Converts string to decimal. Handles culture and scientific notations. 122 | /// 123 | /// Input string. 124 | /// Decimal value 125 | public static decimal StringToDecimal(String value) 126 | { 127 | return decimal.Parse(value, NumberStyles.Any, CultureInfo.InvariantCulture); 128 | } 129 | 130 | /// 131 | /// Parse instruments API's CSV response. 132 | /// 133 | /// Response of instruments API. 134 | /// CSV data as array of nested string dictionary. 135 | public static List> ParseCSV(string Data) 136 | { 137 | string[] lines = Data.Split('\n'); 138 | 139 | List> instruments = new List>(); 140 | 141 | using (var parser = new CsvTextFieldParser(StreamFromString(Data))) 142 | { 143 | // parser.CommentTokens = new string[] { "#" }; 144 | // parser.SetDelimiters(new string[] { "," }); 145 | parser.HasFieldsEnclosedInQuotes = true; 146 | 147 | // Skip over header line. 148 | string[] headers = parser.ReadFields(); 149 | 150 | while (!parser.EndOfData) 151 | { 152 | string[] fields = parser.ReadFields(); 153 | Dictionary item = new Dictionary(); 154 | 155 | for (var i = 0; i < headers.Length; i++) 156 | item.Add(headers[i], fields[i]); 157 | 158 | instruments.Add(item); 159 | } 160 | } 161 | 162 | return instruments; 163 | } 164 | 165 | /// 166 | /// Wraps a string inside a stream 167 | /// 168 | /// string data 169 | /// Stream that reads input string 170 | public static MemoryStream StreamFromString(string value) 171 | { 172 | return new MemoryStream(Encoding.UTF8.GetBytes(value ?? "")); 173 | } 174 | 175 | /// 176 | /// Helper function to add parameter to the request only if it is not null or empty 177 | /// 178 | /// Dictionary to add the key-value pair 179 | /// Key of the parameter 180 | /// Value of the parameter 181 | public static void AddIfNotNull(Dictionary Params, string Key, string Value) 182 | { 183 | if (!String.IsNullOrEmpty(Value)) 184 | Params.Add(Key, Value); 185 | } 186 | 187 | /// 188 | /// Generates SHA256 checksum for login. 189 | /// 190 | /// Input data to generate checksum for. 191 | /// SHA256 checksum in hex format. 192 | public static string SHA256Hash(string Data) 193 | { 194 | StringBuilder hexhash = new StringBuilder(); 195 | byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes(Data)); 196 | foreach (byte b in hash) 197 | { 198 | hexhash.Append(b.ToString("x2")); 199 | } 200 | return hexhash.ToString(); 201 | } 202 | 203 | /// 204 | /// Creates key=value with url encoded value 205 | /// 206 | /// Key 207 | /// Value 208 | /// Combined string 209 | public static string BuildParam(string Key, dynamic Value) 210 | { 211 | if (Value is string) 212 | { 213 | return HttpUtility.UrlEncode(Key) + "=" + HttpUtility.UrlEncode((string)Value); 214 | } 215 | else 216 | { 217 | string[] values = (string[])Value; 218 | return String.Join("&", values.Select(x => HttpUtility.UrlEncode(Key) + "=" + HttpUtility.UrlEncode(x))); 219 | } 220 | } 221 | 222 | /// 223 | /// Converts Unix timestamp to DateTime 224 | /// 225 | /// Unix timestamp in seconds. 226 | /// DateTime object. 227 | public static DateTime UnixToDateTime(UInt64 unixTimeStamp) 228 | { 229 | // Unix timestamp is seconds past epoch 230 | DateTime dateTime = new DateTime(1970, 1, 1, 5, 30, 0, 0, DateTimeKind.Unspecified); 231 | dateTime = dateTime.AddSeconds(unixTimeStamp); 232 | return dateTime; 233 | } 234 | 235 | /// 236 | /// Returns a default value if key doesn't exist in dictionary 237 | /// 238 | public static V GetValueOrDefault 239 | (IDictionary dictionary, K key, V defaultValue) => 240 | dictionary.TryGetValue(key, out var ret) ? ret : defaultValue; 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /KiteConnectTest/responses/mf_instruments.csv: -------------------------------------------------------------------------------- 1 | tradingsymbol,amc,name,purchase_allowed,redemption_allowed,minimum_purchase_amount,purchase_amount_multiplier,minimum_additional_purchase_amount,minimum_redemption_quantity,redemption_quantity_multiplier,dividend_type,scheme_type,plan,settlement_type,last_price,last_price_date 2 | INF209K01157,FAKE_MF,FAKE_FUND,1,1,1234.0,1.314E+1,1000.0,0.001,0.001,payout,equity,regular,T3,106.8,2017-11-23 3 | INF209K01157,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Advantage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,106.8,2017-11-23 4 | INF209K01165,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Advantage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,436.72,2017-11-23 5 | INF209K01VG0,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Advantage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,134.2,2017-11-23 6 | INF209K01VH8,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Advantage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,453.46,2017-11-23 7 | INF209K01BS7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced 95 Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,153.26,2017-11-23 8 | INF209K01BT5,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced 95 Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,758.0,2017-11-23 9 | INF209K01ZC0,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced 95 Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,796.56,2017-11-23 10 | INF209KA1LH3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced 95 Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,219.49,2017-11-23 11 | INF084M01AB8,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced Advantage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,balanced,regular,T3,50.46,2017-11-23 12 | INF084M01AC6,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced Advantage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,balanced,regular,T3,22.07,2017-11-23 13 | INF084M01DJ5,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced Advantage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,balanced,direct,T3,52.43,2017-11-23 14 | INF084M01DK3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Balanced Advantage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,balanced,direct,T3,23.0,2017-11-23 15 | INF209K010W9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking And Financial Services Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,19.62,2017-11-23 16 | INF209K011W7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking And Financial Services Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,27.94,2017-11-23 17 | INF209K013W3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking And Financial Services Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,24.55,2017-11-23 18 | INF209K014W1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking And Financial Services Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,28.99,2017-11-23 19 | INF209K01BE7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking and PSU Debt Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,9.9875,2017-11-23 20 | INF209K01BF4,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking and PSU Debt Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,49.8034,2017-11-23 21 | INF209K01YJ8,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking and PSU Debt Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,12.7089,2017-11-23 22 | INF209K01YK6,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking and PSU Debt Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,10.4884,2017-11-23 23 | INF209K01YL4,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Banking and PSU Debt Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,51.1321,2017-11-23 24 | INF209K01LQ0,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Cash Manager,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,408.9951,2017-11-23 25 | INF209K01XU7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Cash Manager - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,425.8148,2017-11-23 26 | INF209K01RU9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Cash Plus,1,1,5000.0,1.0,1000.0,0.001,0.001,growth,liquid,regular,T1,271.5949,2017-11-23 27 | INF209K01VA3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Cash Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,liquid,direct,T1,272.5712,2017-11-23 28 | INF209K01VD7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Cash Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,liquid,direct,T1,147.9867,2017-11-23 29 | INF209K01199,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Commodity Equities Fund - Global Agri Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T6,16.4009,2017-11-23 30 | INF209K01207,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Commodity Equities Fund - Global Agri Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T6,23.1229,2017-11-23 31 | INF209K01AH2,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Constant Maturity 10 Year Gilt Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,50.6235,2017-11-23 32 | INF209K01AI0,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Constant Maturity 10 Year Gilt Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,12.0695,2017-11-23 33 | INF209K01XS1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Constant Maturity 10 Year Gilt Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,50.998,2017-11-23 34 | INF209KA1K47,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Corporate Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,12.6521,2017-11-23 35 | INF209KA1K54,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Corporate Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,11.4171,2017-11-23 36 | INF209KA1K88,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Corporate Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,12.9524,2017-11-23 37 | INF209KA1K96,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Corporate Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,11.708,2017-11-23 38 | INF209K01397,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dividend Yield Plus,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,17.25,2017-11-23 39 | INF209K01405,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dividend Yield Plus,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,178.4,2017-11-23 40 | INF209K01Q55,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dividend Yield Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,26.66,2017-11-23 41 | INF209K01WA1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dividend Yield Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,185.33,2017-11-23 42 | INF209K01793,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,30.0556,2017-11-23 43 | INF209K01801,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,10.9249,2017-11-23 44 | INF209K01819,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,10.1744,2017-11-23 45 | INF209KA1TV7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T1,12.1802,2017-11-23 46 | INF209K01N82,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,30.8721,2017-11-23 47 | INF209K01R62,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,11.1149,2017-11-23 48 | INF209K01R88,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,10.4108,2017-11-23 49 | INF209KA1TX3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Dynamic Bond Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,12.4196,2017-11-23 50 | INF209K01256,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Enhanced Arbitrage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,10.8783,2017-11-23 51 | INF209K01264,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Enhanced Arbitrage Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,17.5067,2017-11-23 52 | INF209K01P80,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Enhanced Arbitrage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,11.0934,2017-11-23 53 | INF209K01VP1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Enhanced Arbitrage Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,17.9567,2017-11-23 54 | INF209K01AJ8,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,710.7,2017-11-23 55 | INF209K01AQ3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,104.58,2017-11-23 56 | INF209K01XX1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,742.17,2017-11-23 57 | INF209KA1TS3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Savings Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,13.1,2017-11-23 58 | INF209KA1TT1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Savings Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,11.64,2017-11-23 59 | INF209KA1TP9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Savings Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,13.54,2017-11-23 60 | INF209KA1TQ7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Equity Savings Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,12.27,2017-11-23 61 | INF084M01101,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Aggressive Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,fof,regular,T4,21.9919,2017-11-23 62 | INF084M01119,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Aggressive Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,fof,regular,T4,20.13,2017-11-23 63 | INF084M01044,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Conservative Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,fof,regular,T4,17.3032,2017-11-23 64 | INF084M01051,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Conservative Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,fof,regular,T4,15.744,2017-11-23 65 | INF084M01077,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Prudent Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,fof,regular,T4,19.0899,2017-11-23 66 | INF084M01085,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Financial Planning FoF Prudent Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,fof,regular,T4,17.1217,2017-11-23 67 | INF209K01MG9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Floating Rate Fund - Long Term Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,208.1037,2017-11-23 68 | INF209K01UX7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Floating Rate Fund - Long Term Plan - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,210.3858,2017-11-23 69 | INF209K01RV7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Floating Rate Fund - Short Term Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,liquid,regular,T1,225.569,2017-11-23 70 | INF209K01UU3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Floating Rate Fund - Short Term Plan - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,liquid,direct,T1,226.363,2017-11-23 71 | INF209K01BO6,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Frontline Equity Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,27.34,2017-11-23 72 | INF209K01BR9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Frontline Equity Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,217.34,2017-11-23 73 | INF209K01YX9,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Frontline Equity Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,50.73,2017-11-23 74 | INF209K01YY7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Frontline Equity Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,227.39,2017-11-23 75 | INF209K01AC3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,48.6101,2017-11-23 76 | INF209K01AD1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,48.6101,2017-11-23 77 | INF209K01AF6,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,10.1758,2017-11-23 78 | INF209K01XP7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,49.8019,2017-11-23 79 | INF209K01XQ5,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,49.8019,2017-11-23 80 | INF209KA1LC4,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gilt Plus - PF Plan - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,10.3855,2017-11-23 81 | INF209K01PF4,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gold Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,fof,regular,T3,9.5415,2017-11-23 82 | INF209K01PG2,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gold Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,fof,regular,T3,9.5402,2017-11-23 83 | INF209K01YT7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gold Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,fof,direct,T3,9.6571,2017-11-23 84 | INF209K01YU5,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Gold Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,fof,direct,T3,9.6609,2017-11-23 85 | INF209K01R13,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Income Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,13.3298,2017-11-23 86 | INF209K01WY1,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Income Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,direct,T1,78.7456,2017-11-23 87 | INF209KA1WL2,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Income Plus - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,direct,T1,11.621,2017-11-23 88 | INF209K01579,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Income Plus - Regular Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,debt,regular,T1,76.0586,2017-11-23 89 | INF209K01587,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Income Plus - Regular Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,debt,regular,T1,12.7941,2017-11-23 90 | INF209K01LA4,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Index Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,13.3014,2017-11-23 91 | INF209K01LB2,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Index Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,101.4926,2017-11-23 92 | INF209K01VX5,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Index Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,13.4709,2017-11-23 93 | INF209K01VY3,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life Index Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,101.6988,2017-11-23 94 | INF209K01439,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India GenNext Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,25.71,2017-11-23 95 | INF209K01447,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India GenNext Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,78.3,2017-11-23 96 | INF209K01Q63,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India GenNext Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,29.23,2017-11-23 97 | INF209K01WC7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India GenNext Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,82.08,2017-11-23 98 | INF209K01280,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India Opportunities Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,regular,T3,30.52,2017-11-23 99 | INF209K01298,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India Opportunities Fund,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,regular,T3,146.95,2017-11-23 100 | INF209K01P98,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India Opportunities Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,payout,equity,direct,T3,42.01,2017-11-23 101 | INF209K01VR7,BirlaSunLifeMutualFund_MF,Aditya Birla Sun Life India Opportunities Fund - Direct Plan,1,1,1000.0,1.0,1000.0,0.001,0.001,growth,equity,direct,T3,151.59,2017-11-23 102 | -------------------------------------------------------------------------------- /KiteConnectTest/KiteTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using KiteConnect; 4 | using System.Net; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Text; 8 | 9 | namespace KiteConnectTest 10 | { 11 | [TestClass] 12 | public class KiteTest 13 | { 14 | MockServer ms; 15 | 16 | [TestInitialize] 17 | public void TestInitialize() 18 | { 19 | ms = new MockServer("http://localhost:8080/"); 20 | } 21 | 22 | [TestCleanup] 23 | public void TestCleanup() 24 | { 25 | ms.Stop(); 26 | } 27 | 28 | [TestMethod] 29 | public void TestSetAccessToken() 30 | { 31 | Kite kite = new Kite("apikey"); 32 | kite.SetAccessToken("access_token"); 33 | Assert.ThrowsException(() => kite.GetPositions()); 34 | } 35 | 36 | 37 | [TestMethod] 38 | public void TestError() 39 | { 40 | string json = File.ReadAllText(@"responses/error.json", Encoding.UTF8); 41 | ms.SetStatusCode(403); 42 | ms.SetResponse("application/json", json); 43 | Kite kite = new Kite("apikey", Root: "http://localhost:8080", Debug: true); 44 | Assert.ThrowsException(() => kite.GetProfile()); 45 | } 46 | 47 | [TestMethod] 48 | public void TestProfile() 49 | { 50 | string json = File.ReadAllText(@"responses/profile.json", Encoding.UTF8); 51 | ms.SetResponse("application/json", json); 52 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 53 | Profile profile = kite.GetProfile(); 54 | Console.WriteLine(profile.Email); 55 | Assert.AreEqual(profile.Email, "xxxyyy@gmail.com"); 56 | } 57 | 58 | [TestMethod] 59 | public void TestPositions() 60 | { 61 | string json = File.ReadAllText(@"responses/positions.json", Encoding.UTF8); 62 | ms.SetResponse("application/json", json); 63 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 64 | PositionResponse positionResponse = kite.GetPositions(); 65 | Assert.AreEqual(positionResponse.Net[0].TradingSymbol, "LEADMINI17DECFUT"); 66 | Assert.AreEqual(positionResponse.Day[0].TradingSymbol, "GOLDGUINEA17DECFUT"); 67 | } 68 | 69 | [TestMethod] 70 | public void TestHoldings() 71 | { 72 | string json = File.ReadAllText(@"responses/holdings.json", Encoding.UTF8); 73 | ms.SetResponse("application/json", json); 74 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 75 | List holdings = kite.GetHoldings(); 76 | Assert.AreEqual(holdings[0].AveragePrice, 40.67m); 77 | } 78 | 79 | [TestMethod] 80 | public void TestAuctionInstruments() 81 | { 82 | string json = File.ReadAllText(@"responses/auction_instruments.json", Encoding.UTF8); 83 | ms.SetResponse("application/json", json); 84 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 85 | List instruments = kite.GetAuctionInstruments(); 86 | Assert.AreEqual(instruments[0].PNL, 564.8000000000002m); 87 | } 88 | 89 | [TestMethod] 90 | public void TestMargins() 91 | { 92 | string json = File.ReadAllText(@"responses/margins.json", Encoding.UTF8); 93 | ms.SetResponse("application/json", json); 94 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 95 | UserMarginsResponse margins = kite.GetMargins(); 96 | 97 | Assert.AreEqual(margins.Equity.Net, (decimal)1697.7); 98 | Assert.AreEqual(margins.Commodity.Net, (decimal)-8676.296); 99 | } 100 | 101 | [TestMethod] 102 | public void TestOrderMargins() 103 | { 104 | string json = File.ReadAllText(@"responses/order_margins.json", Encoding.UTF8); 105 | ms.SetResponse("application/json", json); 106 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 107 | 108 | OrderMarginParams param = new OrderMarginParams(); 109 | param.Exchange = Constants.EXCHANGE_NFO; 110 | param.TradingSymbol = "ASHOKLEY20NOVFUT"; 111 | param.TransactionType = Constants.TRANSACTION_TYPE_SELL; 112 | param.Quantity = 1; 113 | param.Price = 64.0000m; 114 | param.OrderType = Constants.ORDER_TYPE_MARKET; 115 | param.Product = Constants.PRODUCT_MIS; 116 | 117 | List margins = kite.GetOrderMargins(new List() { param }); 118 | 119 | Assert.AreEqual(margins[0].Total, (decimal)8.36025); 120 | Assert.AreEqual(margins[0].SPAN, (decimal)5.408); 121 | Assert.AreEqual(margins[0].Leverage, (decimal)5); 122 | Assert.AreEqual(margins[0].Charges.TransactionTax, (decimal)0.5); 123 | Assert.AreEqual(margins[0].Charges.GST.IGST, (decimal)0.386496); 124 | } 125 | 126 | [TestMethod] 127 | public void TestOrderMarginsCompact() 128 | { 129 | string json = File.ReadAllText(@"responses/order_margins_compact.json", Encoding.UTF8); 130 | ms.SetResponse("application/json", json); 131 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 132 | 133 | OrderMarginParams param = new OrderMarginParams(); 134 | param.Exchange = Constants.EXCHANGE_NFO; 135 | param.TradingSymbol = "ASHOKLEY21JULFUT"; 136 | param.TransactionType = Constants.TRANSACTION_TYPE_SELL; 137 | param.Quantity = 1; 138 | param.Price = 64.0000m; 139 | param.OrderType = Constants.ORDER_TYPE_MARKET; 140 | param.Product = Constants.PRODUCT_MIS; 141 | 142 | OrderMarginParams param2 = new OrderMarginParams(); 143 | param2.Exchange = Constants.EXCHANGE_NFO; 144 | param2.TradingSymbol = "NIFTY21JUL15000PE"; 145 | param.TransactionType = Constants.TRANSACTION_TYPE_BUY; 146 | param2.Quantity = 75; 147 | param2.Price = 300; 148 | param2.Product = Constants.PRODUCT_MIS; 149 | param2.OrderType = Constants.ORDER_TYPE_LIMIT; 150 | 151 | List margins = kite.GetOrderMargins(new List() { param, param2 }, Mode: Constants.MARGIN_MODE_COMPACT); 152 | 153 | Assert.AreEqual(margins[0].Total, (decimal)30.2280825); 154 | Assert.AreEqual(margins[0].SPAN, (decimal)0); 155 | } 156 | 157 | [TestMethod] 158 | public void TestBasketMargins() 159 | { 160 | string json = File.ReadAllText(@"responses/basket_margins.json", Encoding.UTF8); 161 | ms.SetResponse("application/json", json); 162 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 163 | 164 | OrderMarginParams param = new OrderMarginParams(); 165 | param.Exchange = Constants.EXCHANGE_NFO; 166 | param.TradingSymbol = "ASHOKLEY21JULFUT"; 167 | param.TransactionType = Constants.TRANSACTION_TYPE_SELL; 168 | param.Quantity = 1; 169 | param.Price = 64.0000m; 170 | param.OrderType = Constants.ORDER_TYPE_MARKET; 171 | param.Product = Constants.PRODUCT_MIS; 172 | 173 | OrderMarginParams param2 = new OrderMarginParams(); 174 | param2.Exchange = Constants.EXCHANGE_NFO; 175 | param2.TradingSymbol = "NIFTY21JUL15000PE"; 176 | param.TransactionType = Constants.TRANSACTION_TYPE_BUY; 177 | param2.Quantity = 75; 178 | param2.Price = 300; 179 | param2.Product = Constants.PRODUCT_MIS; 180 | param2.OrderType = Constants.ORDER_TYPE_LIMIT; 181 | 182 | BasketMargin margins = kite.GetBasketMargins(new List() { param, param2 }); 183 | 184 | Assert.AreEqual(margins.Final.Total, (decimal)22530.221345); 185 | Assert.AreEqual(margins.Final.SPAN, (decimal)26.9577); 186 | } 187 | 188 | [TestMethod] 189 | public void TestBasketMarginsCompact() 190 | { 191 | string json = File.ReadAllText(@"responses/basket_margins_compact.json", Encoding.UTF8); 192 | ms.SetResponse("application/json", json); 193 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 194 | 195 | OrderMarginParams param = new OrderMarginParams(); 196 | param.Exchange = Constants.EXCHANGE_NFO; 197 | param.TradingSymbol = "ASHOKLEY21JULFUT"; 198 | param.TransactionType = Constants.TRANSACTION_TYPE_SELL; 199 | param.Quantity = 1; 200 | param.Price = 64.0000m; 201 | param.OrderType = Constants.ORDER_TYPE_MARKET; 202 | param.Product = Constants.PRODUCT_MIS; 203 | 204 | OrderMarginParams param2 = new OrderMarginParams(); 205 | param2.Exchange = Constants.EXCHANGE_NFO; 206 | param2.TradingSymbol = "NIFTY21JUL15000PE"; 207 | param.TransactionType = Constants.TRANSACTION_TYPE_BUY; 208 | param2.Quantity = 75; 209 | param2.Price = 300; 210 | param2.Product = Constants.PRODUCT_MIS; 211 | param2.OrderType = Constants.ORDER_TYPE_LIMIT; 212 | 213 | BasketMargin margins = kite.GetBasketMargins(new List() { param, param2 }, Mode: Constants.MARGIN_MODE_COMPACT); 214 | 215 | Assert.AreEqual(margins.Final.Total, (decimal)22530.2280825); 216 | Assert.AreEqual(margins.Final.SPAN, (decimal)0); 217 | } 218 | 219 | [TestMethod] 220 | public void TestEquityMargins() 221 | { 222 | string json = File.ReadAllText(@"responses/equity_margins.json", Encoding.UTF8); 223 | ms.SetResponse("application/json", json); 224 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 225 | UserMargin margin = kite.GetMargins("equity"); 226 | 227 | Assert.AreEqual(margin.Net, (decimal)1812.3535); 228 | } 229 | 230 | [TestMethod] 231 | public void TestCommodityMargins() 232 | { 233 | string json = File.ReadAllText(@"responses/equity_margins.json", Encoding.UTF8); 234 | ms.SetResponse("application/json", json); 235 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 236 | UserMargin margin = kite.GetMargins("commodity"); 237 | 238 | Assert.AreEqual(margin.Net, (decimal)1812.3535); 239 | } 240 | 241 | [TestMethod] 242 | public void TestOHLC() 243 | { 244 | string json = File.ReadAllText(@"responses/ohlc.json", Encoding.UTF8); 245 | ms.SetResponse("application/json", json); 246 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 247 | Dictionary ohlcs = kite.GetOHLC(new string[] { "408065", "NSE:INFY" }); 248 | 249 | Assert.AreEqual(ohlcs["408065"].LastPrice, (decimal)966.8); 250 | } 251 | 252 | [TestMethod] 253 | public void TestLTP() 254 | { 255 | string json = File.ReadAllText(@"responses/ltp.json", Encoding.UTF8); 256 | ms.SetResponse("application/json", json); 257 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 258 | Dictionary ltps = kite.GetLTP(new string[] { "NSE:INFY" }); 259 | 260 | Assert.AreEqual(ltps["NSE:INFY"].LastPrice, (decimal)989.2); 261 | } 262 | 263 | [TestMethod] 264 | public void TestQuote() 265 | { 266 | string json = File.ReadAllText(@"responses/quote.json", Encoding.UTF8); 267 | ms.SetResponse("application/json", json); 268 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 269 | Dictionary quotes = kite.GetQuote(new string[] { "NSE:ASHOKLEY", "NSE:NIFTY 50" }); 270 | 271 | Assert.AreEqual(quotes["NSE:ASHOKLEY"].LastPrice, (decimal)76.6); 272 | Assert.AreEqual(quotes["NSE:NIFTY 50"].LowerCircuitLimit, 0); 273 | } 274 | 275 | [TestMethod] 276 | public void TestOrders() 277 | { 278 | string json = File.ReadAllText(@"responses/orders.json", Encoding.UTF8); 279 | ms.SetResponse("application/json", json); 280 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 281 | List orders = kite.GetOrders(); 282 | 283 | Assert.AreEqual(orders[0].Price, 72); 284 | 285 | Assert.AreEqual(orders[2].Tag, "connect test order2"); 286 | Assert.AreEqual(orders[2].Tags[1], "XXXXX"); 287 | 288 | Assert.AreEqual(orders[3].ValidityTTL, 2); 289 | 290 | Assert.AreEqual(orders[3].Meta["iceberg"]["legs"], 5); 291 | 292 | Assert.AreEqual(orders[0].AuctionNumber, 10); 293 | } 294 | 295 | [TestMethod] 296 | public void TestGTTs() 297 | { 298 | string json = File.ReadAllText(@"responses/gtt_get_orders.json", Encoding.UTF8); 299 | ms.SetResponse("application/json", json); 300 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 301 | List gtts = kite.GetGTTs(); 302 | 303 | Assert.AreEqual(gtts[0].Id, 105099); 304 | Assert.AreEqual(gtts[0].Condition?.TriggerValues[0], 102m); 305 | Assert.AreEqual(gtts[0].Condition?.TriggerValues[1], 103.7m); 306 | 307 | } 308 | 309 | [TestMethod] 310 | public void TestGTT() 311 | { 312 | string json = File.ReadAllText(@"responses/gtt_get_order.json", Encoding.UTF8); 313 | ms.SetResponse("application/json", json); 314 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 315 | GTT gtt = kite.GetGTT(123); 316 | 317 | Assert.AreEqual(gtt.Id, 123); 318 | } 319 | 320 | [TestMethod] 321 | public void TestOrderInfo() 322 | { 323 | string json = File.ReadAllText(@"responses/orderinfo.json", Encoding.UTF8); 324 | ms.SetResponse("application/json", json); 325 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 326 | List orderhistory = kite.GetOrderHistory("171124000819854"); 327 | 328 | Assert.AreEqual(orderhistory[0].PendingQuantity, 100); 329 | } 330 | 331 | [TestMethod] 332 | public void TestInstruments() 333 | { 334 | string csv = File.ReadAllText(@"responses/instruments_all.csv", Encoding.UTF8); 335 | ms.SetResponse("text/csv", csv); 336 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 337 | List instruments = kite.GetInstruments(); 338 | 339 | Assert.AreEqual(instruments[0].InstrumentToken, (uint)3813889); 340 | Assert.AreEqual(instruments[0].LastPrice, 10.01m); 341 | Assert.AreEqual(instruments[0].Strike, 13.14m); 342 | } 343 | 344 | [TestMethod] 345 | public void TestSegmentInstruments() 346 | { 347 | string csv = File.ReadAllText(@"responses/instruments_nse.csv", Encoding.UTF8); 348 | ms.SetResponse("text/csv", csv); 349 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 350 | List instruments = kite.GetInstruments(Constants.EXCHANGE_NSE); 351 | 352 | Assert.AreEqual(instruments[0].InstrumentToken, (uint)3813889); 353 | } 354 | 355 | [TestMethod] 356 | public void TestTrades() 357 | { 358 | string json = File.ReadAllText(@"responses/trades.json", Encoding.UTF8); 359 | ms.SetResponse("application/json", json); 360 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 361 | List trades = kite.GetOrderTrades("151220000000000"); 362 | 363 | Assert.AreEqual(trades[0].TradeId, "159918"); 364 | } 365 | 366 | [TestMethod] 367 | public void TestMFSIPs() 368 | { 369 | string json = File.ReadAllText(@"responses/mf_sips.json", Encoding.UTF8); 370 | ms.SetResponse("application/json", json); 371 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 372 | List sips = kite.GetMFSIPs(); 373 | 374 | Assert.AreEqual(sips[0].SIPId, "1234"); 375 | } 376 | 377 | [TestMethod] 378 | public void TestMFSIP() 379 | { 380 | string json = File.ReadAllText(@"responses/mf_sip.json", Encoding.UTF8); 381 | ms.SetResponse("application/json", json); 382 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 383 | MFSIP sip = kite.GetMFSIPs("1234"); 384 | 385 | Assert.AreEqual(sip.SIPId, "1234"); 386 | } 387 | 388 | [TestMethod] 389 | public void TestMFOrders() 390 | { 391 | string json = File.ReadAllText(@"responses/mf_orders.json", Encoding.UTF8); 392 | ms.SetResponse("application/json", json); 393 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 394 | List orders = kite.GetMFOrders(); 395 | 396 | Assert.AreEqual(orders[0].OrderId, "123123"); 397 | } 398 | 399 | [TestMethod] 400 | public void TestMFOrder() 401 | { 402 | string json = File.ReadAllText(@"responses/mf_order.json", Encoding.UTF8); 403 | ms.SetResponse("application/json", json); 404 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 405 | MFOrder order = kite.GetMFOrders("123123"); 406 | 407 | Assert.AreEqual(order.OrderId, "123123"); 408 | } 409 | 410 | [TestMethod] 411 | public void TestMFHoldings() 412 | { 413 | string json = File.ReadAllText(@"responses/mf_holdings.json", Encoding.UTF8); 414 | ms.SetResponse("application/json", json); 415 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 416 | List holdings = kite.GetMFHoldings(); 417 | 418 | Assert.AreEqual(holdings[0].Folio, "123123/123"); 419 | } 420 | 421 | [TestMethod] 422 | public void TestMFInstruments() 423 | { 424 | string csv = File.ReadAllText(@"responses/mf_instruments.csv", Encoding.UTF8); 425 | ms.SetResponse("text/csv", csv); 426 | Kite kite = new Kite("apikey", Root: "http://localhost:8080"); 427 | List instruments = kite.GetMFInstruments(); 428 | 429 | Assert.AreEqual(instruments[0].TradingSymbol, "INF209K01157"); 430 | Assert.AreEqual(instruments[0].MinimumPurchaseAmount, 1234.0m); 431 | Assert.AreEqual(instruments[0].PurchaseAmountMultiplier, 13.14m); 432 | } 433 | } 434 | } 435 | -------------------------------------------------------------------------------- /KiteConnectSample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using KiteConnect; 3 | using System.Collections.Generic; 4 | 5 | namespace KiteConnectSample 6 | { 7 | class Program 8 | { 9 | // instances of Kite and Ticker 10 | static Ticker ticker; 11 | static Kite kite; 12 | 13 | // Initialize key and secret of your app 14 | static string MyAPIKey = "abcdefghijklmnopqrstuvwxyz"; 15 | static string MySecret = "abcdefghijklmnopqrstuvwxyz"; 16 | static string MyUserId = "ZR0000"; 17 | 18 | // persist these data in settings or db or file 19 | static string MyPublicToken = "abcdefghijklmnopqrstuvwxyz"; 20 | static string MyAccessToken = "abcdefghijklmnopqrstuvwxyz"; 21 | 22 | static void Main(string[] args) 23 | { 24 | kite = new Kite(MyAPIKey, Debug: true); 25 | 26 | // For handling 403 errors 27 | 28 | kite.SetSessionExpiryHook(OnTokenExpire); 29 | 30 | // Initializes the login flow 31 | 32 | try 33 | { 34 | initSession(); 35 | } 36 | catch (Exception e) 37 | { 38 | // Cannot continue without proper authentication 39 | Console.WriteLine(e.Message); 40 | Console.ReadKey(); 41 | Environment.Exit(0); 42 | } 43 | 44 | kite.SetAccessToken(MyAccessToken); 45 | 46 | // Initialize ticker 47 | 48 | initTicker(); 49 | 50 | // Get all GTTs 51 | 52 | List gtts = kite.GetGTTs(); 53 | Console.WriteLine(Utils.JsonSerialize(gtts[0])); 54 | 55 | // Get GTT by Id 56 | 57 | GTT gtt = kite.GetGTT(99691); 58 | Console.WriteLine(Utils.JsonSerialize(gtt)); 59 | 60 | // Cacncel GTT by Id 61 | 62 | var gttCancelResponse = kite.CancelGTT(1582); 63 | Console.WriteLine(Utils.JsonSerialize(gttCancelResponse)); 64 | 65 | // Place GTT 66 | 67 | GTTParams gttParams = new GTTParams(); 68 | gttParams.TriggerType = Constants.GTT_TRIGGER_OCO; 69 | gttParams.Exchange = "NSE"; 70 | gttParams.TradingSymbol = "SBIN"; 71 | gttParams.LastPrice = 288.9m; 72 | 73 | List triggerPrices = new List(); 74 | triggerPrices.Add(260m); 75 | triggerPrices.Add(320m); 76 | gttParams.TriggerPrices = triggerPrices; 77 | 78 | // Only sell is allowed for OCO or two-leg orders. 79 | // Single leg orders can be buy or sell order. 80 | // Passing a last price is mandatory. 81 | // A stop-loss order must have trigger and price below last price and target order must have trigger and price above last price. 82 | // Only limit order type and CNC product type is allowed for now. 83 | 84 | GTTOrderParams order1Params = new GTTOrderParams(); 85 | order1Params.OrderType = Constants.ORDER_TYPE_LIMIT; 86 | order1Params.Price = 250m; 87 | order1Params.Product = Constants.PRODUCT_CNC; 88 | order1Params.TransactionType = Constants.TRANSACTION_TYPE_SELL; 89 | order1Params.Quantity = 0; 90 | 91 | GTTOrderParams order2Params = new GTTOrderParams(); 92 | order2Params.OrderType = Constants.ORDER_TYPE_LIMIT; 93 | order2Params.Price = 320m; 94 | order2Params.Product = Constants.PRODUCT_CNC; 95 | order2Params.TransactionType = Constants.TRANSACTION_TYPE_SELL; 96 | order2Params.Quantity = 1; 97 | 98 | // Target or upper trigger 99 | List ordersList = new List(); 100 | ordersList.Add(order1Params); 101 | ordersList.Add(order2Params); 102 | gttParams.Orders = ordersList; 103 | 104 | var placeGTTResponse = kite.PlaceGTT(gttParams); 105 | Console.WriteLine(Utils.JsonSerialize(placeGTTResponse)); 106 | 107 | var modifyGTTResponse = kite.ModifyGTT(407301, gttParams); 108 | Console.WriteLine(Utils.JsonSerialize(modifyGTTResponse)); 109 | 110 | // Positions 111 | 112 | PositionResponse positions = kite.GetPositions(); 113 | Console.WriteLine(Utils.JsonSerialize(positions.Net[0])); 114 | 115 | kite.ConvertPosition( 116 | Exchange: Constants.EXCHANGE_NSE, 117 | TradingSymbol: "ASHOKLEY", 118 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 119 | PositionType: Constants.POSITION_DAY, 120 | Quantity: 1, 121 | OldProduct: Constants.PRODUCT_MIS, 122 | NewProduct: Constants.PRODUCT_CNC 123 | ); 124 | 125 | // Holdings 126 | 127 | List holdings = kite.GetHoldings(); 128 | Console.WriteLine(Utils.JsonSerialize(holdings[0])); 129 | 130 | // Instruments 131 | 132 | List instruments = kite.GetInstruments(); 133 | Console.WriteLine(Utils.JsonSerialize(instruments[0])); 134 | 135 | // Get quotes of upto 200 scrips 136 | 137 | Dictionary quotes = kite.GetQuote(InstrumentId: new string[] { "NSE:INFY", "NSE:ASHOKLEY" }); 138 | Console.WriteLine(Utils.JsonSerialize(quotes)); 139 | 140 | // Get OHLC and LTP of upto 200 scrips 141 | 142 | Dictionary ohlcs = kite.GetOHLC(InstrumentId: new string[] { "NSE:INFY", "NSE:ASHOKLEY" }); 143 | Console.WriteLine(Utils.JsonSerialize(ohlcs)); 144 | 145 | // Get LTP of upto 200 scrips 146 | 147 | Dictionary ltps = kite.GetLTP(InstrumentId: new string[] { "NSE:INFY", "NSE:ASHOKLEY" }); 148 | Console.WriteLine(Utils.JsonSerialize(ltps)); 149 | 150 | // Trigger Range 151 | 152 | Dictionary triggerRange = kite.GetTriggerRange( 153 | InstrumentId: new string[] { "NSE:ASHOKLEY" }, 154 | TrasactionType: Constants.TRANSACTION_TYPE_BUY 155 | ); 156 | Console.WriteLine(Utils.JsonSerialize(triggerRange)); 157 | 158 | // Get all orders 159 | 160 | List orders = kite.GetOrders(); 161 | Console.WriteLine(Utils.JsonSerialize(orders[0])); 162 | 163 | // Get order by id 164 | 165 | List orderinfo = kite.GetOrderHistory("1234"); 166 | Console.WriteLine(Utils.JsonSerialize(orderinfo[0])); 167 | 168 | // Place sell order 169 | 170 | Dictionary response = kite.PlaceOrder( 171 | Exchange: Constants.EXCHANGE_CDS, 172 | TradingSymbol: "USDINR17AUGFUT", 173 | TransactionType: Constants.TRANSACTION_TYPE_SELL, 174 | Quantity: 1, 175 | Price: 64.0000m, 176 | OrderType: Constants.ORDER_TYPE_MARKET, 177 | Product: Constants.PRODUCT_MIS 178 | ); 179 | Console.WriteLine("Order Id: " + response["data"]["order_id"]); 180 | 181 | // Place buy order 182 | 183 | kite.PlaceOrder( 184 | Exchange: Constants.EXCHANGE_CDS, 185 | TradingSymbol: "USDINR17AUGFUT", 186 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 187 | Quantity: 1, 188 | Price: 63.9000m, 189 | OrderType: Constants.ORDER_TYPE_LIMIT, 190 | Product: Constants.PRODUCT_MIS 191 | ); 192 | 193 | // Cancel order by id 194 | 195 | kite.CancelOrder("1234"); 196 | 197 | //BO LIMIT order placing 198 | 199 | kite.PlaceOrder( 200 | Exchange: Constants.EXCHANGE_NSE, 201 | TradingSymbol: "ASHOKLEY", 202 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 203 | Quantity: 1, 204 | Price: 115, 205 | Product: Constants.PRODUCT_MIS, 206 | OrderType: Constants.ORDER_TYPE_LIMIT, 207 | Validity: Constants.VALIDITY_DAY, 208 | SquareOffValue: 2, 209 | StoplossValue: 2, 210 | Variety: Constants.VARIETY_BO 211 | ); 212 | 213 | // BO LIMIT exiting 214 | 215 | kite.CancelOrder( 216 | OrderId: "1234", 217 | Variety: Constants.VARIETY_BO, 218 | ParentOrderId: "5678" 219 | ); 220 | 221 | // BO SL order placing 222 | 223 | kite.PlaceOrder( 224 | Exchange: Constants.EXCHANGE_NSE, 225 | TradingSymbol: "ASHOKLEY", 226 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 227 | Quantity: 1, 228 | Price: 117, 229 | Product: Constants.PRODUCT_MIS, 230 | OrderType: Constants.ORDER_TYPE_SL, 231 | Validity: Constants.VALIDITY_DAY, 232 | SquareOffValue: 2, 233 | StoplossValue: 2, 234 | TriggerPrice: 117.5m, 235 | Variety: Constants.VARIETY_BO 236 | ); 237 | 238 | // BO SL exiting 239 | 240 | kite.CancelOrder( 241 | OrderId: "1234", 242 | Variety: Constants.VARIETY_BO, 243 | ParentOrderId: "5678" 244 | ); 245 | 246 | // CO LIMIT order placing 247 | 248 | kite.PlaceOrder( 249 | Exchange: Constants.EXCHANGE_NSE, 250 | TradingSymbol: "ASHOKLEY", 251 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 252 | Quantity: 1, 253 | Price: 115.5m, 254 | Product: Constants.PRODUCT_MIS, 255 | OrderType: Constants.ORDER_TYPE_LIMIT, 256 | Validity: Constants.VALIDITY_DAY, 257 | TriggerPrice: 116.5m, 258 | Variety: Constants.VARIETY_CO 259 | ); 260 | 261 | // CO LIMIT exiting 262 | 263 | kite.CancelOrder( 264 | OrderId: "1234", 265 | Variety: Constants.VARIETY_BO, 266 | ParentOrderId: "5678" 267 | ); 268 | 269 | // CO MARKET order placing 270 | 271 | kite.PlaceOrder( 272 | Exchange: Constants.EXCHANGE_NSE, 273 | TradingSymbol: "ASHOKLEY", 274 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 275 | Quantity: 1, 276 | Product: Constants.PRODUCT_MIS, 277 | OrderType: Constants.ORDER_TYPE_MARKET, 278 | Validity: Constants.VALIDITY_DAY, 279 | TriggerPrice: 116.5m, 280 | Variety: Constants.VARIETY_CO 281 | ); 282 | 283 | // CO MARKET exiting 284 | 285 | kite.CancelOrder( 286 | OrderId: "1234", 287 | Variety: Constants.VARIETY_BO, 288 | ParentOrderId: "5678" 289 | ); 290 | 291 | // Place order with TTL validity 292 | kite.PlaceOrder( 293 | Exchange: Constants.EXCHANGE_NSE, 294 | TradingSymbol: "INFY", 295 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 296 | Quantity: 1, 297 | Price: 1500.0m, 298 | OrderType: Constants.ORDER_TYPE_LIMIT, 299 | Product: Constants.PRODUCT_MIS, 300 | Validity: Constants.VALIDITY_TTL, 301 | ValidityTTL: 5 302 | ); 303 | 304 | // Place an Iceberg order 305 | kite.PlaceOrder( 306 | Exchange: Constants.EXCHANGE_NSE, 307 | TradingSymbol: "INFY", 308 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 309 | Quantity: 10, 310 | Price: 1500.0m, 311 | OrderType: Constants.ORDER_TYPE_LIMIT, 312 | Product: Constants.PRODUCT_MIS, 313 | Variety: Constants.VARIETY_ICEBERG, 314 | IcebergLegs: 2, 315 | IcebergQuantity: 5 316 | ); 317 | 318 | // Trades 319 | 320 | List trades = kite.GetOrderTrades("1234"); 321 | Console.WriteLine(Utils.JsonSerialize(trades[0])); 322 | 323 | // Margins 324 | 325 | UserMargin commodityMargins = kite.GetMargins(Constants.MARGIN_COMMODITY); 326 | UserMargin equityMargins = kite.GetMargins(Constants.MARGIN_EQUITY); 327 | 328 | // Order margins 329 | 330 | OrderMarginParams orderParam = new OrderMarginParams(); 331 | orderParam.Exchange = Constants.EXCHANGE_NFO; 332 | orderParam.TradingSymbol = "ASHOKLEY21JULFUT"; 333 | orderParam.TransactionType = Constants.TRANSACTION_TYPE_SELL; 334 | orderParam.Quantity = 1; 335 | orderParam.Price = 64.0000m; 336 | orderParam.OrderType = Constants.ORDER_TYPE_MARKET; 337 | orderParam.Product = Constants.PRODUCT_MIS; 338 | 339 | List margins = kite.GetOrderMargins(new List() { orderParam }); 340 | 341 | // Basket margins 342 | 343 | OrderMarginParams basketParam = new OrderMarginParams(); 344 | basketParam.Exchange = Constants.EXCHANGE_NFO; 345 | basketParam.TradingSymbol = "NIFTY21JUL15000PE"; 346 | basketParam.TransactionType = Constants.TRANSACTION_TYPE_BUY; 347 | basketParam.Quantity = 75; 348 | basketParam.Price = 300; 349 | basketParam.Product = Constants.PRODUCT_MIS; 350 | basketParam.OrderType = Constants.ORDER_TYPE_LIMIT; 351 | 352 | BasketMargin basketMargins = kite.GetBasketMargins(new List() { basketParam }, ConsiderPositions: true); 353 | 354 | // Virtual contract notes 355 | 356 | ContractNoteParams contractNoteParam = new ContractNoteParams(); 357 | contractNoteParam.OrderID = "230821101633675"; 358 | contractNoteParam.Quantity = 1; 359 | contractNoteParam.AveragePrice = 99.7m; 360 | contractNoteParam.Exchange = "NSE"; 361 | contractNoteParam.TradingSymbol = "BHEL"; 362 | contractNoteParam.TransactionType = Constants.TRANSACTION_TYPE_BUY; 363 | contractNoteParam.Variety = Constants.VARIETY_REGULAR; 364 | contractNoteParam.OrderType = Constants.ORDER_TYPE_LIMIT; 365 | contractNoteParam.Product = Constants.PRODUCT_MIS; 366 | List contractNotes = kite.GetVirtualContractNote(new List() { contractNoteParam }); 367 | Console.WriteLine(Utils.JsonSerialize(contractNotes)); 368 | 369 | // Historical Data With Dates 370 | 371 | List historical = kite.GetHistoricalData( 372 | InstrumentToken: "5633", 373 | FromDate: new DateTime(2016, 1, 1, 12, 50, 0), // 2016-01-01 12:50:00 AM 374 | ToDate: new DateTime(2016, 1, 1, 13, 10, 0), // 2016-01-01 01:10:00 PM 375 | Interval: Constants.INTERVAL_MINUTE, 376 | Continuous: false 377 | ); 378 | Console.WriteLine(Utils.JsonSerialize(historical[0])); 379 | 380 | // Mutual Funds Instruments 381 | 382 | List mfinstruments = kite.GetMFInstruments(); 383 | Console.WriteLine(Utils.JsonSerialize(mfinstruments[0])); 384 | 385 | // Mutual funds get all orders 386 | 387 | List mforders = kite.GetMFOrders(); 388 | Console.WriteLine(Utils.JsonSerialize(mforders[0])); 389 | 390 | // Mutual funds get order by id 391 | 392 | MFOrder mforder = kite.GetMFOrders(OrderId: "1234"); 393 | Console.WriteLine(Utils.JsonSerialize(mforder)); 394 | 395 | // Mutual funds place order 396 | 397 | kite.PlaceMFOrder( 398 | TradingSymbol: "INF174K01LS2", 399 | TransactionType: Constants.TRANSACTION_TYPE_BUY, 400 | Amount: 20000 401 | ); 402 | 403 | // Mutual funds cancel order by id 404 | 405 | kite.CancelMFOrder(OrderId: "1234"); 406 | 407 | // Mutual Funds get all SIPs 408 | 409 | List mfsips = kite.GetMFSIPs(); 410 | Console.WriteLine(Utils.JsonSerialize(mfsips[0])); 411 | 412 | // Mutual Funds get SIP by id 413 | 414 | MFSIP sip = kite.GetMFSIPs("63429"); 415 | Console.WriteLine(Utils.JsonSerialize(sip)); 416 | 417 | // Mutual Funds place SIP order 418 | 419 | kite.PlaceMFSIP( 420 | TradingSymbol: "INF174K01LS2", 421 | Amount: 1000, 422 | InitialAmount: 5000, 423 | Frequency: "monthly", 424 | InstalmentDay: 1, 425 | Instalments: -1 // -1 means infinite 426 | ); 427 | 428 | // Mutual Funds modify SIP order 429 | 430 | kite.ModifyMFSIP( 431 | SIPId: "1234", 432 | Amount: 1000, 433 | Frequency: "monthly", 434 | InstalmentDay: 1, 435 | Instalments: 10, 436 | Status: "paused" 437 | ); 438 | 439 | kite.CancelMFSIP(SIPId: "1234"); 440 | 441 | // Mutual Funds Holdings 442 | 443 | List mfholdings = kite.GetMFHoldings(); 444 | Console.WriteLine(Utils.JsonSerialize(mfholdings[0])); 445 | 446 | Console.ReadKey(); 447 | 448 | // Disconnect from ticker 449 | 450 | ticker.Close(); 451 | } 452 | 453 | private static void initSession() 454 | { 455 | Console.WriteLine("Goto " + kite.GetLoginURL()); 456 | Console.WriteLine("Enter request token: "); 457 | string requestToken = Console.ReadLine(); 458 | User user = kite.GenerateSession(requestToken, MySecret); 459 | 460 | Console.WriteLine(Utils.JsonSerialize(user)); 461 | 462 | MyAccessToken = user.AccessToken; 463 | MyPublicToken = user.PublicToken; 464 | } 465 | 466 | private static void initTicker() 467 | { 468 | ticker = new Ticker(MyAPIKey, MyAccessToken); 469 | 470 | ticker.OnTick += OnTick; 471 | ticker.OnReconnect += OnReconnect; 472 | ticker.OnNoReconnect += OnNoReconnect; 473 | ticker.OnError += OnError; 474 | ticker.OnClose += OnClose; 475 | ticker.OnConnect += OnConnect; 476 | ticker.OnOrderUpdate += OnOrderUpdate; 477 | 478 | ticker.EnableReconnect(Interval: 5, Retries: 50); 479 | ticker.Connect(); 480 | 481 | // Subscribing to NIFTY50 and setting mode to LTP 482 | ticker.Subscribe(Tokens: new UInt32[] { 256265 }); 483 | ticker.SetMode(Tokens: new UInt32[] { 256265 }, Mode: Constants.MODE_LTP); 484 | } 485 | 486 | private static void OnTokenExpire() 487 | { 488 | Console.WriteLine("Need to login again"); 489 | } 490 | 491 | private static void OnConnect() 492 | { 493 | Console.WriteLine("Connected ticker"); 494 | } 495 | 496 | private static void OnClose() 497 | { 498 | Console.WriteLine("Closed ticker"); 499 | } 500 | 501 | private static void OnError(string Message) 502 | { 503 | Console.WriteLine("Error: " + Message); 504 | } 505 | 506 | private static void OnNoReconnect() 507 | { 508 | Console.WriteLine("Not reconnecting"); 509 | } 510 | 511 | private static void OnReconnect() 512 | { 513 | Console.WriteLine("Reconnecting"); 514 | } 515 | 516 | private static void OnTick(Tick TickData) 517 | { 518 | Console.WriteLine("Tick " + Utils.JsonSerialize(TickData)); 519 | } 520 | 521 | private static void OnOrderUpdate(Order OrderData) 522 | { 523 | Console.WriteLine("OrderUpdate " + Utils.JsonSerialize(OrderData)); 524 | } 525 | } 526 | } 527 | -------------------------------------------------------------------------------- /KiteConnect/Ticker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.WebSockets; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | namespace KiteConnect 9 | { 10 | /// 11 | /// The WebSocket client for connecting to Kite Connect's streaming quotes service. 12 | /// 13 | public class Ticker 14 | { 15 | // If set to true will print extra debug information 16 | private bool _debug = false; 17 | 18 | // Root domain for ticker. Can be changed with Root parameter in the constructor. 19 | private string _root = "wss://ws.kite.trade/"; 20 | 21 | // Configurations to create ticker connection 22 | private string _apiKey; 23 | private string _accessToken; 24 | private string _socketUrl = ""; 25 | private bool _isReconnect = false; 26 | private int _interval = 5; 27 | private int _retries = 50; 28 | private int _retryCount = 0; 29 | 30 | // A watchdog timer for monitoring the connection of ticker. 31 | System.Timers.Timer _timer; 32 | int _timerTick = 5; 33 | 34 | // Instance of WebSocket class that wraps .Net version 35 | private IWebSocket _ws; 36 | 37 | // Dictionary that keeps instrument_token -> mode data 38 | private Dictionary _subscribedTokens; 39 | 40 | // Delegates for callbacks 41 | 42 | /// 43 | /// Delegate for OnConnect event 44 | /// 45 | public delegate void OnConnectHandler(); 46 | 47 | /// 48 | /// Delegate for OnClose event 49 | /// 50 | public delegate void OnCloseHandler(); 51 | 52 | /// 53 | /// Delegate for OnTick event 54 | /// 55 | /// Tick data 56 | public delegate void OnTickHandler(Tick TickData); 57 | 58 | /// 59 | /// Delegate for OnOrderUpdate event 60 | /// 61 | /// Order data 62 | public delegate void OnOrderUpdateHandler(Order OrderData); 63 | 64 | /// 65 | /// Delegate for OnError event 66 | /// 67 | /// Error message 68 | public delegate void OnErrorHandler(string Message); 69 | 70 | /// 71 | /// Delegate for OnReconnect event 72 | /// 73 | public delegate void OnReconnectHandler(); 74 | 75 | /// 76 | /// Delegate for OnNoReconnect event 77 | /// 78 | public delegate void OnNoReconnectHandler(); 79 | 80 | // Events that can be subscribed 81 | /// 82 | /// Event triggered when ticker is connected 83 | /// 84 | public event OnConnectHandler OnConnect; 85 | 86 | /// 87 | /// Event triggered when ticker is disconnected 88 | /// 89 | public event OnCloseHandler OnClose; 90 | 91 | /// 92 | /// Event triggered when ticker receives a tick 93 | /// 94 | public event OnTickHandler OnTick; 95 | 96 | /// 97 | /// Event triggered when ticker receives an order update 98 | /// 99 | public event OnOrderUpdateHandler OnOrderUpdate; 100 | 101 | /// 102 | /// Event triggered when ticker encounters an error 103 | /// 104 | public event OnErrorHandler OnError; 105 | 106 | /// 107 | /// Event triggered when ticker is reconnected 108 | /// 109 | public event OnReconnectHandler OnReconnect; 110 | 111 | /// 112 | /// Event triggered when ticker is not reconnecting after failure 113 | /// 114 | public event OnNoReconnectHandler OnNoReconnect; 115 | 116 | /// 117 | /// Initialize websocket client instance. 118 | /// 119 | /// API key issued to you 120 | /// Zerodha client id of the authenticated user 121 | /// Token obtained after the login flow in 122 | /// exchange for the `request_token`.Pre-login, this will default to None, 123 | /// but once you have obtained it, you should 124 | /// persist it in a database or session to pass 125 | /// to the Kite Connect class initialisation for subsequent requests. 126 | /// Websocket API end point root. Unless you explicitly 127 | /// want to send API requests to a non-default endpoint, this can be ignored. 128 | /// Enables WebSocket autreconnect in case of network failure/disconnection. 129 | /// Interval (in seconds) between auto reconnection attemptes. Defaults to 5 seconds. 130 | /// Maximum number reconnection attempts. Defaults to 50 attempts. 131 | public Ticker(string APIKey, string AccessToken, string Root = null, bool Reconnect = false, int ReconnectInterval = 5, int ReconnectTries = 50, bool Debug = false, IWebSocket CustomWebSocket = null) 132 | { 133 | _debug = Debug; 134 | _apiKey = APIKey; 135 | _accessToken = AccessToken; 136 | _subscribedTokens = new Dictionary(); 137 | _interval = ReconnectInterval; 138 | _timerTick = ReconnectInterval; 139 | _retries = ReconnectTries; 140 | if (!String.IsNullOrEmpty(Root)) 141 | _root = Root; 142 | _isReconnect = Reconnect; 143 | _socketUrl = _root + String.Format("?api_key={0}&access_token={1}", _apiKey, _accessToken); 144 | 145 | // initialize websocket 146 | if (CustomWebSocket != null) 147 | { 148 | _ws = CustomWebSocket; 149 | } 150 | else 151 | { 152 | _ws = new WebSocket(); 153 | } 154 | 155 | _ws.OnConnect += _onConnect; 156 | _ws.OnData += _onData; 157 | _ws.OnClose += _onClose; 158 | _ws.OnError += _onError; 159 | 160 | // initializing watchdog timer 161 | _timer = new System.Timers.Timer(); 162 | _timer.Elapsed += _onTimerTick; 163 | _timer.Interval = 1000; // checks connection every second 164 | } 165 | 166 | private void _onError(string Message) 167 | { 168 | // pipe the error message from ticker to the events 169 | OnError?.Invoke(Message); 170 | } 171 | 172 | private void _onClose() 173 | { 174 | // stop the timer while normally closing the connection 175 | _timer.Stop(); 176 | OnClose?.Invoke(); 177 | } 178 | 179 | /// 180 | /// Reads 2 byte short int from byte stream 181 | /// 182 | private ushort ReadShort(byte[] b, ref int offset) 183 | { 184 | ushort data = (ushort)(b[offset + 1] + (b[offset] << 8)); 185 | offset += 2; 186 | return data; 187 | } 188 | 189 | /// 190 | /// Reads 4 byte int32 from byte stream 191 | /// 192 | private UInt32 ReadInt(byte[] b, ref int offset) 193 | { 194 | UInt32 data = (UInt32)BitConverter.ToUInt32(new byte[] { b[offset + 3], b[offset + 2], b[offset + 1], b[offset + 0] }, 0); 195 | offset += 4; 196 | return data; 197 | } 198 | 199 | /// 200 | /// Get the divisor to convert price values 201 | /// 202 | private decimal GetDivisor(uint InstrumentToken) 203 | { 204 | uint segment = InstrumentToken & 0xff; 205 | switch (segment) 206 | { 207 | case 3: // CDS 208 | return 10000000.0m; 209 | case 6: // BCD 210 | return 10000.0m; 211 | default: 212 | return 100.0m; 213 | } 214 | } 215 | 216 | /// 217 | /// Reads an ltp mode tick from raw binary data 218 | /// 219 | private Tick ReadLTP(byte[] b, ref int offset) 220 | { 221 | Tick tick = new Tick(); 222 | tick.Mode = Constants.MODE_LTP; 223 | tick.InstrumentToken = ReadInt(b, ref offset); 224 | 225 | decimal divisor = GetDivisor(tick.InstrumentToken); 226 | 227 | tick.Tradable = (tick.InstrumentToken & 0xff) != 9; 228 | tick.LastPrice = ReadInt(b, ref offset) / divisor; 229 | return tick; 230 | } 231 | 232 | /// 233 | /// Reads a index's quote mode tick from raw binary data 234 | /// 235 | private Tick ReadIndexQuote(byte[] b, ref int offset) 236 | { 237 | Tick tick = new Tick(); 238 | tick.Mode = Constants.MODE_QUOTE; 239 | tick.InstrumentToken = ReadInt(b, ref offset); 240 | 241 | decimal divisor = GetDivisor(tick.InstrumentToken); 242 | 243 | tick.Tradable = (tick.InstrumentToken & 0xff) != 9; 244 | tick.LastPrice = ReadInt(b, ref offset) / divisor; 245 | tick.High = ReadInt(b, ref offset) / divisor; 246 | tick.Low = ReadInt(b, ref offset) / divisor; 247 | tick.Open = ReadInt(b, ref offset) / divisor; 248 | tick.Close = ReadInt(b, ref offset) / divisor; 249 | tick.Change = ReadInt(b, ref offset) / divisor; 250 | return tick; 251 | } 252 | 253 | private Tick ReadIndexFull(byte[] b, ref int offset) 254 | { 255 | Tick tick = new Tick(); 256 | tick.Mode = Constants.MODE_FULL; 257 | tick.InstrumentToken = ReadInt(b, ref offset); 258 | 259 | decimal divisor = GetDivisor(tick.InstrumentToken); 260 | 261 | tick.Tradable = (tick.InstrumentToken & 0xff) != 9; 262 | tick.LastPrice = ReadInt(b, ref offset) / divisor; 263 | tick.High = ReadInt(b, ref offset) / divisor; 264 | tick.Low = ReadInt(b, ref offset) / divisor; 265 | tick.Open = ReadInt(b, ref offset) / divisor; 266 | tick.Close = ReadInt(b, ref offset) / divisor; 267 | // ignore this int 268 | ReadInt(b, ref offset); 269 | // calculate the change based on existing values 270 | tick.Change = tick.LastPrice - tick.Close; 271 | uint time = ReadInt(b, ref offset); 272 | tick.Timestamp = Utils.UnixToDateTime(time); 273 | return tick; 274 | } 275 | 276 | /// 277 | /// Reads a quote mode tick from raw binary data 278 | /// 279 | private Tick ReadQuote(byte[] b, ref int offset) 280 | { 281 | Tick tick = new Tick(); 282 | tick.Mode = Constants.MODE_QUOTE; 283 | tick.InstrumentToken = ReadInt(b, ref offset); 284 | 285 | decimal divisor = GetDivisor(tick.InstrumentToken); 286 | 287 | tick.Tradable = (tick.InstrumentToken & 0xff) != 9; 288 | tick.LastPrice = ReadInt(b, ref offset) / divisor; 289 | tick.LastQuantity = ReadInt(b, ref offset); 290 | tick.AveragePrice = ReadInt(b, ref offset) / divisor; 291 | tick.Volume = ReadInt(b, ref offset); 292 | tick.BuyQuantity = ReadInt(b, ref offset); 293 | tick.SellQuantity = ReadInt(b, ref offset); 294 | tick.Open = ReadInt(b, ref offset) / divisor; 295 | tick.High = ReadInt(b, ref offset) / divisor; 296 | tick.Low = ReadInt(b, ref offset) / divisor; 297 | tick.Close = ReadInt(b, ref offset) / divisor; 298 | 299 | return tick; 300 | } 301 | 302 | /// 303 | /// Reads a full mode tick from raw binary data 304 | /// 305 | private Tick ReadFull(byte[] b, ref int offset) 306 | { 307 | Tick tick = new Tick(); 308 | tick.Mode = Constants.MODE_FULL; 309 | tick.InstrumentToken = ReadInt(b, ref offset); 310 | 311 | decimal divisor = GetDivisor(tick.InstrumentToken); 312 | 313 | tick.Tradable = (tick.InstrumentToken & 0xff) != 9; 314 | tick.LastPrice = ReadInt(b, ref offset) / divisor; 315 | tick.LastQuantity = ReadInt(b, ref offset); 316 | tick.AveragePrice = ReadInt(b, ref offset) / divisor; 317 | tick.Volume = ReadInt(b, ref offset); 318 | tick.BuyQuantity = ReadInt(b, ref offset); 319 | tick.SellQuantity = ReadInt(b, ref offset); 320 | tick.Open = ReadInt(b, ref offset) / divisor; 321 | tick.High = ReadInt(b, ref offset) / divisor; 322 | tick.Low = ReadInt(b, ref offset) / divisor; 323 | tick.Close = ReadInt(b, ref offset) / divisor; 324 | 325 | // KiteConnect 3 fields 326 | tick.LastTradeTime = Utils.UnixToDateTime(ReadInt(b, ref offset)); 327 | tick.OI = ReadInt(b, ref offset); 328 | tick.OIDayHigh = ReadInt(b, ref offset); 329 | tick.OIDayLow = ReadInt(b, ref offset); 330 | tick.Timestamp = Utils.UnixToDateTime(ReadInt(b, ref offset)); 331 | 332 | 333 | tick.Bids = new DepthItem[5]; 334 | for (int i = 0; i < 5; i++) 335 | { 336 | tick.Bids[i].Quantity = ReadInt(b, ref offset); 337 | tick.Bids[i].Price = ReadInt(b, ref offset) / divisor; 338 | tick.Bids[i].Orders = ReadShort(b, ref offset); 339 | offset += 2; 340 | } 341 | 342 | tick.Offers = new DepthItem[5]; 343 | for (int i = 0; i < 5; i++) 344 | { 345 | tick.Offers[i].Quantity = ReadInt(b, ref offset); 346 | tick.Offers[i].Price = ReadInt(b, ref offset) / divisor; 347 | tick.Offers[i].Orders = ReadShort(b, ref offset); 348 | offset += 2; 349 | } 350 | return tick; 351 | } 352 | 353 | private void _onData(byte[] Data, int Count, string MessageType) 354 | { 355 | _timerTick = _interval; 356 | if (MessageType == "Binary") 357 | { 358 | if (Count == 1) 359 | { 360 | if (_debug) Console.WriteLine(DateTime.Now.ToLocalTime() + " Heartbeat"); 361 | } 362 | else 363 | { 364 | int offset = 0; 365 | ushort count = ReadShort(Data, ref offset); //number of packets 366 | if (_debug) Console.WriteLine("No of packets: " + count); 367 | if (_debug) Console.WriteLine("No of bytes: " + Count); 368 | 369 | for (ushort i = 0; i < count; i++) 370 | { 371 | ushort length = ReadShort(Data, ref offset); // length of the packet 372 | if (_debug) Console.WriteLine("Packet Length " + length); 373 | Tick tick = new Tick(); 374 | if (length == 8) // ltp 375 | tick = ReadLTP(Data, ref offset); 376 | else if (length == 28) // index quote 377 | tick = ReadIndexQuote(Data, ref offset); 378 | else if (length == 32) // index quote 379 | tick = ReadIndexFull(Data, ref offset); 380 | else if (length == 44) // quote 381 | tick = ReadQuote(Data, ref offset); 382 | else if (length == 184) // full with marketdepth and timestamp 383 | tick = ReadFull(Data, ref offset); 384 | // If the number of bytes got from stream is less that that is required 385 | // data is invalid. This will skip that wrong tick 386 | if (tick.InstrumentToken != 0 && IsConnected && offset <= Count) 387 | { 388 | OnTick(tick); 389 | } 390 | } 391 | } 392 | } 393 | else if (MessageType == "Text") 394 | { 395 | string message = Encoding.UTF8.GetString(Data.Take(Count).ToArray()); 396 | if (_debug) Console.WriteLine("WebSocket Message: " + message); 397 | 398 | Dictionary messageDict = Utils.JsonDeserialize(message); 399 | if (messageDict["type"] == "order") 400 | { 401 | OnOrderUpdate?.Invoke(new Order(messageDict["data"])); 402 | } 403 | else if (messageDict["type"] == "error") 404 | { 405 | OnError?.Invoke(messageDict["data"]); 406 | } 407 | } 408 | else if (MessageType == "Close") 409 | { 410 | Close(); 411 | } 412 | 413 | } 414 | 415 | private void _onTimerTick(object sender, System.Timers.ElapsedEventArgs e) 416 | { 417 | // For each timer tick count is reduced. If count goes below 0 then reconnection is triggered. 418 | _timerTick--; 419 | if (_timerTick < 0) 420 | { 421 | _timer.Stop(); 422 | if (_isReconnect) 423 | Reconnect(); 424 | } 425 | if (_debug) Console.WriteLine(_timerTick); 426 | } 427 | 428 | private void _onConnect() 429 | { 430 | // Reset timer and retry counts and resubscribe to tokens. 431 | _retryCount = 0; 432 | _timerTick = _interval; 433 | _timer.Start(); 434 | if (_subscribedTokens.Count > 0) 435 | ReSubscribe(); 436 | OnConnect?.Invoke(); 437 | } 438 | 439 | /// 440 | /// Tells whether ticker is connected to server not. 441 | /// 442 | public bool IsConnected 443 | { 444 | get { return _ws.IsConnected(); } 445 | } 446 | 447 | /// 448 | /// Start a WebSocket connection 449 | /// 450 | public void Connect() 451 | { 452 | _timerTick = _interval; 453 | _timer.Start(); 454 | if (!IsConnected) 455 | { 456 | _ws.Connect(_socketUrl, new Dictionary() { ["X-Kite-Version"] = "3" }); 457 | } 458 | } 459 | 460 | /// 461 | /// Close a WebSocket connection 462 | /// 463 | public void Close() 464 | { 465 | _timer.Stop(); 466 | _ws.Close(); 467 | } 468 | 469 | /// 470 | /// Reconnect WebSocket connection in case of failures 471 | /// 472 | private void Reconnect() 473 | { 474 | if (IsConnected) 475 | _ws.Close(true); 476 | 477 | if (_retryCount > _retries) 478 | { 479 | _ws.Close(true); 480 | DisableReconnect(); 481 | OnNoReconnect?.Invoke(); 482 | } 483 | else 484 | { 485 | OnReconnect?.Invoke(); 486 | _retryCount += 1; 487 | _ws.Close(true); 488 | Connect(); 489 | _timerTick = (int)Math.Min(Math.Pow(2, _retryCount) * _interval, 60); 490 | if (_debug) Console.WriteLine("New interval " + _timerTick); 491 | _timer.Start(); 492 | } 493 | } 494 | 495 | /// 496 | /// Subscribe to a list of instrument_tokens. 497 | /// 498 | /// List of instrument instrument_tokens to subscribe 499 | public void Subscribe(UInt32[] Tokens) 500 | { 501 | if (Tokens.Length == 0) return; 502 | 503 | string msg = "{\"a\":\"subscribe\",\"v\":[" + String.Join(",", Tokens) + "]}"; 504 | if (_debug) Console.WriteLine(msg.Length); 505 | 506 | if (IsConnected) 507 | _ws.Send(msg); 508 | foreach (UInt32 token in Tokens) 509 | if (!_subscribedTokens.ContainsKey(token)) 510 | _subscribedTokens.Add(token, "quote"); 511 | } 512 | 513 | /// 514 | /// Unsubscribe the given list of instrument_tokens. 515 | /// 516 | /// List of instrument instrument_tokens to unsubscribe 517 | public void UnSubscribe(UInt32[] Tokens) 518 | { 519 | if (Tokens.Length == 0) return; 520 | 521 | string msg = "{\"a\":\"unsubscribe\",\"v\":[" + String.Join(",", Tokens) + "]}"; 522 | if (_debug) Console.WriteLine(msg); 523 | 524 | if (IsConnected) 525 | _ws.Send(msg); 526 | foreach (UInt32 token in Tokens) 527 | if (_subscribedTokens.ContainsKey(token)) 528 | _subscribedTokens.Remove(token); 529 | } 530 | 531 | /// 532 | /// Set streaming mode for the given list of tokens. 533 | /// 534 | /// List of instrument tokens on which the mode should be applied 535 | /// Mode to set. It can be one of the following: ltp, quote, full. 536 | public void SetMode(UInt32[] Tokens, string Mode) 537 | { 538 | if (Tokens.Length == 0) return; 539 | 540 | string msg = "{\"a\":\"mode\",\"v\":[\"" + Mode + "\", [" + String.Join(",", Tokens) + "]]}"; 541 | if (_debug) Console.WriteLine(msg); 542 | 543 | if (IsConnected) 544 | _ws.Send(msg); 545 | foreach (UInt32 token in Tokens) 546 | if (_subscribedTokens.ContainsKey(token)) 547 | _subscribedTokens[token] = Mode; 548 | } 549 | 550 | /// 551 | /// Resubscribe to all currently subscribed tokens. Used to restore all the subscribed tokens after successful reconnection. 552 | /// 553 | public void ReSubscribe() 554 | { 555 | if (_debug) Console.WriteLine("Resubscribing"); 556 | UInt32[] all_tokens = _subscribedTokens.Keys.ToArray(); 557 | 558 | UInt32[] ltp_tokens = all_tokens.Where(key => _subscribedTokens[key] == "ltp").ToArray(); 559 | UInt32[] quote_tokens = all_tokens.Where(key => _subscribedTokens[key] == "quote").ToArray(); 560 | UInt32[] full_tokens = all_tokens.Where(key => _subscribedTokens[key] == "full").ToArray(); 561 | 562 | UnSubscribe(all_tokens); 563 | Subscribe(all_tokens); 564 | 565 | SetMode(ltp_tokens, "ltp"); 566 | SetMode(quote_tokens, "quote"); 567 | SetMode(full_tokens, "full"); 568 | } 569 | 570 | /// 571 | /// Enable WebSocket autreconnect in case of network failure/disconnection. 572 | /// 573 | /// Interval between auto reconnection attemptes. `onReconnect` callback is triggered when reconnection is attempted. 574 | /// Maximum number reconnection attempts. Defaults to 50 attempts. `onNoReconnect` callback is triggered when number of retries exceeds this value. 575 | public void EnableReconnect(int Interval = 5, int Retries = 50) 576 | { 577 | _isReconnect = true; 578 | _interval = Math.Max(Interval, 5); 579 | _retries = Retries; 580 | 581 | _timerTick = _interval; 582 | if (IsConnected) 583 | _timer.Start(); 584 | } 585 | 586 | /// 587 | /// Disable WebSocket autreconnect. 588 | /// 589 | public void DisableReconnect() 590 | { 591 | _isReconnect = false; 592 | if (IsConnected) 593 | _timer.Stop(); 594 | _timerTick = _interval; 595 | } 596 | } 597 | } 598 | --------------------------------------------------------------------------------