{"id":19000298,"url":"https://github.com/ssxdev/option-chain-algotrade","last_synced_at":"2025-04-22T17:05:24.471Z","repository":{"id":251262802,"uuid":"666136062","full_name":"ssxdev/option-chain-algotrade","owner":"ssxdev","description":"This files contains all the necessary function required to run the Kite Ticker API to Stream and Fetch Option Data","archived":false,"fork":false,"pushed_at":"2025-02-11T15:08:53.000Z","size":167,"stargazers_count":9,"open_issues_count":1,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-17T07:17:28.019Z","etag":null,"topics":["algo","algotrading","kite","kiteconnect","python"],"latest_commit_sha":null,"homepage":"https://kite.trade/docs/kiteconnectjs/v3/KiteTicker.html","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ssxdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-13T19:52:32.000Z","updated_at":"2025-02-11T15:08:56.000Z","dependencies_parsed_at":"2024-08-01T21:27:17.275Z","dependency_job_id":"5902d838-cc77-45f9-aad7-7359f6397c33","html_url":"https://github.com/ssxdev/option-chain-algotrade","commit_stats":null,"previous_names":["ssxdev/option-chain-kite-ticker","surendarsingh/option-chain-kite-ticker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssxdev%2Foption-chain-algotrade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssxdev%2Foption-chain-algotrade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssxdev%2Foption-chain-algotrade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssxdev%2Foption-chain-algotrade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssxdev","download_url":"https://codeload.github.com/ssxdev/option-chain-algotrade/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250285662,"owners_count":21405296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algo","algotrading","kite","kiteconnect","python"],"created_at":"2024-11-08T18:06:52.162Z","updated_at":"2025-04-22T17:05:24.452Z","avatar_url":"https://github.com/ssxdev.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Option Chain Stream for Indian Stock Market built with Kite Ticker APIs\n\nThis library utilizes Kite Connect APIs to fetch the Option Chain of all the derivatives traded in the Indian stock market. With support for all exchanges, including NFO, MCX, CDS, and BCD, comprehensive option chain data can be streamed effortlessly in real-time. The library provides a convenient API to fetch the option chain of the assets.\n\nSome major features are\n\n* ✅ Light weight\n* ⚡️ Optimized for speed - Uses parallel connections through Python Multiprocessing\n* 📈 Supports subscribing to all the derivatives across all exchanges (NFO for equity, MCX, CDS, BCD) in a single API\n* ⏱️ No considerable difference in execution time even when subscribed to all the symbols present in Indian exchanges -\n  Uses cache wherever possible to eliminate network calls\n* 📊 Filters to remove unwanted options\n* 💡 Option chain is enriched by additional data like underlying asset price, lot size etc.\n* 🔧 Installable via pip\n\n## Prerequisites\n\nThis tool requires basic understanding\nof [the working of kite websockets](https://kite.trade/docs/connect/v3/websocket/).\n\nYou will also need\n\n1. Working [redis database](https://redis.io/)\n2. [Kite developer account](https://developers.kite.trade/) and application secrets (api_key and api_secret)\n\n## Installation\n\n```bash\ngit clone https://github.com/SurendarSingh/Option-Chain-Kite-Ticker.git\ncd Option-Chain-Kite-Ticker\npip install -r requirements.txt\n```\n\n## Usage\n\nThere are 2 main classes in this library. `OptionStream` to fetch and store the option chain in the database. `OptionChainFetcher` retrieves the stored option chain from the database.\n\nSubscribing to the option chain stream requires you to pass the trading symbols you want to monitor and expiry date.\nTrading symbol must be prefixed with the exchange to which the derivative belongs.\nE.g. NFO:HDFCBANK, NFO:RELIANCE, MCX:CRUDEOIL, CDS:EURINR. \nBy adding the symbol NFO:HDFCBANK, all the call and put options of NSE:HDFCBANK will be added to the option chain.\n\nNote that All equity derivatives are present in NFO exchange.\n\n\n## Basic example\n\nRedis service should be running in your machine before following the next steps.\n\nRunning this code requires kite developer app secrets (API key, API secret and Access token).\n\nSecrets can be provided\n\n1. By placing the secrets json in the filepath `$HOME/.kite/secrets` by default or pass any filename to the get_secrets() method.\n   The secrets json looks like this\n\n```json\n{\n  \"api_key\": \"your_api_key\",\n  \"api_secret\": \"your_api_secret\",\n  \"access_token\": \"generated_access_token\"\n}\n```\n\n\n2. By hard coding the secrets in the file\n\nHere's a simple code snippet to get started: \n\n```python\nfrom option_stream import OptionStream\nfrom helper import get_secrets\nfrom option_chain import OptionChainFetcher\n\n# the option stream start should be in main module\nif __name__ == '__main__':\n    # by default secrets are fetched from ~/.kite/secrets\n    secrets = get_secrets()  # or get_secrets(filename)\n\n    # or\n    # secrets = {\n    #     'api_key': 'your_api_key',\n    #     'api_secret': 'your_api_secret',\n    #     'access_token': 'generated_access_token'\n    # }\n\n    # there is no limit on the number of symbols to subscribe to\n    symbols = ['NFO:HDFCBANK', 'NFO:INFY', 'NFO:RELIANCE', 'NFO:DRREDDY', 'NFO:EICHERMOT']\n    # symbols = ['CDS:EURINR', 'CDS:GBPINR', 'CDS:JPYINR', 'CDS:USDINR', 'BCD:EURINR']\n    # symbols = ['MCX:GOLD', 'MCX:GOLDM', 'MCX:NATURALGAS', 'MCX:NICKEL', 'MCX:SILVER', 'MCX:SILVERM']\n\n    stream = OptionStream(symbols, secrets, expiry='23-02-2023')\n\n    # start the stream in a background thread\n    # start will return once the subscription is started and the first ticks are received\n    # this usually takes 20 sec.\n\n    # By default, threaded is False. This allows you to run this process in foreground while you fetch the option chain \n    # somewhere else.\n    stream.start(threaded=True)\n\n    # start fetching option chain\n    option_chain_fetcher = OptionChainFetcher()\n\n    # option chain for each trading symbol can be fetched in 3 ms\n    option_chain = option_chain_fetcher.get_option_chain('NFO:HDFCBANK')\n\n    # fetch option chain in bulk\n    option_chains = option_chain_fetcher.get_option_chains(\n        ['NFO:HDFCBANK', 'NFO:INFY', 'NFO:RELIANCE', 'NFO:DRREDDY', 'NFO:EICHERMOT'])\n    \n    # do some processing here\n```\n\n`start` method on the `OptionStream` class starts the process which subscribes to websockets, stores the quotes received and\ncreates the option chain.\nBy default, this is a blocking method call. This allows you to fetch the option chain in another process.\n\nYou can pass `threaded=True` to run the option stream in the background.\n\nIdeally you don't want to fetch the option chain the same python module that you use to start the option stream.\n\n### Fetching the option chain\n\nMake sure you start the option stream process before you fetch the option chain to avoid receiving the outdated data. You can only get the option chain for the trading symbols subscribed to the `OptionStream`.\n\n```python\nfrom option_chain import OptionChainFetcher\n\noption_chain_fetcher = OptionChainFetcher()\n\n# option chain for each trading symbol can be fetched in 3 ms\noption_chain = option_chain_fetcher.get_option_chain('NFO:HDFCBANK')\n\nwhile True:\n    option_chains = option_chain_fetcher.get_option_chains(\n        ['NFO:HDFCBANK', 'NFO:INFY', 'NFO:RELIANCE', 'NFO:DRREDDY', 'NFO:EICHERMOT'])\n    # do some processing on option chains\n    break\n```\n\n**Option Chain Response:**\n\nExample of option chain could be found [here](resources/hdfcbank_option_chain.json).\n\n\u003cdetails\u003e\n\u003csummary\u003eSee the shortened response here. \u003c/summary\u003e\n\n```json\n{\n  \"trading_symbol\": \"HDFCBANK\",\n  \"segment\": \"NFO-OPT\",\n  \"underlying_value\": \"1658.1\",\n  \"expiry\": {\n    \"23-02-2023\": [\n      {\n        \"strike_price\": 1600.0,\n        \"ce\": {\n          \"bid_quantity\": 1650,\n          \"bid_price\": 63.4,\n          \"ask_quantity\": 550,\n          \"ask_price\": 65.2,\n          \"premium\": 65.0,\n          \"last_trade_time\": \"13-02-2023 10:59:43\",\n          \"exchange_timestamp\": \"13-02-2023 12:57:46\",\n          \"last_traded_quantity\": 550,\n          \"change\": 3.916866506794569,\n          \"oi\": 398750,\n          \"oi_day_high\": 430100,\n          \"oi_day_low\": 398750,\n          \"total_buy_quantity\": 73700,\n          \"ohlc\": {\n            \"open\": 60.0,\n            \"high\": 66.4,\n            \"low\": 52.6,\n            \"close\": 62.55\n          },\n          \"total_sell_quantity\": 47300,\n          \"volume\": 202400,\n          \"bid\": [\n            {\n              \"quantity\": 1650,\n              \"price\": 63.4,\n              \"orders\": 3\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 63.35,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 1100,\n              \"price\": 63.3,\n              \"orders\": 2\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 63.15,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 62.7,\n              \"orders\": 1\n            }\n          ],\n          \"ask\": [\n            {\n              \"quantity\": 550,\n              \"price\": 65.2,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 65.25,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 65.3,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 68.25,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 69.0,\n              \"orders\": 1\n            }\n          ],\n          \"tradable\": true,\n          \"depth\": {\n            \"buy\": [\n              {\n                \"quantity\": 1650,\n                \"price\": 63.4,\n                \"orders\": 3\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 63.35,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 1100,\n                \"price\": 63.3,\n                \"orders\": 2\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 63.15,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 62.7,\n                \"orders\": 1\n              }\n            ],\n            \"sell\": [\n              {\n                \"quantity\": 550,\n                \"price\": 65.2,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 65.25,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 65.3,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 68.25,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 69.0,\n                \"orders\": 1\n              }\n            ]\n          },\n          \"instrument_token\": 20601602\n        },\n        \"pe\": {\n          \"bid_quantity\": 550,\n          \"bid_price\": 4.55,\n          \"ask_quantity\": 550,\n          \"ask_price\": 4.7,\n          \"premium\": 4.55,\n          \"last_trade_time\": \"13-02-2023 10:59:55\",\n          \"exchange_timestamp\": \"13-02-2023 12:57:46\",\n          \"last_traded_quantity\": 550,\n          \"change\": -12.500000000000005,\n          \"oi\": 1410200,\n          \"oi_day_high\": 1499850,\n          \"oi_day_low\": 1408000,\n          \"total_buy_quantity\": 151250,\n          \"ohlc\": {\n            \"open\": 5.05,\n            \"high\": 6.0,\n            \"low\": 4.25,\n            \"close\": 5.2\n          },\n          \"total_sell_quantity\": 191950,\n          \"volume\": 2049300,\n          \"bid\": [\n            {\n              \"quantity\": 550,\n              \"price\": 4.55,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 4.35,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 11550,\n              \"price\": 4.3,\n              \"orders\": 2\n            },\n            {\n              \"quantity\": 2200,\n              \"price\": 4.25,\n              \"orders\": 3\n            },\n            {\n              \"quantity\": 1100,\n              \"price\": 4.2,\n              \"orders\": 2\n            }\n          ],\n          \"ask\": [\n            {\n              \"quantity\": 550,\n              \"price\": 4.7,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 1100,\n              \"price\": 4.75,\n              \"orders\": 2\n            },\n            {\n              \"quantity\": 550,\n              \"price\": 4.8,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 1100,\n              \"price\": 4.9,\n              \"orders\": 1\n            },\n            {\n              \"quantity\": 1100,\n              \"price\": 5.0,\n              \"orders\": 2\n            }\n          ],\n          \"tradable\": true,\n          \"depth\": {\n            \"buy\": [\n              {\n                \"quantity\": 550,\n                \"price\": 4.55,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 4.35,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 11550,\n                \"price\": 4.3,\n                \"orders\": 2\n              },\n              {\n                \"quantity\": 2200,\n                \"price\": 4.25,\n                \"orders\": 3\n              },\n              {\n                \"quantity\": 1100,\n                \"price\": 4.2,\n                \"orders\": 2\n              }\n            ],\n            \"sell\": [\n              {\n                \"quantity\": 550,\n                \"price\": 4.7,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 1100,\n                \"price\": 4.75,\n                \"orders\": 2\n              },\n              {\n                \"quantity\": 550,\n                \"price\": 4.8,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 1100,\n                \"price\": 4.9,\n                \"orders\": 1\n              },\n              {\n                \"quantity\": 1100,\n                \"price\": 5.0,\n                \"orders\": 2\n              }\n            ]\n          },\n          \"instrument_token\": 20601858\n        }\n      },\n      {\n        \"strike_price\": 1650.0,\n        \"another_key\": \"and so on.. see the full response above\"\n      }\n    ]\n  },\n  \"source\": \"kite_api\",\n  \"lot_size\": 550\n}\n```\n\n\u003c/details\u003e\n\n**Fields**\n\n* Underlying value - Last day's market price of the underlying asset. This value is available only for non index equity\n  options as of now.\n* Rest of the fields - are self-explanatory\n\n## Advanced Usage\n\n### Filter out unwanted options\n\nAs of today, there are 217 underlying assets in Indian stock market across all the exchanges. It means we need to\nsubscribe to approximately 16,000 instrument tokens to fetch the data of all the options.\n\nKite websocket API\nrestricts the parallel connections to 3 and there could be a maximum of 3000 tokens per connection. Only 9000\ntokens could be subscribed with a single access token. Hence, it's not possible to fetch quotes of all the tokens with the access token of just one application in Kite Connect.   \n\nBut most of the times, we will not be interested in deep ITM/OTM options which are\n15% to 30% away from the spot price of the underlying asset as these options are highly illiquid or have no open\ninterest.\n\nWith the percentage filter, you can filter out these options. You can specify value in percentage. Any option whose\nstrike price is farther from the spot price by specified value will be filtered out.\nConsider an example where the underlying asset say RELIANCE has a spot price of 1000 INR. If the percentage filter of\nvalue 20 is applied, all the options whose strike price is greater than 1200 and lesser than 800 are removed from the option chain.\n\n### Other features\n\n- By default, db=0 (Database index) is selected in redis. You can change it by passing the RedisConfig instance. Make\n  sure you pass the same configuration to OptionChainFetcher APIs if you use this configuration.\n\n## Code describing the advanced usage\n\n```python\nfrom option_stream import OptionStream\nfrom helper import get_secrets\nfrom redis_helper import RedisConfig\n\n# the option stream start should be in main module\nif __name__ == '__main__':\n    secrets = get_secrets()\n\n    symbols = ['NFO:HDFCBANK', 'NFO:INFY', 'NFO:RELIANCE', 'NFO:DRREDDY', 'NFO:EICHERMOT']\n\n    # The percentage criteria filters out options with strike prices that are more than a specified value away\n    # from the current spot price. In this example, percentage value is set to 12.5%.\n    # By adding this criteria filter, it resolves to 262 tokens instead of 438 tokens if no filter was\n    # applied\n    criteria = {'name': 'percentage', 'properties': {'value': 12.5}}\n\n    stream = OptionStream(symbols, secrets,\n                          expiry='23-02-2023',\n                          criteria=criteria,\n                          redis_config=RedisConfig(db=1)\n                          )\n    stream.start()\n```\n\n## How does it work internally?\n\nKite Connect APIs provides Websockets API. It enables us to subscribe to individual options of the underlying asset.\nMaximum of 3 websockets connections can be established and each connection can subscribe upto 3000 instrument tokens.\n\nKiteInstrumentManager runs once a day during the first run of the option stream to fetch the instruments. Once the\nOptionStream is instantiated with the underlying assets, the corresponding tokens are calculated.\nNumber of websocket connections are determined based on the size of the tokens with a limit of 3. Connections are\ncreated within separate python processes. Quotes/ticks are obtained after the websocket connection is established. Ticks\nare stored in redis hash. Storage of ticks is handled by separate worker threads. Another worker thread calculates the\noption chain using the stored ticks.\n\nOptionChainFetcher class provides an interface to fetch the quotes stored in the database.\n\n## Contact\n\nFeel free to [contact me](https://github.com/surendarsingh) if you need any support regarding the usage of this library. If there are bugs, please create an\nissue in GitHub.  ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssxdev%2Foption-chain-algotrade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssxdev%2Foption-chain-algotrade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssxdev%2Foption-chain-algotrade/lists"}