opencode-pyneruntime 6.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencode_pyneruntime-6.6.4.dist-info/METADATA +281 -0
- opencode_pyneruntime-6.6.4.dist-info/RECORD +261 -0
- opencode_pyneruntime-6.6.4.dist-info/WHEEL +5 -0
- opencode_pyneruntime-6.6.4.dist-info/entry_points.txt +6 -0
- opencode_pyneruntime-6.6.4.dist-info/licenses/LICENSE +201 -0
- opencode_pyneruntime-6.6.4.dist-info/licenses/NOTICE +21 -0
- opencode_pyneruntime-6.6.4.dist-info/top_level.txt +1 -0
- pynecore/__init__.py +6 -0
- pynecore/cli/__init__.py +2 -0
- pynecore/cli/app.py +238 -0
- pynecore/cli/commands/__init__.py +343 -0
- pynecore/cli/commands/benchmark.py +186 -0
- pynecore/cli/commands/compile.py +198 -0
- pynecore/cli/commands/data.py +857 -0
- pynecore/cli/commands/debug.py +63 -0
- pynecore/cli/commands/optimize.py +956 -0
- pynecore/cli/commands/plugin.py +242 -0
- pynecore/cli/commands/run.py +2006 -0
- pynecore/cli/pluggable.py +132 -0
- pynecore/cli/utils/__init__.py +0 -0
- pynecore/cli/utils/api_error_handler.py +168 -0
- pynecore/cli/utils/broker_picker.py +330 -0
- pynecore/cli/utils/error_hook.py +28 -0
- pynecore/cli/utils/keyreader.py +178 -0
- pynecore/cli/utils/provider_picker.py +19 -0
- pynecore/cli/utils/symbol_browser.py +1149 -0
- pynecore/core/__init__.py +0 -0
- pynecore/core/aggregator.py +257 -0
- pynecore/core/bar_magnifier.py +168 -0
- pynecore/core/broker/__init__.py +64 -0
- pynecore/core/broker/defaults.py +113 -0
- pynecore/core/broker/disappearance.py +927 -0
- pynecore/core/broker/emulator.py +345 -0
- pynecore/core/broker/exceptions.py +346 -0
- pynecore/core/broker/idempotency.py +401 -0
- pynecore/core/broker/intent_builder.py +334 -0
- pynecore/core/broker/journal.py +1785 -0
- pynecore/core/broker/models.py +1600 -0
- pynecore/core/broker/native_failsafe_manager.py +1436 -0
- pynecore/core/broker/one_way_emulator.py +1128 -0
- pynecore/core/broker/position.py +787 -0
- pynecore/core/broker/run_identity.py +126 -0
- pynecore/core/broker/software_entry_stop_engine.py +351 -0
- pynecore/core/broker/software_partial_bracket_engine.py +1379 -0
- pynecore/core/broker/spot_inventory.py +1327 -0
- pynecore/core/broker/storage.py +2655 -0
- pynecore/core/broker/store_helpers.py +2161 -0
- pynecore/core/broker/sync_engine.py +16070 -0
- pynecore/core/broker/validation.py +382 -0
- pynecore/core/class_property.py +7 -0
- pynecore/core/config.py +392 -0
- pynecore/core/csv_file.py +547 -0
- pynecore/core/currency.py +262 -0
- pynecore/core/data_converter.py +1002 -0
- pynecore/core/datetime.py +296 -0
- pynecore/core/download_info.py +71 -0
- pynecore/core/download_runner.py +274 -0
- pynecore/core/htf_aggregator.py +181 -0
- pynecore/core/import_hook.py +358 -0
- pynecore/core/instance_state.py +494 -0
- pynecore/core/live_ltf_collector.py +442 -0
- pynecore/core/live_ltf_window.py +189 -0
- pynecore/core/live_runner.py +1347 -0
- pynecore/core/module_property.py +26 -0
- pynecore/core/ohlcv_file.py +1888 -0
- pynecore/core/overload.py +371 -0
- pynecore/core/pine_cast.py +113 -0
- pynecore/core/pine_export.py +95 -0
- pynecore/core/pine_method.py +244 -0
- pynecore/core/pine_range.py +86 -0
- pynecore/core/pine_udt.py +69 -0
- pynecore/core/plugin/__init__.py +394 -0
- pynecore/core/plugin/broker.py +781 -0
- pynecore/core/plugin/cli.py +96 -0
- pynecore/core/plugin/live_provider.py +208 -0
- pynecore/core/plugin/provider.py +331 -0
- pynecore/core/provider_string.py +148 -0
- pynecore/core/random.py +40 -0
- pynecore/core/resampler.py +686 -0
- pynecore/core/safe_convert.py +64 -0
- pynecore/core/script.py +1011 -0
- pynecore/core/script_runner.py +3202 -0
- pynecore/core/security.py +1749 -0
- pynecore/core/security_process.py +1253 -0
- pynecore/core/security_shm.py +456 -0
- pynecore/core/series.py +417 -0
- pynecore/core/strategy_stats.py +669 -0
- pynecore/core/symbol_map.py +134 -0
- pynecore/core/syminfo.py +505 -0
- pynecore/core/viz.py +591 -0
- pynecore/lib/__init__.py +1771 -0
- pynecore/lib/_fixnan.py +32 -0
- pynecore/lib/_math_stateful.py +202 -0
- pynecore/lib/_timeframe_change.py +101 -0
- pynecore/lib/adjustment.py +6 -0
- pynecore/lib/alert.py +39 -0
- pynecore/lib/alert.pyi +14 -0
- pynecore/lib/array.py +1051 -0
- pynecore/lib/barmerge.py +60 -0
- pynecore/lib/barstate.py +30 -0
- pynecore/lib/box.py +415 -0
- pynecore/lib/chart.py +128 -0
- pynecore/lib/color.py +152 -0
- pynecore/lib/color.pyi +50 -0
- pynecore/lib/currency.py +62 -0
- pynecore/lib/dayofweek.py +36 -0
- pynecore/lib/dayofweek.pyi +18 -0
- pynecore/lib/display.py +8 -0
- pynecore/lib/dividends.py +9 -0
- pynecore/lib/earnings.py +11 -0
- pynecore/lib/extend.py +6 -0
- pynecore/lib/font.py +5 -0
- pynecore/lib/footprint.py +79 -0
- pynecore/lib/format.py +11 -0
- pynecore/lib/hline.py +67 -0
- pynecore/lib/hline.pyi +24 -0
- pynecore/lib/label.py +409 -0
- pynecore/lib/line.py +433 -0
- pynecore/lib/linefill.py +93 -0
- pynecore/lib/location.py +11 -0
- pynecore/lib/log.py +362 -0
- pynecore/lib/map.py +150 -0
- pynecore/lib/math.py +385 -0
- pynecore/lib/matrix.py +708 -0
- pynecore/lib/order.py +8 -0
- pynecore/lib/pivotpointtype.py +8 -0
- pynecore/lib/plot.py +95 -0
- pynecore/lib/plot.pyi +33 -0
- pynecore/lib/polyline.py +91 -0
- pynecore/lib/position.py +15 -0
- pynecore/lib/request.py +281 -0
- pynecore/lib/runtime.py +5 -0
- pynecore/lib/scale.py +9 -0
- pynecore/lib/session.py +267 -0
- pynecore/lib/session.pyi +12 -0
- pynecore/lib/shape.py +18 -0
- pynecore/lib/size.py +12 -0
- pynecore/lib/splits.py +4 -0
- pynecore/lib/strategy/__init__.py +4778 -0
- pynecore/lib/strategy/closedtrades.py +347 -0
- pynecore/lib/strategy/closedtrades.pyi +53 -0
- pynecore/lib/strategy/commission.py +9 -0
- pynecore/lib/strategy/direction.py +9 -0
- pynecore/lib/strategy/oca.py +13 -0
- pynecore/lib/strategy/opentrades.py +281 -0
- pynecore/lib/strategy/opentrades.pyi +49 -0
- pynecore/lib/strategy/risk.py +109 -0
- pynecore/lib/string.py +649 -0
- pynecore/lib/syminfo.py +84 -0
- pynecore/lib/ta.py +2230 -0
- pynecore/lib/table.py +290 -0
- pynecore/lib/text.py +17 -0
- pynecore/lib/ticker.py +207 -0
- pynecore/lib/timeframe.py +293 -0
- pynecore/lib/volume_row.py +67 -0
- pynecore/lib/xloc.py +4 -0
- pynecore/lib/yloc.py +5 -0
- pynecore/providers/__init__.py +0 -0
- pynecore/providers/ccxt.py +664 -0
- pynecore/providers/replay.py +187 -0
- pynecore/pynesys/__init__.py +0 -0
- pynecore/pynesys/api.py +498 -0
- pynecore/pynesys/compiler.py +112 -0
- pynecore/standalone.py +99 -0
- pynecore/testing/__init__.py +1 -0
- pynecore/testing/broker_lab/__init__.py +41 -0
- pynecore/testing/broker_lab/__main__.py +5 -0
- pynecore/testing/broker_lab/cli.py +87 -0
- pynecore/testing/broker_lab/generate.py +47 -0
- pynecore/testing/broker_lab/model.py +84 -0
- pynecore/testing/broker_lab/reference.py +645 -0
- pynecore/testing/broker_lab/runner.py +372 -0
- pynecore/testing/broker_lab/scheduler.py +50 -0
- pynecore/testing/broker_lab/subprocess.py +73 -0
- pynecore/transformers/__init__.py +0 -0
- pynecore/transformers/builtin_shadow.py +136 -0
- pynecore/transformers/closure_arguments_transformer.py +428 -0
- pynecore/transformers/display_rewrite.py +140 -0
- pynecore/transformers/dynamic_default.py +147 -0
- pynecore/transformers/function_isolation.py +757 -0
- pynecore/transformers/import_lifter.py +61 -0
- pynecore/transformers/import_normalizer.py +328 -0
- pynecore/transformers/inline_series_hoist.py +178 -0
- pynecore/transformers/input_transformer.py +175 -0
- pynecore/transformers/lib_series.py +201 -0
- pynecore/transformers/locations.py +70 -0
- pynecore/transformers/module_properties.json +3387 -0
- pynecore/transformers/module_property.py +221 -0
- pynecore/transformers/ne_guard.py +70 -0
- pynecore/transformers/persistent.py +320 -0
- pynecore/transformers/persistent_series.py +76 -0
- pynecore/transformers/safe_convert_transformer.py +97 -0
- pynecore/transformers/safe_division_transformer.py +95 -0
- pynecore/transformers/script_requirements.py +308 -0
- pynecore/transformers/security.py +752 -0
- pynecore/transformers/security_instantiation.py +274 -0
- pynecore/transformers/series.py +275 -0
- pynecore/transformers/slot_layout.py +381 -0
- pynecore/transformers/type_checking_stripper.py +25 -0
- pynecore/transformers/unused_series_detector.py +267 -0
- pynecore/types/__init__.py +21 -0
- pynecore/types/alert.py +5 -0
- pynecore/types/barmerge.py +5 -0
- pynecore/types/base.py +39 -0
- pynecore/types/box.py +37 -0
- pynecore/types/chart.py +17 -0
- pynecore/types/color.py +107 -0
- pynecore/types/currency.py +5 -0
- pynecore/types/datetime.py +6 -0
- pynecore/types/display.py +5 -0
- pynecore/types/dividends.py +5 -0
- pynecore/types/earnings.py +5 -0
- pynecore/types/extend.py +5 -0
- pynecore/types/font.py +5 -0
- pynecore/types/footprint.py +41 -0
- pynecore/types/format.py +5 -0
- pynecore/types/hline.py +24 -0
- pynecore/types/ib_persistent.py +8 -0
- pynecore/types/ib_persistent.pyi +10 -0
- pynecore/types/label.py +35 -0
- pynecore/types/line.py +32 -0
- pynecore/types/linefill.py +13 -0
- pynecore/types/location.py +5 -0
- pynecore/types/matrix.py +999 -0
- pynecore/types/na.py +237 -0
- pynecore/types/na.pyi +83 -0
- pynecore/types/ohlcv.py +12 -0
- pynecore/types/order.py +5 -0
- pynecore/types/persistent.py +8 -0
- pynecore/types/persistent.pyi +13 -0
- pynecore/types/pine_types.py +11 -0
- pynecore/types/pine_types.pyi +15 -0
- pynecore/types/pivotpointtype.py +5 -0
- pynecore/types/plot.py +12 -0
- pynecore/types/plot_meta.py +60 -0
- pynecore/types/polyline.py +40 -0
- pynecore/types/position.py +5 -0
- pynecore/types/scale.py +5 -0
- pynecore/types/script_type.py +15 -0
- pynecore/types/series.py +23 -0
- pynecore/types/series.pyi +19 -0
- pynecore/types/session.py +35 -0
- pynecore/types/shape.py +5 -0
- pynecore/types/size.py +5 -0
- pynecore/types/source.py +33 -0
- pynecore/types/splits.py +5 -0
- pynecore/types/strategy.py +45 -0
- pynecore/types/table.py +87 -0
- pynecore/types/text.py +13 -0
- pynecore/types/type_checker.py +7 -0
- pynecore/types/type_checker.pyi +48 -0
- pynecore/types/volume_row.py +36 -0
- pynecore/types/weekdays.py +11 -0
- pynecore/types/xloc.py +5 -0
- pynecore/types/yloc.py +5 -0
- pynecore/utils/__init__.py +0 -0
- pynecore/utils/file_utils.py +50 -0
- pynecore/utils/rich/__init__.py +0 -0
- pynecore/utils/rich/date_column.py +25 -0
- pynecore/utils/sequence_view.py +92 -0
- pynecore/utils/stdlib_checker.py +17 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tomllib
|
|
3
|
+
import time
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
|
|
12
|
+
from ..app import app, app_state
|
|
13
|
+
from ..utils.api_error_handler import APIErrorHandler
|
|
14
|
+
from pynecore.pynesys.compiler import PyneComp
|
|
15
|
+
from ...utils.file_utils import copy_mtime
|
|
16
|
+
|
|
17
|
+
__all__ = []
|
|
18
|
+
|
|
19
|
+
console = Console()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _print_usage(compiler: PyneComp, sleep: float = 0):
|
|
23
|
+
"""Print usage statistics in a nicely formatted table."""
|
|
24
|
+
usage = compiler.get_usage()
|
|
25
|
+
|
|
26
|
+
# Create the main usage table
|
|
27
|
+
table = Table(title="API Usage Statistics", show_header=True, header_style="bold magenta")
|
|
28
|
+
table.add_column("Period", style="cyan", no_wrap=True)
|
|
29
|
+
table.add_column("Used", style="bold red", justify="right")
|
|
30
|
+
table.add_column("Limit", style="bold green", justify="right")
|
|
31
|
+
table.add_column("Remaining", style="bold yellow", justify="right")
|
|
32
|
+
table.add_column("Reset At", style="dim")
|
|
33
|
+
|
|
34
|
+
# Add daily usage
|
|
35
|
+
table.add_row(
|
|
36
|
+
"Daily",
|
|
37
|
+
str(usage.daily.used),
|
|
38
|
+
str(usage.daily.limit),
|
|
39
|
+
str(usage.daily.remaining),
|
|
40
|
+
usage.daily.reset_at.strftime("%Y-%m-%d %H:%M:%S UTC")
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Add hourly usage
|
|
44
|
+
table.add_row(
|
|
45
|
+
"Hourly",
|
|
46
|
+
str(usage.hourly.used),
|
|
47
|
+
str(usage.hourly.limit),
|
|
48
|
+
str(usage.hourly.remaining),
|
|
49
|
+
usage.hourly.reset_at.strftime("%Y-%m-%d %H:%M:%S UTC")
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
console.print(table)
|
|
53
|
+
|
|
54
|
+
# Show API key expiration information
|
|
55
|
+
try:
|
|
56
|
+
# Sleep to wait for usage is saved in the background of the DB
|
|
57
|
+
if sleep > 0:
|
|
58
|
+
time.sleep(sleep)
|
|
59
|
+
|
|
60
|
+
token_info = compiler.validate_api_key()
|
|
61
|
+
if token_info.valid and token_info.expiration:
|
|
62
|
+
print()
|
|
63
|
+
expiry_table = Table(title="API Key Information", show_header=True, header_style="bold magenta")
|
|
64
|
+
expiry_table.add_column("Property", style="cyan", no_wrap=True)
|
|
65
|
+
expiry_table.add_column("Value", style="white")
|
|
66
|
+
|
|
67
|
+
# Calculate days remaining
|
|
68
|
+
now = datetime.now()
|
|
69
|
+
days_remaining = (token_info.expiration - now).days
|
|
70
|
+
hours_remaining = (token_info.expiration - now).total_seconds() / 3600
|
|
71
|
+
|
|
72
|
+
# Format expiration time
|
|
73
|
+
expiry_str = token_info.expiration.strftime("%Y-%m-%d %H:%M:%S")
|
|
74
|
+
|
|
75
|
+
# Add rows
|
|
76
|
+
expiry_table.add_row("Expires At", expiry_str)
|
|
77
|
+
|
|
78
|
+
if days_remaining > 0:
|
|
79
|
+
expiry_table.add_row("Days Remaining", f"{days_remaining} days")
|
|
80
|
+
elif hours_remaining > 0:
|
|
81
|
+
expiry_table.add_row("Hours Remaining", f"{hours_remaining:.1f} hours")
|
|
82
|
+
else:
|
|
83
|
+
expiry_table.add_row("Status", "[red]EXPIRED[/red]")
|
|
84
|
+
|
|
85
|
+
console.print(expiry_table)
|
|
86
|
+
except (AttributeError, ValueError, TypeError) as e:
|
|
87
|
+
print()
|
|
88
|
+
console.print(f"[yellow]⚠[/yellow] Could not validate API key expiration: {str(e)}")
|
|
89
|
+
console.print("[dim]API key information unavailable[/dim]")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# noinspection PyShadowingBuiltins
|
|
93
|
+
@app.command()
|
|
94
|
+
def compile(
|
|
95
|
+
script: Path = typer.Argument(
|
|
96
|
+
None, file_okay=True, dir_okay=False,
|
|
97
|
+
help="Path to Pine Script file (.pine extension) or name of script in [cyan]scripts[/cyan] directory"
|
|
98
|
+
),
|
|
99
|
+
output: Path | None = typer.Option(
|
|
100
|
+
None, "--output", "-o",
|
|
101
|
+
help="Output Python file path (defaults to same name with .py extension)"
|
|
102
|
+
),
|
|
103
|
+
strict: bool = typer.Option(
|
|
104
|
+
False, "--strict", '-s',
|
|
105
|
+
help="Enable strict compilation mode with enhanced error checking"
|
|
106
|
+
),
|
|
107
|
+
force: bool = typer.Option(
|
|
108
|
+
False, "--force", "-f",
|
|
109
|
+
help="Force recompilation even if output file is up-to-date"
|
|
110
|
+
),
|
|
111
|
+
api_key: str | None = typer.Option(
|
|
112
|
+
None, "--api-key", "-a",
|
|
113
|
+
help="PyneSys API key (overrides configuration file)",
|
|
114
|
+
envvar="PYNESYS_API_KEY"
|
|
115
|
+
),
|
|
116
|
+
show_usage: bool = typer.Option(
|
|
117
|
+
False, "--usage", "-u",
|
|
118
|
+
help="Print API usage statistics after compilation"
|
|
119
|
+
)
|
|
120
|
+
):
|
|
121
|
+
"""
|
|
122
|
+
Compile Pine Script to Python using PyneSys API.
|
|
123
|
+
|
|
124
|
+
The system automatically searches for the workdir folder in the current and parent directories.
|
|
125
|
+
If not found, it creates or uses a workdir folder in the current directory.
|
|
126
|
+
|
|
127
|
+
Only version 6 is supported (no v4 or v5 support).
|
|
128
|
+
API key can be provided via --api-key or via config file: [cyan]workdir/config/api.toml[/cyan].
|
|
129
|
+
|
|
130
|
+
If no script is provided, will print usage statistics and exit.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
# Read api.toml configuration
|
|
134
|
+
api_config = {}
|
|
135
|
+
try:
|
|
136
|
+
with open(app_state.config_dir / 'api.toml', 'rb') as f:
|
|
137
|
+
api_config = tomllib.load(f)['api']
|
|
138
|
+
except KeyError:
|
|
139
|
+
console.print("[red]Invalid API config file (api.toml)![/red]")
|
|
140
|
+
raise typer.Exit(1)
|
|
141
|
+
except FileNotFoundError:
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
# Override API key if provided
|
|
145
|
+
if api_key:
|
|
146
|
+
api_config['api_key'] = api_key
|
|
147
|
+
|
|
148
|
+
# Override API URL if provided via environment variable
|
|
149
|
+
api_url = os.getenv("PYNESYS_API_URL")
|
|
150
|
+
if api_url:
|
|
151
|
+
api_config['base_url'] = api_url
|
|
152
|
+
|
|
153
|
+
# Create the compiler instance
|
|
154
|
+
compiler = PyneComp(**api_config)
|
|
155
|
+
|
|
156
|
+
# Ensure script was provided
|
|
157
|
+
if not script:
|
|
158
|
+
_print_usage(compiler)
|
|
159
|
+
raise typer.Exit(0)
|
|
160
|
+
|
|
161
|
+
# Ensure .py extension
|
|
162
|
+
if script.suffix != ".pine":
|
|
163
|
+
script = script.with_suffix(".pine")
|
|
164
|
+
# Expand script path
|
|
165
|
+
if len(script.parts) == 1:
|
|
166
|
+
script = app_state.scripts_dir / script
|
|
167
|
+
|
|
168
|
+
# Determine output path
|
|
169
|
+
out_path: Path = output if output is not None else script.with_suffix('.py')
|
|
170
|
+
|
|
171
|
+
# Check if compilation is needed (smart compilation)
|
|
172
|
+
if not compiler.needs_compilation(script, out_path) and not force:
|
|
173
|
+
console.print(f"[green]✓[/green] Output file is up-to-date: {output}")
|
|
174
|
+
console.print("[dim]Use --force to recompile anyway[/dim]")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
# Compile script
|
|
178
|
+
with APIErrorHandler(console):
|
|
179
|
+
with Progress(
|
|
180
|
+
SpinnerColumn(finished_text="[green]✓"),
|
|
181
|
+
TextColumn("[progress.description]{task.description}"),
|
|
182
|
+
console=console
|
|
183
|
+
) as progress:
|
|
184
|
+
task = progress.add_task("Compiling Pine Script...", total=1)
|
|
185
|
+
|
|
186
|
+
# Compile the .pine file to .py
|
|
187
|
+
out_path = compiler.compile(script, out_path, force=force, strict=strict)
|
|
188
|
+
|
|
189
|
+
progress.update(task, completed=1)
|
|
190
|
+
|
|
191
|
+
# Preserve modification time from source file
|
|
192
|
+
copy_mtime(script, out_path)
|
|
193
|
+
|
|
194
|
+
console.print(f"The compiled script is located at: [cyan]{out_path}[/cyan]")
|
|
195
|
+
|
|
196
|
+
if show_usage:
|
|
197
|
+
print()
|
|
198
|
+
_print_usage(compiler, 1.0)
|