programgarden 2.6.0__tar.gz → 2.6.1__tar.gz
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.
- {programgarden-2.6.0 → programgarden-2.6.1}/PKG-INFO +6 -2
- {programgarden-2.6.0 → programgarden-2.6.1}/README.md +4 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/executor.py +25 -5
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resolver.py +24 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/pyproject.toml +2 -2
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/binding_validator.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/client.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/code_worker.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/context.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/adjustment_delivery.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/broker_evidence.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/broker_order_totals.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/broker_snapshot.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/checkpoint_manager.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/db_naming.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/execution_storage.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/fill_reconciler.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/order_cancellation.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/order_recovery.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/owned_order_cancellation.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/position_reconciliation.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/query_builder.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/sqlite_scope.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/workflow_position_tracker.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/workflow_risk_tracker.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/deep_fixtures.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/futures_contract_info.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/futures_orderable.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/futures_pnl.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/futures_read_evidence.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/incremental_build.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/managed_order_control.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/node_runner.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/order_lifecycle.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/plugin/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/plugin/sandbox.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/providers/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/providers/llm_errors.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/providers/llm_provider.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/reconnect_handler.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_contracts.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_events.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_external.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_order_adapter.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_orders.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_scenarios.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_semantics.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_sources.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_sqlite.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/replay_triggers.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resource/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resource/context.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resource/limiter.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resource/monitor.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/resource/throttle.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/semantic_rules.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/__init__.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/credential_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/definition_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/event_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/job_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/registry_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/tools/sqlite_tools.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/validation_recommender.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/validation_replay.py +0 -0
- {programgarden-2.6.0 → programgarden-2.6.1}/programgarden/valuation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: programgarden
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.1
|
|
4
4
|
Summary: ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진
|
|
5
5
|
License-Expression: AGPL-3.0-or-later
|
|
6
6
|
Author: 프로그램동산
|
|
@@ -16,7 +16,7 @@ Requires-Dist: croniter (>=6.0.0,<7.0.0)
|
|
|
16
16
|
Requires-Dist: litellm (>=1.40.0)
|
|
17
17
|
Requires-Dist: lxml (>=6.0.2,<7.0.0)
|
|
18
18
|
Requires-Dist: programgarden-community (>=2.3.1,<3.0.0)
|
|
19
|
-
Requires-Dist: programgarden-core (>=2.6.
|
|
19
|
+
Requires-Dist: programgarden-core (>=2.6.1,<3.0.0)
|
|
20
20
|
Requires-Dist: programgarden-finance (>=2.0.1,<3.0.0)
|
|
21
21
|
Requires-Dist: psutil (>=6.0.0,<7.0.0)
|
|
22
22
|
Requires-Dist: psycopg2-binary (>=2.9.11,<3.0.0)
|
|
@@ -29,6 +29,10 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
|
|
30
30
|
# ProgramGarden
|
|
31
31
|
|
|
32
|
+
An unreleased [stock history interval correction](../../docs/stock-history-interval-contract.md)
|
|
33
|
+
rejects unsupported intraday periods instead of silently querying daily bars.
|
|
34
|
+
Supported g3204 periods retain their existing requests and output contract.
|
|
35
|
+
|
|
32
36
|
An unreleased [futures detail and durable state candidate](../../docs/futures-contract-details-and-rollover-state.md)
|
|
33
37
|
adds exact o3105 metadata, opt-in execution-scoped SQLite and XHKG calendar
|
|
34
38
|
intersection. Missing evidence remains explicit; this does not authorize orders.
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# ProgramGarden
|
|
2
2
|
|
|
3
|
+
An unreleased [stock history interval correction](../../docs/stock-history-interval-contract.md)
|
|
4
|
+
rejects unsupported intraday periods instead of silently querying daily bars.
|
|
5
|
+
Supported g3204 periods retain their existing requests and output contract.
|
|
6
|
+
|
|
3
7
|
An unreleased [futures detail and durable state candidate](../../docs/futures-contract-details-and-rollover-state.md)
|
|
4
8
|
adds exact o3105 metadata, opt-in execution-scoped SQLite and XHKG calendar
|
|
5
9
|
intersection. Missing evidence remains explicit; this does not authorize orders.
|
|
@@ -12186,7 +12186,7 @@ class HistoricalDataNodeExecutor(NodeExecutorBase):
|
|
|
12186
12186
|
HistoricalDataNode executor - 과거 OHLCV 데이터 조회
|
|
12187
12187
|
|
|
12188
12188
|
LS Finance Chart API를 사용하여 과거 차트 데이터를 조회합니다.
|
|
12189
|
-
-
|
|
12189
|
+
- Overseas stock: g3204 (daily/weekly/monthly/yearly; no intraday)
|
|
12190
12190
|
- 해외선물: o3108 (일봉), o3103 (분봉)
|
|
12191
12191
|
"""
|
|
12192
12192
|
|
|
@@ -12208,6 +12208,15 @@ class HistoricalDataNodeExecutor(NodeExecutorBase):
|
|
|
12208
12208
|
) -> Dict[str, Any]:
|
|
12209
12209
|
"""과거 데이터 조회"""
|
|
12210
12210
|
|
|
12211
|
+
# Reject unsupported stock periods before fixtures can manufacture success.
|
|
12212
|
+
# The broker-specific fetch repeats this guard for direct/legacy callers.
|
|
12213
|
+
connection = config.get("connection")
|
|
12214
|
+
product = connection.get("product") if isinstance(connection, dict) else None
|
|
12215
|
+
if node_type == "OverseasStockHistoricalDataNode" or (
|
|
12216
|
+
node_type == "HistoricalDataNode" and product in (None, "overseas_stock")
|
|
12217
|
+
):
|
|
12218
|
+
self._stock_history_gubun(config.get("interval", "1d"))
|
|
12219
|
+
|
|
12211
12220
|
# deep_validate: HistoricalDataNode hits the real LS API. Inject a fixture
|
|
12212
12221
|
# time series so the flow completes without a network call.
|
|
12213
12222
|
if context.is_deep_validate:
|
|
@@ -12451,6 +12460,18 @@ class HistoricalDataNodeExecutor(NodeExecutorBase):
|
|
|
12451
12460
|
# 파싱 실패 시 오늘 날짜 반환
|
|
12452
12461
|
return datetime.now().strftime("%Y%m%d")
|
|
12453
12462
|
|
|
12463
|
+
@staticmethod
|
|
12464
|
+
def _stock_history_gubun(interval: str) -> str:
|
|
12465
|
+
"""Reject unsupported periods instead of relabeling daily bars."""
|
|
12466
|
+
periods = {"1d": "2", "1w": "3", "1M": "4", "1Y": "5"}
|
|
12467
|
+
if not isinstance(interval, str) or interval not in periods:
|
|
12468
|
+
raise ValueError(
|
|
12469
|
+
"UNSUPPORTED_STOCK_HISTORY_INTERVAL: OverseasStockHistoricalDataNode "
|
|
12470
|
+
"supports 1d, 1w, 1M and 1Y through LS g3204. "
|
|
12471
|
+
"Intraday g3203 is not supported; select a supported period explicitly."
|
|
12472
|
+
)
|
|
12473
|
+
return periods[interval]
|
|
12474
|
+
|
|
12454
12475
|
async def _fetch_overseas_stock(
|
|
12455
12476
|
self,
|
|
12456
12477
|
symbols: List[str],
|
|
@@ -12472,6 +12493,9 @@ class HistoricalDataNodeExecutor(NodeExecutorBase):
|
|
|
12472
12493
|
반환: [{symbol, exchange, time_series: [{date, open, high, low, close, volume}, ...]}, ...]
|
|
12473
12494
|
"""
|
|
12474
12495
|
|
|
12496
|
+
# Validate before credential access or login, outside the soft-failure handler.
|
|
12497
|
+
gubun = self._stock_history_gubun(interval)
|
|
12498
|
+
|
|
12475
12499
|
credential = context.get_credential()
|
|
12476
12500
|
if not credential:
|
|
12477
12501
|
context.log("error", "Credential not set for HistoricalDataNode", node_id)
|
|
@@ -12494,10 +12518,6 @@ class HistoricalDataNodeExecutor(NodeExecutorBase):
|
|
|
12494
12518
|
|
|
12495
12519
|
api = ls.overseas_stock()
|
|
12496
12520
|
|
|
12497
|
-
# interval → gubun 변환 (g3204: 2=일, 3=주, 4=월, 5=년)
|
|
12498
|
-
gubun_map = {"1d": "2", "1w": "3", "1M": "4", "1Y": "5"}
|
|
12499
|
-
gubun = gubun_map.get(interval, "2")
|
|
12500
|
-
|
|
12501
12521
|
# 거래소 코드 매핑 (역변환용)
|
|
12502
12522
|
exchcd_to_exchange = {"82": "NASDAQ", "81": "NYSE", "83": "AMEX"}
|
|
12503
12523
|
|
|
@@ -345,6 +345,7 @@ class WorkflowResolver:
|
|
|
345
345
|
|
|
346
346
|
# Order routing choices are literals, never prices or item bindings.
|
|
347
347
|
self._validate_order_enums(workflow, registry, result)
|
|
348
|
+
self._validate_stock_history_interval(workflow, registry, result)
|
|
348
349
|
|
|
349
350
|
# 11. Static recommendations (topology analysis)
|
|
350
351
|
for rec in run_static_recommendation_rules(
|
|
@@ -362,6 +363,29 @@ class WorkflowResolver:
|
|
|
362
363
|
|
|
363
364
|
return result
|
|
364
365
|
|
|
366
|
+
def _validate_stock_history_interval(self, workflow, registry, result) -> None:
|
|
367
|
+
"""Keep static/deep validation aligned with the stock chart executor."""
|
|
368
|
+
node_type = "OverseasStockHistoricalDataNode"
|
|
369
|
+
node_class = registry.get(node_type)
|
|
370
|
+
if node_class is None:
|
|
371
|
+
return
|
|
372
|
+
field = node_class.get_field_schema()["interval"]
|
|
373
|
+
for node in workflow.nodes:
|
|
374
|
+
if node.get("type") != node_type:
|
|
375
|
+
continue
|
|
376
|
+
if node.get("interval", field.default) in field.enum_values:
|
|
377
|
+
continue
|
|
378
|
+
result.add(build_error(
|
|
379
|
+
ErrorCode.INVALID_FIELD_ENUM,
|
|
380
|
+
"Stock historical intervals require a supported LS g3204 period; "
|
|
381
|
+
"intraday g3203 is not supported.",
|
|
382
|
+
location=ErrorLocation(
|
|
383
|
+
node_id=node.get("id"), node_type=node_type, field_path="interval",
|
|
384
|
+
),
|
|
385
|
+
available_values=field.enum_values,
|
|
386
|
+
suggestion="Choose 1d, 1w, 1M or 1Y explicitly; do not substitute daily bars for an intraday strategy.",
|
|
387
|
+
))
|
|
388
|
+
|
|
365
389
|
def _validate_order_enums(self, workflow, registry, result) -> None:
|
|
366
390
|
"""Enforce fixed price/order types without changing dynamic close sides."""
|
|
367
391
|
from programgarden_core.models.field_binding import ExpressionMode
|
|
@@ -5,7 +5,7 @@ authors = [
|
|
|
5
5
|
homepage = "https://programgarden.com"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
name = "programgarden"
|
|
8
|
-
version = "2.6.
|
|
8
|
+
version = "2.6.1"
|
|
9
9
|
license = "AGPL-3.0-or-later"
|
|
10
10
|
description = "ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진"
|
|
11
11
|
readme = "README.md"
|
|
@@ -36,7 +36,7 @@ litellm = ">=1.40.0"
|
|
|
36
36
|
# 로 통째 실패한다(1.35.1 의 조용한 TypeError 보다 강한 모듈 로드 실패).
|
|
37
37
|
# (1.26.0 이후로도 context.py 는 WorkflowPnLEvent(**event_data) 에 personal_metrics
|
|
38
38
|
# 를 무조건 실으므로 그 하한 근거도 이 상한에 포함된다.)
|
|
39
|
-
programgarden-core = "^2.6.
|
|
39
|
+
programgarden-core = "^2.6.1"
|
|
40
40
|
programgarden-finance = "^2.0.1"
|
|
41
41
|
programgarden-community = "^2.3.1"
|
|
42
42
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/owned_order_cancellation.py
RENAMED
|
File without changes
|
{programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/position_reconciliation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden-2.6.0 → programgarden-2.6.1}/programgarden/database/workflow_position_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|