├── .github └── workflows │ ├── main.yml │ └── static.yml ├── .gitignore ├── LICENSE ├── README.md ├── StrikesAllowed.json ├── main.py └── requirements.txt /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Update Latest ZerodhaStrikesAllowedToTrade 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | schedule: 10 | - cron: '30 2 * * 1-5' 11 | - cron: '27 15 * * 1-5' 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | env: 16 | CI_COMMIT_MESSAGE: Updated Latest ZerodhaStrikesAllowedToTrade Json File 17 | CI_COMMIT_AUTHOR: DrJuneMoone 18 | steps: 19 | - uses: actions/checkout@v3 20 | # Build steps 21 | - uses: actions/setup-python@v4 22 | with: 23 | python-version: '3.10.x' 24 | - run: python --version 25 | - run: pip install -r requirements.txt 26 | - run: python main.py 27 | 28 | # Commit and push all changed files. 29 | - name: GIT Commit Build Artifacts (coverage, dist, devdist, docs) 30 | # Only run on main branch push (e.g. after pull request merge). 31 | if: contains(fromJson('["schedule", "push", "pull_request"]'), github.event_name) 32 | run: | 33 | git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" 34 | git config --global user.email "MooneDrJune@users.noreply.github.com" 35 | git add --all 36 | git commit --all -m "${{ env.CI_COMMIT_MESSAGE }}" 37 | git push 38 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | pull_request: 9 | branches: ["main"] 10 | schedule: 11 | - cron: '45 2 * * 1-5' 12 | - cron: '43 15 * * 1-5' 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 17 | permissions: 18 | contents: read 19 | pages: write 20 | id-token: write 21 | 22 | # Allow one concurrent deployment 23 | concurrency: 24 | group: "pages" 25 | cancel-in-progress: true 26 | 27 | jobs: 28 | # Single deploy job since we're just deploying 29 | deploy: 30 | environment: 31 | name: github-pages 32 | url: ${{ steps.deployment.outputs.page_url }} 33 | runs-on: ubuntu-latest 34 | steps: 35 | - name: Checkout 36 | uses: actions/checkout@v3 37 | - name: Setup Pages 38 | uses: actions/configure-pages@v2 39 | - name: Upload artifact 40 | uses: actions/upload-pages-artifact@v1 41 | with: 42 | # Upload entire repository 43 | path: '.' 44 | - name: Deploy to GitHub Pages 45 | id: deployment 46 | uses: actions/deploy-pages@v1 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Techfane Technologies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zerodha Strikes Allowed To Trade 2 | A Python Script To Fetch The Nifty, BankNifty And FinNifty Contracts Allowed For Trading At Zerodha Kite Platform. 3 | 4 | ## Update Frequency 5 | Check for updates daily at 08:00 AM IST and 08:00 PM IST 6 | 7 | ## Raw JSON Files 8 | - [StrikesAllowed.json](https://techfanetechnologies.github.io/ZerodhaStrikesAllowedToTrade/StrikesAllowed.json) 9 | 10 | ## _If You have liked the work, Do Star This Repository and Stay-Up-To-Date_ 11 |

12 | How To Star A Repository 13 |

14 | 15 | -------------------------------------------------------------------------------- /StrikesAllowed.json: -------------------------------------------------------------------------------- 1 | {"BankNifty": {"26/06/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}, "31/07/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}, "28/08/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}}, "Nifty": {"12/06/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}, "19/06/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}, "26/06/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes Allowed"}}, "FinNifty": {"26/06/2025": {"NRML": "All Strikes Allowed ", "MIS": "All Strikes With Oi Over 500 Lots Allowed"}}} -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | :description: A Python Script To Fetch The Nifty, Bank Nifty & Fin Nifty Contracts Allowed For Trading At Zerodha Kite Platform. 4 | :license: MIT. 5 | :author: Dr June Moone 6 | :created: On Monday November 28, 2022 11:17:53 GMT+05:30 7 | """ 8 | __author__ = "Dr June Moone" 9 | __webpage__ = "https://github.com/MooneDrJune" 10 | __license__ = "MIT" 11 | 12 | try: 13 | import json 14 | import requests 15 | from lxml import html 16 | from typing import Tuple, List, Dict, Union 17 | except (ImportError, ModuleNotFoundError): 18 | __import__("os").system( 19 | f"{__import__('sys').executable} -m pip install -U requests lxml json" 20 | ) 21 | finally: 22 | import json 23 | import requests 24 | from lxml import html 25 | from typing import Tuple, List, Dict, Union 26 | 27 | 28 | def fetchAllowedLists( 29 | url: str = "https://zerodha.com/margin-calculator/SPAN/", 30 | ) -> Tuple[List[str], List[str], List[str]]: 31 | table_data = [ 32 | item.strip() 33 | for item in html.fromstring(requests.get(url=url).content) 34 | .xpath('//*[@id="remove_container"]/section[2]/div[2]')[0] 35 | .text_content() 36 | .strip() 37 | .splitlines() 38 | if item.strip() != "" 39 | ] 40 | 41 | sec_under_ban = table_data[ 42 | table_data.index("Securities under ban") 43 | + 1 : table_data.index("Bank Nifty contracts allowed for trading") 44 | ] 45 | sec_under_ban = ( 46 | sec_under_ban[: sec_under_ban.index("More information")] 47 | if "More information" in sec_under_ban 48 | else sec_under_ban 49 | ) 50 | bnf_allowed = table_data[ 51 | table_data.index("Bank Nifty contracts allowed for trading") 52 | + 1 : table_data.index("Nifty contracts allowed for trading") 53 | ] 54 | bnf_allowed = ( 55 | bnf_allowed[: bnf_allowed.index("More information")] 56 | if "More information" in bnf_allowed 57 | else bnf_allowed 58 | ) 59 | nf_allowed = table_data[ 60 | table_data.index("Nifty contracts allowed for trading") 61 | + 1 : table_data.index("Finnifty contracts allowed for trading") 62 | ] 63 | nf_allowed = ( 64 | nf_allowed[: nf_allowed.index("More information")] 65 | if "More information" in nf_allowed 66 | else nf_allowed 67 | ) 68 | fnf_allowed = table_data[ 69 | table_data.index("Finnifty contracts allowed for trading") + 1 : 70 | ] 71 | fnf_allowed = ( 72 | fnf_allowed[: fnf_allowed.index("More information")] 73 | if "More information" in fnf_allowed 74 | else fnf_allowed 75 | ) 76 | return bnf_allowed, nf_allowed, fnf_allowed 77 | 78 | 79 | def updateDict( 80 | allowedList: List[str], 81 | ) -> Dict[str, Dict[str, Union[List[float], str]]]: 82 | StrikesAllowed = {} 83 | if len(allowedList) == 1: 84 | if "More information" in allowedList[0]: 85 | text = allowedList[0].split("More information")[0].strip() 86 | else: 87 | text = allowedList[0] 88 | allowedList = [ 89 | "Ne" + i if i.startswith("xt") else "Cu" + i if i.startswith("rrent") else i 90 | for i in [ 91 | _item 92 | for item in [item.split(" Ne") for item in text.split(" Cu")] 93 | for _item in item 94 | ] 95 | ] 96 | for item in allowedList: 97 | ((nrml, mis,), prd,) = ( 98 | tuple( 99 | [ 100 | item.split(" to ") if " to " in item else item 101 | for item in item.split("NRML:")[-1].split("MIS:") 102 | ] 103 | ), 104 | item.split("-")[0].strip(), 105 | ) 106 | StrikesAllowed[prd] = { 107 | "NRML": ( 108 | {"from": float(nrml[0]), "to": float(nrml[-1])} 109 | if isinstance(nrml, list) 110 | else nrml.title() 111 | ), 112 | "MIS": ( 113 | {"from": float(mis[0]), "to": float(mis[-1])} 114 | if isinstance(mis, list) 115 | else mis.title() 116 | ), 117 | } 118 | return StrikesAllowed 119 | 120 | 121 | if __name__ == "__main__": 122 | StrikesAllowed = dict( 123 | zip( 124 | ("BankNifty", "Nifty", "FinNifty"), 125 | tuple(map(updateDict, fetchAllowedLists())), 126 | ) 127 | ) 128 | with open("StrikesAllowed.json", "w") as jsonFile: 129 | jsonFile.write(json.dumps(StrikesAllowed)) 130 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | lxml 3 | --------------------------------------------------------------------------------