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
pynecore/lib/line.py
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
from copy import copy as _copy
|
|
2
|
+
from typing import Any, overload
|
|
3
|
+
|
|
4
|
+
from ..core.module_property import module_property
|
|
5
|
+
from ..types.chart import ChartPoint
|
|
6
|
+
from ..types.base import next_vid
|
|
7
|
+
from ..types.line import LineEnum, Line
|
|
8
|
+
from ..types.na import NA, na_int, na_float
|
|
9
|
+
from ..types.pine_types import PyneFloat, PyneInt
|
|
10
|
+
from ..lib import xloc as _xloc, extend as _extend, color as _color
|
|
11
|
+
from ..lib import linefill as _linefill
|
|
12
|
+
from .. import lib
|
|
13
|
+
|
|
14
|
+
_registry: dict[Line, None] = {}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _remove(line_obj: Line) -> None:
|
|
18
|
+
"""Remove a line and every linefill referencing it (Pine deletes a linefill
|
|
19
|
+
when either of its lines is deleted, including count-limit eviction)."""
|
|
20
|
+
_registry.pop(line_obj, None)
|
|
21
|
+
_linefill._registry[:] = [lf for lf in _linefill._registry
|
|
22
|
+
if lf.line1 is not line_obj and lf.line2 is not line_obj]
|
|
23
|
+
|
|
24
|
+
style_arrow_both = LineEnum('ab')
|
|
25
|
+
style_arrow_left = LineEnum('al')
|
|
26
|
+
style_arrow_right = LineEnum('ar')
|
|
27
|
+
style_dashed = LineEnum('dsh')
|
|
28
|
+
style_dotted = LineEnum('dot')
|
|
29
|
+
style_solid = LineEnum('sol')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@overload
|
|
33
|
+
def new(first_point: ChartPoint, second_point: ChartPoint, xloc: _xloc.XLoc = _xloc.bar_index,
|
|
34
|
+
extend: _extend.Extend = _extend.none, color: _color.Color = _color.blue,
|
|
35
|
+
style: LineEnum = style_solid, width: int = 1, force_overlay: bool = False) -> Line: ...
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@overload
|
|
39
|
+
def new(x1: int | float, y1: float, x2: int | float, y2: float,
|
|
40
|
+
xloc: _xloc.XLoc = _xloc.bar_index, extend: _extend.Extend = _extend.none,
|
|
41
|
+
color: _color.Color = _color.blue, style: LineEnum = style_solid,
|
|
42
|
+
width: int = 1, force_overlay: bool = False) -> Line: ...
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Positional parameter orders of the two Pine call shapes; ``new()`` maps ``*args``
|
|
46
|
+
# onto one of these depending on whether the first positional is a ``chart.point``.
|
|
47
|
+
_POINT_PARAMS = ('first_point', 'second_point', 'xloc', 'extend', 'color', 'style',
|
|
48
|
+
'width', 'force_overlay')
|
|
49
|
+
_COORD_PARAMS = ('x1', 'y1', 'x2', 'y2', 'xloc', 'extend', 'color', 'style',
|
|
50
|
+
'width', 'force_overlay')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# noinspection PyProtectedMember
|
|
54
|
+
def new(*args: Any, **kwargs: Any) -> Line:
|
|
55
|
+
"""
|
|
56
|
+
Creates a new line object.
|
|
57
|
+
|
|
58
|
+
Two call shapes are accepted (Pine-compatible):
|
|
59
|
+
- ``line.new(first_point, second_point, ...)`` where both arguments are ``chart.point`` objects.
|
|
60
|
+
- ``line.new(x1, y1, x2, y2, ...)`` where ``x1`` / ``x2`` are bar index
|
|
61
|
+
(``xloc.bar_index``) or bar UNIX time in milliseconds (``xloc.bar_time``),
|
|
62
|
+
and ``y1`` / ``y2`` are prices. Float ``x1`` / ``x2`` are truncated to int
|
|
63
|
+
to mirror Pine's implicit float-to-int conversion on ``series int`` parameters.
|
|
64
|
+
|
|
65
|
+
:param x1: Bar index / bar time of the first point (coordinate form)
|
|
66
|
+
:param y1: Price of the first point (coordinate form)
|
|
67
|
+
:param x2: Bar index / bar time of the second point (coordinate form only)
|
|
68
|
+
:param y2: Price of the second point (coordinate form only)
|
|
69
|
+
:param xloc: Possible values: ``xloc.bar_index`` and ``xloc.bar_time``
|
|
70
|
+
:param extend: If ``extend=extend.none``, draws segment from (x1, y1) to (x2, y2)
|
|
71
|
+
:param color: Line color
|
|
72
|
+
:param style: Line style. Possible values: ``line.style_solid``, ``line.style_dotted``,
|
|
73
|
+
``line.style_dashed``, ``line.style_arrow_left``, ``line.style_arrow_right``,
|
|
74
|
+
``line.style_arrow_both``
|
|
75
|
+
:param width: Line width in pixels
|
|
76
|
+
:param force_overlay: If true, the drawing will display on the main chart pane
|
|
77
|
+
:param first_point: First ``chart.point`` (point form, keyword equivalent of the first positional)
|
|
78
|
+
:param second_point: Second ``chart.point`` (point form, keyword equivalent of the second positional)
|
|
79
|
+
:return: A line object
|
|
80
|
+
"""
|
|
81
|
+
if args:
|
|
82
|
+
names = _POINT_PARAMS if isinstance(args[0], ChartPoint) else _COORD_PARAMS
|
|
83
|
+
if len(args) > len(names):
|
|
84
|
+
raise TypeError(f"line.new() takes at most {len(names)} positional arguments")
|
|
85
|
+
for name, value in zip(names, args):
|
|
86
|
+
if name in kwargs:
|
|
87
|
+
raise TypeError(f"line.new() got multiple values for argument '{name}'")
|
|
88
|
+
kwargs[name] = value
|
|
89
|
+
first_point = kwargs.get('first_point')
|
|
90
|
+
second_point = kwargs.get('second_point')
|
|
91
|
+
xloc = kwargs.get('xloc', _xloc.bar_index)
|
|
92
|
+
extend = kwargs.get('extend', _extend.none)
|
|
93
|
+
color = kwargs.get('color', _color.blue)
|
|
94
|
+
style = kwargs.get('style', style_solid)
|
|
95
|
+
width = kwargs.get('width', 1)
|
|
96
|
+
force_overlay = kwargs.get('force_overlay', False)
|
|
97
|
+
if isinstance(first_point, ChartPoint):
|
|
98
|
+
second = second_point if isinstance(second_point, ChartPoint) else first_point
|
|
99
|
+
if xloc == _xloc.bar_time:
|
|
100
|
+
x1_val, y1_val = first_point.time, first_point.price
|
|
101
|
+
x2_val, y2_val = second.time, second.price
|
|
102
|
+
else:
|
|
103
|
+
x1_val, y1_val = first_point.index, first_point.price
|
|
104
|
+
x2_val, y2_val = second.index, second.price
|
|
105
|
+
else:
|
|
106
|
+
x1 = kwargs.get('x1')
|
|
107
|
+
y1 = kwargs.get('y1')
|
|
108
|
+
x2 = kwargs.get('x2')
|
|
109
|
+
y2 = kwargs.get('y2')
|
|
110
|
+
x1_val = int(x1) if isinstance(x1, (int, float)) and x1 == x1 else na_int
|
|
111
|
+
y1_val = y1 if isinstance(y1, (int, float)) else na_float
|
|
112
|
+
x2_val = int(x2) if isinstance(x2, (int, float)) and x2 == x2 else na_int
|
|
113
|
+
y2_val = y2 if isinstance(y2, (int, float)) else na_float
|
|
114
|
+
|
|
115
|
+
line_obj = Line(
|
|
116
|
+
x1=x1_val,
|
|
117
|
+
y1=y1_val,
|
|
118
|
+
x2=x2_val,
|
|
119
|
+
y2=y2_val,
|
|
120
|
+
xloc=xloc,
|
|
121
|
+
extend=extend,
|
|
122
|
+
color=color,
|
|
123
|
+
style=style or style_solid,
|
|
124
|
+
width=width,
|
|
125
|
+
force_overlay=force_overlay
|
|
126
|
+
)
|
|
127
|
+
line_obj.vid = next_vid()
|
|
128
|
+
_registry[line_obj] = None
|
|
129
|
+
# Enforce Pine's max_lines_count cap: drop the oldest line (FIFO) past the limit.
|
|
130
|
+
# A security child never sets ``lib._script``; fall back to TV's hard maximum
|
|
131
|
+
# (500) there, otherwise the registry grows without bound (the child re-runs
|
|
132
|
+
# main() for every bar of its own series, accumulating every drawing ever made).
|
|
133
|
+
if len(_registry) > (lib._script.max_lines_count if lib._script is not None else 500):
|
|
134
|
+
_remove(next(iter(_registry)))
|
|
135
|
+
return line_obj
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# noinspection PyShadowingBuiltins
|
|
139
|
+
@module_property
|
|
140
|
+
def all() -> list[Line]:
|
|
141
|
+
"""Returns all line objects"""
|
|
142
|
+
return list(_registry)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# noinspection PyShadowingBuiltins
|
|
146
|
+
def delete(id):
|
|
147
|
+
"""Delete line object"""
|
|
148
|
+
if isinstance(id, NA):
|
|
149
|
+
return
|
|
150
|
+
_remove(id)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# noinspection PyShadowingBuiltins,PyProtectedMember
|
|
154
|
+
def copy(id):
|
|
155
|
+
"""Copy line object"""
|
|
156
|
+
if isinstance(id, NA):
|
|
157
|
+
return NA(Line)
|
|
158
|
+
clone = _copy(id)
|
|
159
|
+
clone.vid = next_vid()
|
|
160
|
+
_registry[clone] = None
|
|
161
|
+
if len(_registry) > (lib._script.max_lines_count if lib._script is not None else 500):
|
|
162
|
+
_remove(next(iter(_registry)))
|
|
163
|
+
return clone
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# noinspection PyShadowingBuiltins
|
|
167
|
+
def get_x1(id: Line) -> PyneInt:
|
|
168
|
+
"""
|
|
169
|
+
Returns UNIX time or bar index (depending on the last xloc value set) of the first point of the line.
|
|
170
|
+
|
|
171
|
+
:param id: Line object
|
|
172
|
+
:return: UNIX timestamp (in milliseconds) or bar index
|
|
173
|
+
"""
|
|
174
|
+
if isinstance(id, NA):
|
|
175
|
+
return NA(int)
|
|
176
|
+
return id.x1
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# noinspection PyShadowingBuiltins
|
|
180
|
+
def get_y1(id: Line) -> PyneFloat:
|
|
181
|
+
"""
|
|
182
|
+
Returns price of the first point of the line.
|
|
183
|
+
|
|
184
|
+
:param id: Line object
|
|
185
|
+
:return: Price of the first point
|
|
186
|
+
"""
|
|
187
|
+
if isinstance(id, NA):
|
|
188
|
+
return na_float
|
|
189
|
+
return id.y1
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# noinspection PyShadowingBuiltins
|
|
193
|
+
def get_x2(id: Line) -> PyneInt:
|
|
194
|
+
"""
|
|
195
|
+
Returns UNIX time or bar index (depending on the last xloc value set) of the second point of the line.
|
|
196
|
+
|
|
197
|
+
:param id: Line object
|
|
198
|
+
:return: UNIX timestamp (in milliseconds) or bar index
|
|
199
|
+
"""
|
|
200
|
+
if isinstance(id, NA):
|
|
201
|
+
return NA(int)
|
|
202
|
+
return id.x2
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# noinspection PyShadowingBuiltins
|
|
206
|
+
def get_y2(id: Line) -> PyneFloat:
|
|
207
|
+
"""
|
|
208
|
+
Returns price of the second point of the line.
|
|
209
|
+
|
|
210
|
+
:param id: Line object
|
|
211
|
+
:return: Price of the second point
|
|
212
|
+
"""
|
|
213
|
+
if isinstance(id, NA):
|
|
214
|
+
return na_float
|
|
215
|
+
return id.y2
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# noinspection PyShadowingBuiltins
|
|
219
|
+
def set_color(id: Line, color: _color.Color) -> None:
|
|
220
|
+
"""
|
|
221
|
+
Sets the line color
|
|
222
|
+
|
|
223
|
+
:param id: Line object
|
|
224
|
+
:param color: New line color
|
|
225
|
+
"""
|
|
226
|
+
if isinstance(id, NA):
|
|
227
|
+
return
|
|
228
|
+
id.color = color
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# noinspection PyShadowingBuiltins
|
|
232
|
+
def set_extend(id: Line, extend: _extend.Extend) -> None:
|
|
233
|
+
"""
|
|
234
|
+
Sets extending type of this line object
|
|
235
|
+
|
|
236
|
+
:param id: Line object
|
|
237
|
+
:param extend: New extending type
|
|
238
|
+
"""
|
|
239
|
+
if isinstance(id, NA):
|
|
240
|
+
return
|
|
241
|
+
id.extend = extend
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
# noinspection PyShadowingBuiltins
|
|
245
|
+
def set_first_point(id: Line, point: ChartPoint) -> None:
|
|
246
|
+
"""
|
|
247
|
+
Sets the first point of the id line to point
|
|
248
|
+
|
|
249
|
+
:param id: A line object
|
|
250
|
+
:param point: A chart.point object
|
|
251
|
+
"""
|
|
252
|
+
if isinstance(id, NA):
|
|
253
|
+
return
|
|
254
|
+
if id.xloc == _xloc.bar_time:
|
|
255
|
+
id.x1, id.y1 = point.time, point.price
|
|
256
|
+
else: # xloc.bar_index
|
|
257
|
+
id.x1, id.y1 = point.index, point.price
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# noinspection PyShadowingBuiltins
|
|
261
|
+
def set_second_point(id: Line, point: ChartPoint) -> None:
|
|
262
|
+
"""
|
|
263
|
+
Sets the second point of the id line to point
|
|
264
|
+
|
|
265
|
+
:param id: A line object
|
|
266
|
+
:param point: A chart.point object
|
|
267
|
+
"""
|
|
268
|
+
if isinstance(id, NA):
|
|
269
|
+
return
|
|
270
|
+
if id.xloc == _xloc.bar_time:
|
|
271
|
+
id.x2, id.y2 = point.time, point.price
|
|
272
|
+
else: # xloc.bar_index
|
|
273
|
+
id.x2, id.y2 = point.index, point.price
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
# noinspection PyShadowingBuiltins
|
|
277
|
+
def set_style(id: Line, style: LineEnum) -> None:
|
|
278
|
+
"""
|
|
279
|
+
Sets the line style
|
|
280
|
+
|
|
281
|
+
:param id: Line object
|
|
282
|
+
:param style: New line style
|
|
283
|
+
"""
|
|
284
|
+
if isinstance(id, NA):
|
|
285
|
+
return
|
|
286
|
+
id.style = style
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
# noinspection PyShadowingBuiltins
|
|
290
|
+
def set_width(id: Line, width: int) -> None:
|
|
291
|
+
"""
|
|
292
|
+
Sets the line width
|
|
293
|
+
|
|
294
|
+
:param id: Line object
|
|
295
|
+
:param width: New line width in pixels
|
|
296
|
+
"""
|
|
297
|
+
if isinstance(id, NA):
|
|
298
|
+
return
|
|
299
|
+
id.width = width
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# noinspection PyShadowingBuiltins
|
|
303
|
+
def set_x1(id: Line, x: int) -> None:
|
|
304
|
+
"""
|
|
305
|
+
Sets bar index or bar time (depending on the xloc) of the first point
|
|
306
|
+
|
|
307
|
+
:param id: Line object
|
|
308
|
+
:param x: Bar index or bar time
|
|
309
|
+
"""
|
|
310
|
+
if isinstance(id, NA):
|
|
311
|
+
return
|
|
312
|
+
id.x1 = x
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
# noinspection PyShadowingBuiltins
|
|
316
|
+
def set_x2(id: Line, x: int) -> None:
|
|
317
|
+
"""
|
|
318
|
+
Sets bar index or bar time (depending on the xloc) of the second point
|
|
319
|
+
|
|
320
|
+
:param id: Line object
|
|
321
|
+
:param x: Bar index or bar time
|
|
322
|
+
"""
|
|
323
|
+
if isinstance(id, NA):
|
|
324
|
+
return
|
|
325
|
+
id.x2 = x
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
# noinspection PyShadowingBuiltins
|
|
329
|
+
def set_xloc(id: Line, x1: int, x2: int, xloc: _xloc.XLoc) -> None:
|
|
330
|
+
"""
|
|
331
|
+
Sets x-location and new bar index/time values
|
|
332
|
+
|
|
333
|
+
:param id: Line object
|
|
334
|
+
:param x1: Bar index or bar time of the first point
|
|
335
|
+
:param x2: Bar index or bar time of the second point
|
|
336
|
+
:param xloc: New x-location value
|
|
337
|
+
"""
|
|
338
|
+
if isinstance(id, NA):
|
|
339
|
+
return
|
|
340
|
+
id.x1 = x1
|
|
341
|
+
id.x2 = x2
|
|
342
|
+
id.xloc = xloc
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
# noinspection PyShadowingBuiltins
|
|
346
|
+
def set_xy1(id: Line, x: int, y: float) -> None:
|
|
347
|
+
"""
|
|
348
|
+
Sets bar index/time and price of the first point
|
|
349
|
+
|
|
350
|
+
:param id: Line object
|
|
351
|
+
:param x: Bar index or bar time
|
|
352
|
+
:param y: Price
|
|
353
|
+
"""
|
|
354
|
+
if isinstance(id, NA):
|
|
355
|
+
return
|
|
356
|
+
id.x1 = x
|
|
357
|
+
id.y1 = y
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
# noinspection PyShadowingBuiltins
|
|
361
|
+
def set_xy2(id: Line, x: int, y: float) -> None:
|
|
362
|
+
"""
|
|
363
|
+
Sets bar index/time and price of the second point
|
|
364
|
+
|
|
365
|
+
:param id: Line object
|
|
366
|
+
:param x: Bar index or bar time
|
|
367
|
+
:param y: Price
|
|
368
|
+
"""
|
|
369
|
+
if isinstance(id, NA):
|
|
370
|
+
return
|
|
371
|
+
id.x2 = x
|
|
372
|
+
id.y2 = y
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
# noinspection PyShadowingBuiltins
|
|
376
|
+
def set_y1(id: Line, y: float) -> None:
|
|
377
|
+
"""
|
|
378
|
+
Sets price of the first point
|
|
379
|
+
|
|
380
|
+
:param id: Line object
|
|
381
|
+
:param y: Price
|
|
382
|
+
"""
|
|
383
|
+
if isinstance(id, NA):
|
|
384
|
+
return
|
|
385
|
+
id.y1 = y
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
# noinspection PyShadowingBuiltins
|
|
389
|
+
def set_y2(id: Line, y: float) -> None:
|
|
390
|
+
"""
|
|
391
|
+
Sets price of the second point
|
|
392
|
+
|
|
393
|
+
:param id: Line object
|
|
394
|
+
:param y: Price
|
|
395
|
+
"""
|
|
396
|
+
if isinstance(id, NA):
|
|
397
|
+
return
|
|
398
|
+
id.y2 = y
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
# noinspection PyShadowingBuiltins
|
|
402
|
+
def get_price(id: Line, x: int) -> PyneFloat:
|
|
403
|
+
"""
|
|
404
|
+
Returns the price level of a line at a given bar index.
|
|
405
|
+
|
|
406
|
+
:param id: Line object
|
|
407
|
+
:param x: Bar index for which price is required
|
|
408
|
+
:return: Price value of line 'id' at bar index 'x'
|
|
409
|
+
:raises RuntimeError: If the line was created with xloc.bar_time instead of xloc.bar_index
|
|
410
|
+
"""
|
|
411
|
+
if isinstance(id, NA):
|
|
412
|
+
return na_float
|
|
413
|
+
|
|
414
|
+
# Check if line was created with xloc.bar_index
|
|
415
|
+
if id.xloc != _xloc.bar_index:
|
|
416
|
+
raise RuntimeError("line.get_price() can only be called for lines created using 'xloc.bar_index'")
|
|
417
|
+
|
|
418
|
+
# Line is considered to have been created using 'extend=extend.both'
|
|
419
|
+
# Calculate the slope of the line
|
|
420
|
+
x1, y1 = id.x1, id.y1
|
|
421
|
+
x2, y2 = id.x2, id.y2
|
|
422
|
+
|
|
423
|
+
# Handle vertical line case (x1 == x2)
|
|
424
|
+
if x1 == x2:
|
|
425
|
+
# For vertical lines, return y1 for any x
|
|
426
|
+
return y1
|
|
427
|
+
|
|
428
|
+
# Calculate price using linear interpolation/extrapolation
|
|
429
|
+
# Formula: y = y1 + (y2 - y1) * (x - x1) / (x2 - x1)
|
|
430
|
+
slope = (y2 - y1) / (x2 - x1)
|
|
431
|
+
price = y1 + slope * (x - x1)
|
|
432
|
+
|
|
433
|
+
return price
|
pynecore/lib/linefill.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from ..types.base import next_vid
|
|
2
|
+
from ..types.linefill import LineFill
|
|
3
|
+
from ..types.line import Line
|
|
4
|
+
from ..types.na import NA
|
|
5
|
+
from ..lib import color as _color
|
|
6
|
+
|
|
7
|
+
_registry: list[LineFill] = []
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# noinspection PyShadowingBuiltins
|
|
11
|
+
def new(line1: Line, line2: Line, color: _color.Color) -> LineFill:
|
|
12
|
+
"""
|
|
13
|
+
Creates a new linefill object and displays it on the chart, filling the space between line1 and
|
|
14
|
+
line2 with the color specified in color.
|
|
15
|
+
|
|
16
|
+
:param line1: First line object
|
|
17
|
+
:param line2: Second line object
|
|
18
|
+
:param color: The color used to fill the space between the lines
|
|
19
|
+
:return: The ID of a linefill object that can be passed to other linefill.*() functions
|
|
20
|
+
"""
|
|
21
|
+
if isinstance(line1, NA) or isinstance(line2, NA):
|
|
22
|
+
return NA(LineFill)
|
|
23
|
+
|
|
24
|
+
# Pine allows only one linefill per pair of lines: a successive ``linefill.new()``
|
|
25
|
+
# call for the same pair replaces the previous fill.
|
|
26
|
+
for existing in _registry:
|
|
27
|
+
if ((existing.line1 is line1 and existing.line2 is line2)
|
|
28
|
+
or (existing.line1 is line2 and existing.line2 is line1)):
|
|
29
|
+
_registry.remove(existing)
|
|
30
|
+
break
|
|
31
|
+
|
|
32
|
+
linefill_obj = LineFill(
|
|
33
|
+
line1=line1,
|
|
34
|
+
line2=line2,
|
|
35
|
+
color=color
|
|
36
|
+
)
|
|
37
|
+
linefill_obj.vid = next_vid()
|
|
38
|
+
_registry.append(linefill_obj)
|
|
39
|
+
return linefill_obj
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# noinspection PyShadowingBuiltins
|
|
43
|
+
def delete(id: LineFill) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Deletes the specified linefill object. If it has already been deleted, does nothing.
|
|
46
|
+
|
|
47
|
+
:param id: A linefill object
|
|
48
|
+
"""
|
|
49
|
+
if isinstance(id, NA):
|
|
50
|
+
return
|
|
51
|
+
try:
|
|
52
|
+
_registry.remove(id)
|
|
53
|
+
except ValueError:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# noinspection PyShadowingBuiltins
|
|
58
|
+
def get_line1(id: LineFill) -> Line:
|
|
59
|
+
"""
|
|
60
|
+
Returns the ID of the first line used in the id linefill.
|
|
61
|
+
|
|
62
|
+
:param id: A linefill object
|
|
63
|
+
:return: First line object
|
|
64
|
+
"""
|
|
65
|
+
if isinstance(id, NA):
|
|
66
|
+
return NA(Line)
|
|
67
|
+
return id.line1
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# noinspection PyShadowingBuiltins
|
|
71
|
+
def get_line2(id: LineFill) -> Line:
|
|
72
|
+
"""
|
|
73
|
+
Returns the ID of the second line used in the id linefill.
|
|
74
|
+
|
|
75
|
+
:param id: A linefill object
|
|
76
|
+
:return: Second line object
|
|
77
|
+
"""
|
|
78
|
+
if isinstance(id, NA):
|
|
79
|
+
return NA(Line)
|
|
80
|
+
return id.line2
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# noinspection PyShadowingBuiltins
|
|
84
|
+
def set_color(id: LineFill, color: _color.Color) -> None:
|
|
85
|
+
"""
|
|
86
|
+
The function sets the color of the linefill object passed to it.
|
|
87
|
+
|
|
88
|
+
:param id: A linefill object
|
|
89
|
+
:param color: The color of the linefill object
|
|
90
|
+
"""
|
|
91
|
+
if isinstance(id, NA):
|
|
92
|
+
return
|
|
93
|
+
id.color = color
|