{"id":22555235,"url":"https://github.com/elbakramer/pynescript","last_synced_at":"2025-04-10T05:16:51.917Z","repository":{"id":60092954,"uuid":"537742793","full_name":"elbakramer/pynescript","owner":"elbakramer","description":"Handle Pinescript using Python","archived":false,"fork":false,"pushed_at":"2024-02-29T18:45:42.000Z","size":225,"stargazers_count":63,"open_issues_count":1,"forks_count":18,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-10T05:16:44.170Z","etag":null,"topics":["pinescript","python","tradingview"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elbakramer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-17T08:15:01.000Z","updated_at":"2025-03-31T10:09:33.000Z","dependencies_parsed_at":"2023-02-16T06:31:31.288Z","dependency_job_id":null,"html_url":"https://github.com/elbakramer/pynescript","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elbakramer%2Fpynescript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elbakramer%2Fpynescript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elbakramer%2Fpynescript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elbakramer%2Fpynescript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elbakramer","download_url":"https://codeload.github.com/elbakramer/pynescript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161284,"owners_count":21057556,"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":["pinescript","python","tradingview"],"created_at":"2024-12-07T19:07:09.537Z","updated_at":"2025-04-10T05:16:51.890Z","avatar_url":"https://github.com/elbakramer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pynescript\n\n[![PyPI](https://img.shields.io/pypi/v/pynescript.svg)][pypi_]\n[![Status](https://img.shields.io/pypi/status/pynescript.svg)][status]\n[![Python Version](https://img.shields.io/pypi/pyversions/pynescript)][python version]\n[![License](https://img.shields.io/pypi/l/pynescript)][license]\n\n[![Read the documentation at https://pynescript.readthedocs.io/](https://img.shields.io/readthedocs/pynescript/latest.svg?label=Read%20the%20Docs)][read the docs]\n[![Tests](https://github.com/elbakramer/pynescript/workflows/Tests/badge.svg)][tests]\n[![Codecov](https://codecov.io/gh/elbakramer/pynescript/branch/main/graph/badge.svg)][codecov]\n\n[pypi_]: https://pypi.org/project/pynescript/\n[status]: https://pypi.org/project/pynescript/\n[python version]: https://pypi.org/project/pynescript\n[read the docs]: https://pynescript.readthedocs.io/\n[tests]: https://github.com/elbakramer/pynescript/actions?workflow=Tests\n[codecov]: https://app.codecov.io/gh/elbakramer/pynescript\n\n## Features\n\nHandle [Pinescript] using [Python]\n\n-   Parse Pinescript code into AST\n-   Dump parsed AST\n-   Unparse parsed AST back to Pinescript code\n\nGiven an example pinescript with name of `rsi_strategy.pine`:\n\n```pinescript\n//@version=5\nstrategy(\"RSI Strategy\", overlay=true)\nlength = input( 14 )\noverSold = input( 30 )\noverBought = input( 70 )\nprice = close\nvrsi = ta.rsi(price, length)\nco = ta.crossover(vrsi, overSold)\ncu = ta.crossunder(vrsi, overBought)\nif (not na(vrsi))\n\tif (co)\n\t\tstrategy.entry(\"RsiLE\", strategy.long, comment=\"RsiLE\")\n\tif (cu)\n\t\tstrategy.entry(\"RsiSE\", strategy.short, comment=\"RsiSE\")\n//plot(strategy.equity, title=\"equity\", color=color.red, linewidth=2, style=plot.style_areabr)\n```\n\nParsing script into AST and dumping it:\n\n```console\n$ pynescript parse-and-dump rsi_strategy.pine\n```\n\nGives like:\n\n```python\nScript(\n  body=[\n    Expr(\n      value=Call(\n        func=Name(id='strategy', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value='RSI Strategy')),\n          Arg(\n            value=Constant(value=True),\n            name='overlay')])),\n    Assign(\n      target=Name(id='length', ctx=Store()),\n      value=Call(\n        func=Name(id='input', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value=14))]),\n      annotations=[]),\n    ...\n```\n\n\u003cdetails\u003e\n    \u003csummary\u003eFull AST dump that is quite long...\u003c/summary\u003e\n\n```python\nScript(\n  body=[\n    Expr(\n      value=Call(\n        func=Name(id='strategy', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value='RSI Strategy')),\n          Arg(\n            value=Constant(value=True),\n            name='overlay')])),\n    Assign(\n      target=Name(id='length', ctx=Store()),\n      value=Call(\n        func=Name(id='input', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value=14))]),\n      annotations=[]),\n    Assign(\n      target=Name(id='overSold', ctx=Store()),\n      value=Call(\n        func=Name(id='input', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value=30))]),\n      annotations=[]),\n    Assign(\n      target=Name(id='overBought', ctx=Store()),\n      value=Call(\n        func=Name(id='input', ctx=Load()),\n        args=[\n          Arg(\n            value=Constant(value=70))]),\n      annotations=[]),\n    Assign(\n      target=Name(id='price', ctx=Store()),\n      value=Name(id='close', ctx=Load()),\n      annotations=[]),\n    Assign(\n      target=Name(id='vrsi', ctx=Store()),\n      value=Call(\n        func=Attribute(\n          value=Name(id='ta', ctx=Load()),\n          attr='rsi',\n          ctx=Load()),\n        args=[\n          Arg(\n            value=Name(id='price', ctx=Load())),\n          Arg(\n            value=Name(id='length', ctx=Load()))]),\n      annotations=[]),\n    Assign(\n      target=Name(id='co', ctx=Store()),\n      value=Call(\n        func=Attribute(\n          value=Name(id='ta', ctx=Load()),\n          attr='crossover',\n          ctx=Load()),\n        args=[\n          Arg(\n            value=Name(id='vrsi', ctx=Load())),\n          Arg(\n            value=Name(id='overSold', ctx=Load()))]),\n      annotations=[]),\n    Assign(\n      target=Name(id='cu', ctx=Store()),\n      value=Call(\n        func=Attribute(\n          value=Name(id='ta', ctx=Load()),\n          attr='crossunder',\n          ctx=Load()),\n        args=[\n          Arg(\n            value=Name(id='vrsi', ctx=Load())),\n          Arg(\n            value=Name(id='overBought', ctx=Load()))]),\n      annotations=[]),\n    Expr(\n      value=If(\n        test=UnaryOp(\n          op=Not(),\n          operand=Call(\n            func=Name(id='na', ctx=Load()),\n            args=[\n              Arg(\n                value=Name(id='vrsi', ctx=Load()))])),\n        body=[\n          Expr(\n            value=If(\n              test=Name(id='co', ctx=Load()),\n              body=[\n                Expr(\n                  value=Call(\n                    func=Attribute(\n                      value=Name(id='strategy', ctx=Load()),\n                      attr='entry',\n                      ctx=Load()),\n                    args=[\n                      Arg(\n                        value=Constant(value='RsiLE')),\n                      Arg(\n                        value=Attribute(\n                          value=Name(id='strategy', ctx=Load()),\n                          attr='long',\n                          ctx=Load())),\n                      Arg(\n                        value=Constant(value='RsiLE'),\n                        name='comment')]))],\n              orelse=[])),\n          Expr(\n            value=If(\n              test=Name(id='cu', ctx=Load()),\n              body=[\n                Expr(\n                  value=Call(\n                    func=Attribute(\n                      value=Name(id='strategy', ctx=Load()),\n                      attr='entry',\n                      ctx=Load()),\n                    args=[\n                      Arg(\n                        value=Constant(value='RsiSE')),\n                      Arg(\n                        value=Attribute(\n                          value=Name(id='strategy', ctx=Load()),\n                          attr='short',\n                          ctx=Load())),\n                      Arg(\n                        value=Constant(value='RsiSE'),\n                        name='comment')]))],\n              orelse=[]))],\n        orelse=[]))],\n  annotations=[\n    '//@version=5'])\n```\n\n\u003c/details\u003e\n\nParsing into AST and unparsing it back:\n\n```console\n$ pynescript parse-and-unparse rsi_strategy.pine\n```\n\nGives (with some difference in syntax including spacing):\n\n```pinescript\n//@version=5\nstrategy(\"RSI Strategy\", overlay=true)\nlength = input(14)\noverSold = input(30)\noverBought = input(70)\nprice = close\nvrsi = ta.rsi(price, length)\nco = ta.crossover(vrsi, overSold)\ncu = ta.crossunder(vrsi, overBought)\nif not na(vrsi)\n    if co\n        strategy.entry(\"RsiLE\", strategy.long, comment=\"RsiLE\")\n    if cu\n        strategy.entry(\"RsiSE\", strategy.short, comment=\"RsiSE\")\n```\n\n## Requirements\n\n-   Python 3.10 or higher\n\n## Installation\n\nYou can install _Pynescript_ via [pip] from [PyPI]:\n\n```console\n$ pip install pynescript\n```\n\n## Usage\n\nPlease see the [Usage][usage] for details.\n\n## License\n\nDistributed under the terms of the [LGPL 3.0 license][license],\n_Pynescript_ is free and open source software.\n\n## Issues\n\nIf you encounter any problems,\nplease [file an issue] along with a detailed description.\n\n[pinescript]: https://www.tradingview.com/pine-script-docs/en/v5/Introduction.html\n[python]: https://www.python.org/\n\n[pip]: https://pip.pypa.io/\n[pypi]: https://pypi.org/\n\n[file an issue]: https://github.com/elbakramer/pynescript/issues\n\n\u003c!-- github-only --\u003e\n\n[license]: https://github.com/elbakramer/pynescript/blob/main/LICENSE\n[usage]: https://pynescript.readthedocs.io/en/latest/usage.html","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felbakramer%2Fpynescript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felbakramer%2Fpynescript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felbakramer%2Fpynescript/lists"}