programgarden-core 2.5.3__tar.gz → 2.6.0__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_core-2.5.3 → programgarden_core-2.6.0}/PKG-INFO +5 -1
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/README.md +4 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/__init__.py +1 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/locales/en.json +5 -5
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/locales/ko.json +5 -5
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/market_calendar.py +11 -4
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/__init__.py +2 -0
- programgarden_core-2.6.0/programgarden_core/nodes/contract_info_futures.py +122 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data.py +10 -1
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/realtime_futures.py +9 -1
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/session_gate.py +6 -6
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/node_registry.py +2 -2
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/pyproject.toml +1 -1
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/client.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/components.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/listener.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/mixins.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/products.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/sql.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/storage.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/code_node.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/exceptions.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/evaluator.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/reference.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/translator.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/korea_alias.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/connection_rule.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/credential.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/edge.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/event.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/exchange.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/field_binding.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/job.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/order_diagnostics.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/plugin_resource.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/resilience.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/resource.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/validation.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/workflow.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/account_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/account_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/account_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/ai.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/base.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/broker.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/calculation.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/code.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/condition.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/display.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/event.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/fundamental_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/fundamental_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/infra.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/open_orders_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/open_orders_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/open_orders_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/order.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/orderable_quantity_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/portfolio.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/realtime_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/realtime_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/risk.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_futures.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_korea_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_stock.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/trigger.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/news_analyst.json +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/risk_manager.json +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/strategist.json +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/technical_analyst.json +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/__init__.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/credential_registry.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/plugin_registry.py +0 -0
- {programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/retry_executor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: programgarden-core
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: ProgramGarden Core - 노드 기반 DSL 핵심 타입 정의
|
|
5
5
|
License-Expression: AGPL-3.0-or-later
|
|
6
6
|
Author: 프로그램동산
|
|
@@ -19,6 +19,10 @@ US regular-session requests can opt into SessionGateNode.exchange_calendar (XNYS
|
|
|
19
19
|
|
|
20
20
|
# ProgramGarden Core
|
|
21
21
|
|
|
22
|
+
Unreleased schema additions: OverseasFuturesContractInfoNode, SQLiteNode's opt-in
|
|
23
|
+
storage_scope=execution, and SessionGateNode's XHKG calendar. See the
|
|
24
|
+
[runtime contract](../../docs/futures-contract-details-and-rollover-state.md).
|
|
25
|
+
|
|
22
26
|
The REST overseas-stock position catalog declares `sellable_qty`, matching the
|
|
23
27
|
broker-reported capacity preserved by the engine. Missing evidence remains null;
|
|
24
28
|
see [the contract](../../docs/overseas-stock-sellable-quantity.md).
|
|
@@ -2,6 +2,10 @@ US regular-session requests can opt into SessionGateNode.exchange_calendar (XNYS
|
|
|
2
2
|
|
|
3
3
|
# ProgramGarden Core
|
|
4
4
|
|
|
5
|
+
Unreleased schema additions: OverseasFuturesContractInfoNode, SQLiteNode's opt-in
|
|
6
|
+
storage_scope=execution, and SessionGateNode's XHKG calendar. See the
|
|
7
|
+
[runtime contract](../../docs/futures-contract-details-and-rollover-state.md).
|
|
8
|
+
|
|
5
9
|
The REST overseas-stock position catalog declares `sellable_qty`, matching the
|
|
6
10
|
broker-reported capacity preserved by the engine. Missing evidence remains null;
|
|
7
11
|
see [the contract](../../docs/overseas-stock-sellable-quantity.md).
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/locales/en.json
RENAMED
|
@@ -296,7 +296,6 @@
|
|
|
296
296
|
"fields.PerformanceReportNode.risk_free_rate": "Annual risk-free rate as a fraction (e.g. 0.02 for 2%) for Sharpe/Sortino. Default 0.",
|
|
297
297
|
"fields.HTTPRequestNode.auth_required": "Does the API require authentication? Leave unset to let the chatbot decide from context; set true for private APIs (a credential is then required), false for public APIs.",
|
|
298
298
|
"fields.HTTPRequestNode.body": "Request body for POST/PUT/PATCH. Automatically serialized to JSON.",
|
|
299
|
-
|
|
300
299
|
"fields.HTTPRequestNode.credential_id": "Credential ID for authentication. Supports: http_bearer, http_header, http_basic, http_query",
|
|
301
300
|
"fields.HTTPRequestNode.headers": "HTTP headers. Click + to add custom headers (e.g., Content-Type, X-API-Key).",
|
|
302
301
|
"fields.HTTPRequestNode.method": "HTTP method for the request",
|
|
@@ -602,7 +601,6 @@
|
|
|
602
601
|
"fieldNames.PerformanceReportNode.risk_free_rate": "Risk-Free Rate",
|
|
603
602
|
"fieldNames.HTTPRequestNode.auth_required": "Requires Auth",
|
|
604
603
|
"fieldNames.HTTPRequestNode.body": "Request Body",
|
|
605
|
-
|
|
606
604
|
"fieldNames.HTTPRequestNode.credential_id": "Credential",
|
|
607
605
|
"fieldNames.HTTPRequestNode.headers": "Headers",
|
|
608
606
|
"fieldNames.HTTPRequestNode.method": "HTTP Method",
|
|
@@ -877,7 +875,6 @@
|
|
|
877
875
|
"ports.http_request_data": "Request data",
|
|
878
876
|
"ports.http_response": "API response data",
|
|
879
877
|
"ports.http_results": "Per-item results (one {item, response, status_code, success, error} entry per iterated item)",
|
|
880
|
-
|
|
881
878
|
"ports.http_status_code": "HTTP status code",
|
|
882
879
|
"ports.http_success": "Request success flag",
|
|
883
880
|
"ports.items": "Item list",
|
|
@@ -1207,7 +1204,6 @@
|
|
|
1207
1204
|
"connection.OverseasStockBrokerNode.label": "LS Securities overseas stock account",
|
|
1208
1205
|
"connection.TelegramNode.label": "Telegram bot",
|
|
1209
1206
|
"connection_rules.realtime_to_http.reason": "Direct connection from realtime node to HTTPRequestNode is not recommended. Each tick would trigger an HTTP request, potentially hitting external API rate limits.",
|
|
1210
|
-
|
|
1211
1207
|
"connection_rules.realtime_to_http.suggestion": "Place a ThrottleNode between the realtime node and HTTP request node to control request frequency.",
|
|
1212
1208
|
"fields.BaseOrderNode.rate_limit_interval": "Minimum order interval (seconds). Default 5 seconds. The next order will only execute after this time has elapsed since the last order.",
|
|
1213
1209
|
"fields.BaseOrderNode.rate_limit_action": "Action when order interval is not met. skip: silently skip, error: raise error",
|
|
@@ -1251,6 +1247,9 @@
|
|
|
1251
1247
|
"enums.contract_selection.front": "Front month (nearest expiry)",
|
|
1252
1248
|
"enums.contract_selection.next": "Next month (roll target)",
|
|
1253
1249
|
"enums.contract_selection.quarterly": "Quarterly (Mar/Jun/Sep/Dec)",
|
|
1250
|
+
"nodes.OverseasFuturesContractInfoNode.name": "Futures Contract Details",
|
|
1251
|
+
"nodes.OverseasFuturesContractInfoNode.description": "Reads observed contract dates, margins and reported session times from the connected broker. Missing values remain unknown; no order is placed.",
|
|
1252
|
+
"fieldNames.OverseasFuturesContractInfoNode.symbol": "Futures contract",
|
|
1254
1253
|
"nodes.OverseasFuturesOrderableQuantityNode.name": "Futures Orderable Quantity",
|
|
1255
1254
|
"nodes.OverseasFuturesOrderableQuantityNode.description": "Reads contract-specific orderable quantity from the connected futures account. No order is submitted. Require verified=true and sufficient quantity before entry.",
|
|
1256
1255
|
"fieldNames.OverseasFuturesOrderableQuantityNode.symbol": "Contract",
|
|
@@ -1278,5 +1277,6 @@
|
|
|
1278
1277
|
"nodes.SessionGateNode.session_date": "Opening date of the matched window, or an empty string when blocked.",
|
|
1279
1278
|
"nodes.SessionGateNode.timezone": "IANA timezone; daylight-saving transitions use the installed timezone database.",
|
|
1280
1279
|
"nodes.SessionGateNode.trigger": "Evaluate the current local time when triggered.",
|
|
1281
|
-
"nodes.SessionGateNode.windows": "Local HH:MM start/end windows; start inclusive, end exclusive. Overnight windows are supported."
|
|
1280
|
+
"nodes.SessionGateNode.windows": "Local HH:MM start/end windows; start inclusive, end exclusive. Overnight windows are supported.",
|
|
1281
|
+
"fields.SQLiteNode.storage_scope": "Storage scope: shared filename or a durable namespace per execution."
|
|
1282
1282
|
}
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/i18n/locales/ko.json
RENAMED
|
@@ -296,7 +296,6 @@
|
|
|
296
296
|
"fields.PerformanceReportNode.risk_free_rate": "무위험 수익률(소수, 예 0.02=2%) — Sharpe/Sortino용. 기본 0.",
|
|
297
297
|
"fields.HTTPRequestNode.auth_required": "이 API 가 인증이 필요한가요? 미설정이면 챗봇이 문맥으로 판단합니다. 비공개 API 는 true(자격증명 필요), 공개 API 는 false 로 두세요.",
|
|
298
298
|
"fields.HTTPRequestNode.body": "요청 본문 (POST/PUT/PATCH용). 자동으로 JSON 직렬화됨.",
|
|
299
|
-
|
|
300
299
|
"fields.HTTPRequestNode.credential_id": "인증정보 ID. 지원: http_bearer, http_header, http_basic, http_query",
|
|
301
300
|
"fields.HTTPRequestNode.headers": "HTTP 헤더. + 버튼으로 커스텀 헤더 추가 (예: Content-Type, X-API-Key).",
|
|
302
301
|
"fields.HTTPRequestNode.method": "HTTP 요청 메서드",
|
|
@@ -602,7 +601,6 @@
|
|
|
602
601
|
"fieldNames.PerformanceReportNode.risk_free_rate": "무위험 수익률",
|
|
603
602
|
"fieldNames.HTTPRequestNode.auth_required": "인증 필요 여부",
|
|
604
603
|
"fieldNames.HTTPRequestNode.body": "요청본문",
|
|
605
|
-
|
|
606
604
|
"fieldNames.HTTPRequestNode.credential_id": "인증정보",
|
|
607
605
|
"fieldNames.HTTPRequestNode.headers": "헤더",
|
|
608
606
|
"fieldNames.HTTPRequestNode.method": "HTTP메소드",
|
|
@@ -877,7 +875,6 @@
|
|
|
877
875
|
"ports.http_request_data": "요청 데이터",
|
|
878
876
|
"ports.http_response": "API 응답 데이터",
|
|
879
877
|
"ports.http_results": "항목별 결과 (반복된 항목마다 {item, response, status_code, success, error} 한 건)",
|
|
880
|
-
|
|
881
878
|
"ports.http_status_code": "HTTP 상태 코드",
|
|
882
879
|
"ports.http_success": "요청 성공 여부",
|
|
883
880
|
"ports.items": "아이템 목록",
|
|
@@ -1207,7 +1204,6 @@
|
|
|
1207
1204
|
"connection.OverseasStockBrokerNode.label": "LS증권 해외주식 계좌",
|
|
1208
1205
|
"connection.TelegramNode.label": "텔레그램 봇",
|
|
1209
1206
|
"connection_rules.realtime_to_http.reason": "실시간 노드에서 HTTPRequestNode로의 직접 연결은 권장하지 않습니다. 틱 데이터마다 HTTP 요청이 발생하여 외부 API 제한에 걸릴 수 있습니다.",
|
|
1210
|
-
|
|
1211
1207
|
"connection_rules.realtime_to_http.suggestion": "실시간 노드와 HTTP 요청 노드 사이에 ThrottleNode를 배치하여 요청 빈도를 제어하세요.",
|
|
1212
1208
|
"fields.BaseOrderNode.rate_limit_interval": "최소 주문 간격 (초). 기본값 5초. 직전 주문 후 이 시간이 지나야 다음 주문이 실행됩니다.",
|
|
1213
1209
|
"fields.BaseOrderNode.rate_limit_action": "주문 간격 미달 시 동작. skip: 조용히 건너뜀, error: 에러 발생",
|
|
@@ -1251,6 +1247,9 @@
|
|
|
1251
1247
|
"enums.contract_selection.front": "근월물 (만기 가장 가까움)",
|
|
1252
1248
|
"enums.contract_selection.next": "차월물 (롤오버 대상)",
|
|
1253
1249
|
"enums.contract_selection.quarterly": "분기월물 (3·6·9·12월)",
|
|
1250
|
+
"nodes.OverseasFuturesContractInfoNode.name": "해외선물 종목상세 조회",
|
|
1251
|
+
"nodes.OverseasFuturesContractInfoNode.description": "연결된 증권사를 통해 선물 종목의 만기일·최종거래일·증거금·거래시간을 조회합니다. 확인되지 않은 값은 비워 두며 주문을 실행하지 않습니다.",
|
|
1252
|
+
"fieldNames.OverseasFuturesContractInfoNode.symbol": "선물 종목",
|
|
1254
1253
|
"nodes.OverseasFuturesOrderableQuantityNode.name": "해외선물 주문가능수량",
|
|
1255
1254
|
"nodes.OverseasFuturesOrderableQuantityNode.description": "연결된 해외선물 계좌에서 해당 종목의 주문가능수량을 조회합니다. 주문은 제출하지 않으며, 확인 성공 여부와 가능 수량을 확인한 뒤 진입합니다.",
|
|
1256
1255
|
"fieldNames.OverseasFuturesOrderableQuantityNode.symbol": "선물 종목",
|
|
@@ -1278,5 +1277,6 @@
|
|
|
1278
1277
|
"nodes.SessionGateNode.session_date": "허용 구간의 시작일입니다. 차단되면 빈 문자열입니다.",
|
|
1279
1278
|
"nodes.SessionGateNode.timezone": "IANA 시간대입니다. 설치된 시간대 데이터로 서머타임을 반영합니다.",
|
|
1280
1279
|
"nodes.SessionGateNode.trigger": "실행 시점의 현지 시간을 확인합니다.",
|
|
1281
|
-
"nodes.SessionGateNode.windows": "현지 HH:MM 구간입니다. 시작은 포함하고 종료는 제외하며 자정을 넘는 구간도 지원합니다."
|
|
1280
|
+
"nodes.SessionGateNode.windows": "현지 HH:MM 구간입니다. 시작은 포함하고 종료는 제외하며 자정을 넘는 구간도 지원합니다.",
|
|
1281
|
+
"fields.SQLiteNode.storage_scope": "저장 범위: 공용 파일 또는 실행별로 분리한 영구 저장 파일"
|
|
1282
1282
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Scheduled
|
|
1
|
+
"""Scheduled equity sessions, independent of credentials and live market data.
|
|
2
2
|
|
|
3
3
|
This schedule includes published holidays and early closes. It cannot observe
|
|
4
4
|
new emergency closures, instrument halts, or a broker's ability to accept orders.
|
|
@@ -19,15 +19,22 @@ def _calendar(name: str, year: int):
|
|
|
19
19
|
|
|
20
20
|
def scheduled_session_open(name: str, instant: datetime) -> bool:
|
|
21
21
|
"""Exact seconds: opening is inclusive and closing is exclusive."""
|
|
22
|
-
if name not in {"XNYS", "XNAS"}:
|
|
22
|
+
if name not in {"XNYS", "XNAS", "XHKG"}:
|
|
23
23
|
raise ValueError("Unsupported exchange calendar")
|
|
24
24
|
if instant.tzinfo is None or instant.utcoffset() is None:
|
|
25
25
|
raise ValueError("Calendar clock must include timezone")
|
|
26
|
-
|
|
26
|
+
zone = "Asia/Hong_Kong" if name == "XHKG" else "America/New_York"
|
|
27
|
+
market_date = instant.astimezone(ZoneInfo(zone)).date()
|
|
27
28
|
schedule = _calendar(name, market_date.year).schedule
|
|
28
29
|
day = market_date.isoformat()
|
|
29
30
|
if day not in schedule.index:
|
|
30
31
|
return False
|
|
31
32
|
row = schedule.loc[day]
|
|
32
33
|
clock = instant.astimezone(timezone.utc)
|
|
33
|
-
|
|
34
|
+
if not row["open"] <= clock < row["close"]:
|
|
35
|
+
return False
|
|
36
|
+
# XHKG has a scheduled midday break. NaT comparisons are false for markets
|
|
37
|
+
# without breaks; do not admit the lunch interval as an open session.
|
|
38
|
+
if "break_start" in row and row["break_start"] <= clock < row["break_end"]:
|
|
39
|
+
return False
|
|
40
|
+
return True
|
|
@@ -28,6 +28,7 @@ from programgarden_core.nodes.broker import OverseasStockBrokerNode, OverseasFut
|
|
|
28
28
|
from programgarden_core.nodes.data_stock import OverseasStockMarketDataNode
|
|
29
29
|
from programgarden_core.nodes.fundamental_stock import OverseasStockFundamentalNode
|
|
30
30
|
from programgarden_core.nodes.data_futures import OverseasFuturesMarketDataNode
|
|
31
|
+
from programgarden_core.nodes.contract_info_futures import OverseasFuturesContractInfoNode
|
|
31
32
|
from programgarden_core.nodes.backtest_stock import OverseasStockHistoricalDataNode
|
|
32
33
|
from programgarden_core.nodes.backtest_futures import OverseasFuturesHistoricalDataNode
|
|
33
34
|
from programgarden_core.nodes.realtime_stock import (
|
|
@@ -131,6 +132,7 @@ __all__ = [
|
|
|
131
132
|
"OverseasFuturesRealMarketDataNode",
|
|
132
133
|
"OverseasFuturesSymbolQueryNode",
|
|
133
134
|
"FuturesContractNode",
|
|
135
|
+
"OverseasFuturesContractInfoNode",
|
|
134
136
|
# Account - Stock (해외주식)
|
|
135
137
|
"OverseasStockAccountNode",
|
|
136
138
|
"OverseasStockRealAccountNode",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Runtime contract metadata for an exact listed overseas futures symbol."""
|
|
2
|
+
from typing import ClassVar, Dict, List, Literal, Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import Field
|
|
5
|
+
|
|
6
|
+
from programgarden_core.nodes.base import BaseNode, BrokerProvider, InputPort, NodeCategory, OutputPort, ProductScope
|
|
7
|
+
from programgarden_core.models.field_binding import ExpressionMode, FieldCategory, FieldSchema, FieldType
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
CONTRACT_INFO_FIELDS = [
|
|
11
|
+
{"name": key, "type": "string", "description": description}
|
|
12
|
+
for key, description in {
|
|
13
|
+
"symbol": "Exact observed contract symbol.",
|
|
14
|
+
"exchange": "Observed exchange code matching the request.",
|
|
15
|
+
"symbol_name": "Observed contract name; null if absent.",
|
|
16
|
+
"underlying_code": "Observed underlying product code; null if absent.",
|
|
17
|
+
"currency": "Observed contract currency; null if absent.",
|
|
18
|
+
"maturity_date": "LS MtrtDt, YYYY-MM-DD; null if missing or invalid.",
|
|
19
|
+
"last_trading_date": "LS FnlDlDt, YYYY-MM-DD; distinct from maturity; null if unknown.",
|
|
20
|
+
"first_notice_date": "LS FstTrsfrDt, YYYY-MM-DD; null if unknown or not supplied.",
|
|
21
|
+
"master_received_date": "LS ApplDate, YYYY-MM-DD; not proof of future calendar coverage.",
|
|
22
|
+
"korea_start_date": "LS DlDt date, YYYY-MM-DD.",
|
|
23
|
+
"korea_start_time": "LS DlStrtTm time, HH:MM:SS; a reported session, not all trading windows.",
|
|
24
|
+
"korea_end_time": "LS DlEndTm time, HH:MM:SS; no end date is inferred.",
|
|
25
|
+
"local_start_date": "LS OvsStrDay date, YYYY-MM-DD.",
|
|
26
|
+
"local_start_time": "LS OvsStrTm time, HH:MM:SS.",
|
|
27
|
+
"local_end_date": "LS OvsEndDay date, YYYY-MM-DD.",
|
|
28
|
+
"local_end_time": "LS OvsEndTm time, HH:MM:SS.",
|
|
29
|
+
"trade_status_code": "Raw LS DlPsblCd; no undocumented enum interpretation.",
|
|
30
|
+
"source_tr": "o3105.",
|
|
31
|
+
"observed_at": "UTC time of this observation, ISO8601; not a broker data timestamp.",
|
|
32
|
+
}.items()
|
|
33
|
+
] + [
|
|
34
|
+
{"name": key, "type": "number", "description": description}
|
|
35
|
+
for key, description in {
|
|
36
|
+
"initial_margin": "Observed OpngMgn; null if absent/invalid. Not account order capacity.",
|
|
37
|
+
"maintenance_margin": "Observed MntncMgn; null if absent/invalid.",
|
|
38
|
+
"tick_size": "Observed positive UntPrc; null if unavailable.",
|
|
39
|
+
"tick_value": "Observed positive MnChgAmt; null if unavailable.",
|
|
40
|
+
}.items()
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class OverseasFuturesContractInfoNode(BaseNode):
|
|
45
|
+
type: Literal["OverseasFuturesContractInfoNode"] = "OverseasFuturesContractInfoNode"
|
|
46
|
+
category: NodeCategory = NodeCategory.MARKET
|
|
47
|
+
description: str = "i18n:nodes.OverseasFuturesContractInfoNode.description"
|
|
48
|
+
_product_scope: ClassVar[ProductScope] = ProductScope.FUTURES
|
|
49
|
+
_broker_provider: ClassVar[BrokerProvider] = BrokerProvider.LS
|
|
50
|
+
_version: ClassVar[str] = "1.0.0"
|
|
51
|
+
_updated_at: ClassVar[str] = "2026-10-03"
|
|
52
|
+
_change_note: ClassVar[str] = "Read native futures contract dates, margins and reported sessions without placing an order."
|
|
53
|
+
|
|
54
|
+
symbol: Optional[Dict[str, str]] = Field(default=None, description="Exact listed contract identity: symbol and exchange.")
|
|
55
|
+
_inputs: List[InputPort] = [InputPort(name="trigger", type="signal", required=False, description="Refresh after resolving the contract.")]
|
|
56
|
+
_outputs: List[OutputPort] = [
|
|
57
|
+
OutputPort(name="value", type="object", fields=CONTRACT_INFO_FIELDS, description="Observed contract details; null when the query fails. Optional fields remain null."),
|
|
58
|
+
OutputPort(name="verified", type="boolean", description="Successful response with matching symbol/exchange; not completeness of all optional fields."),
|
|
59
|
+
OutputPort(name="missing_fields", type="array", description="Optional output fields absent or invalid in the broker response."),
|
|
60
|
+
OutputPort(name="error", type="string", description="Safe failure reason; null for a matching successful response."),
|
|
61
|
+
]
|
|
62
|
+
_usage: ClassVar[dict] = {
|
|
63
|
+
"when_to_use": ["Inspect runtime maturity/last-trading/notice dates, margins, currency and reported session times for an exact futures contract."],
|
|
64
|
+
"when_not_to_use": ["Selecting front/next months (FuturesContractNode), confirming fills, computing a holiday calendar or authorizing an order."],
|
|
65
|
+
"typical_scenarios": ["FuturesContractNode → OverseasFuturesContractInfoNode → date guard; account-held symbol → detail → rollover eligibility."],
|
|
66
|
+
}
|
|
67
|
+
_features: ClassVar[list] = [
|
|
68
|
+
"One read-only o3105 request; no model call, positive quote requirement or order submission.",
|
|
69
|
+
"Always reads one explicit symbol object; upstream arrays do not repeat the request. Use SplitNode and bind nodes.split.item for an explicit batch.",
|
|
70
|
+
"Missing dates/numbers remain null; source dates are never guessed from the contract month.",
|
|
71
|
+
"Deep validation uses synthetic data; replay uses recorded SDK responses through the same parser.",
|
|
72
|
+
]
|
|
73
|
+
_node_guide: ClassVar[dict] = {
|
|
74
|
+
"input_handling": "Bind one {symbol, exchange} object, with an ordering edge from its producer and an upstream futures broker. Use the actual held contract for rollover, which may differ from today's front month.",
|
|
75
|
+
"output_consumption": "Require verified=true and the specific non-null fields the decision needs. Dates use YYYY-MM-DD. Session times describe the returned session only; use an authoritative calendar for holidays/trading-day offsets. Confirm close fills before reopening.",
|
|
76
|
+
"pitfalls": ["verified does not assert every optional field exists. Initial margin is not available account capacity. Neither dates nor raw trade status prove the exchange is currently open."],
|
|
77
|
+
"common_combinations": ["FuturesContractNode, OverseasFuturesAccountNode, CodeNode, OverseasFuturesOrderableQuantityNode."],
|
|
78
|
+
}
|
|
79
|
+
_anti_patterns: ClassVar[list] = [{"pattern": "Guess missing expiry from weekdays or reopen on order ACK.", "reason": "A reported date and a broker-confirmed execution are separate inputs.", "alternative": "Require the authoritative date and correlated close fills; report unavailable evidence explicitly."}]
|
|
80
|
+
_examples: ClassVar[list] = [{
|
|
81
|
+
"title": "Inspect the current front contract",
|
|
82
|
+
"description": "Read-only component; no order is submitted.",
|
|
83
|
+
"expected_output": "value contains observed details; unsupported or missing fields stay null.",
|
|
84
|
+
"workflow_snippet": {
|
|
85
|
+
"id": "futures-contract-details", "name": "Inspect futures contract",
|
|
86
|
+
"nodes": [{"id": "start", "type": "StartNode"},
|
|
87
|
+
{"id": "broker", "type": "OverseasFuturesBrokerNode", "credential_id": "broker_cred", "paper_trading": True},
|
|
88
|
+
{"id": "contract", "type": "FuturesContractNode", "base_products": ["HMH"], "contract_selection": "front"},
|
|
89
|
+
{"id": "detail", "type": "OverseasFuturesContractInfoNode", "symbol": "{{ nodes.contract.symbols[0] }}"}],
|
|
90
|
+
"edges": [{"from": a, "to": b} for a, b in [("start", "broker"), ("broker", "contract"), ("contract", "detail")]],
|
|
91
|
+
"credentials": [{"credential_id": "broker_cred", "type": "broker_ls_overseas_futures", "data": [{"key": "appkey", "value": ""}, {"key": "appsecret", "value": ""}]}],
|
|
92
|
+
},
|
|
93
|
+
}, {
|
|
94
|
+
"title": "Inspect the proposed next contract",
|
|
95
|
+
"description": "Resolve and inspect the successor before a separate rollover decision; no order is submitted.",
|
|
96
|
+
"expected_output": "The selected next contract's observed dates and margins, with unknown fields remaining null.",
|
|
97
|
+
"workflow_snippet": {
|
|
98
|
+
"id": "futures-next-contract-details", "name": "Inspect next futures contract",
|
|
99
|
+
"nodes": [{"id": "start", "type": "StartNode"},
|
|
100
|
+
{"id": "broker", "type": "OverseasFuturesBrokerNode", "credential_id": "broker_cred", "paper_trading": True},
|
|
101
|
+
{"id": "contract", "type": "FuturesContractNode", "base_products": ["HMH"], "contract_selection": "next"},
|
|
102
|
+
{"id": "detail", "type": "OverseasFuturesContractInfoNode", "symbol": "{{ nodes.contract.symbols[0] }}"}],
|
|
103
|
+
"edges": [{"from": a, "to": b} for a, b in [("start", "broker"), ("broker", "contract"), ("contract", "detail")]],
|
|
104
|
+
"credentials": [{"credential_id": "broker_cred", "type": "broker_ls_overseas_futures", "data": [{"key": "appkey", "value": ""}, {"key": "appsecret", "value": ""}]}],
|
|
105
|
+
},
|
|
106
|
+
}]
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def is_tool_enabled(cls) -> bool:
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def get_field_schema(cls) -> Dict[str, FieldSchema]:
|
|
114
|
+
return {"symbol": FieldSchema(
|
|
115
|
+
name="symbol", type=FieldType.OBJECT,
|
|
116
|
+
display_name="i18n:fieldNames.OverseasFuturesContractInfoNode.symbol",
|
|
117
|
+
description="Exact listed contract symbol and exchange; resolve at run time.",
|
|
118
|
+
category=FieldCategory.PARAMETERS, expression_mode=ExpressionMode.BOTH, required=True,
|
|
119
|
+
object_schema=[{"name": "symbol", "type": "STRING", "required": True}, {"name": "exchange", "type": "STRING", "required": True}],
|
|
120
|
+
bindable_sources=["FuturesContractNode.symbols", "SplitNode.item"],
|
|
121
|
+
example_binding="{{ nodes.contract.symbols[0] }}",
|
|
122
|
+
)}
|
|
@@ -177,6 +177,9 @@ class SQLiteNode(BaseNode):
|
|
|
177
177
|
_img_url: ClassVar[str] = ""
|
|
178
178
|
|
|
179
179
|
# === 기본 설정 ===
|
|
180
|
+
storage_scope: Literal['shared', 'execution'] = Field(
|
|
181
|
+
default='shared', description='i18n:fields.SQLiteNode.storage_scope',
|
|
182
|
+
)
|
|
180
183
|
db_name: str = Field(
|
|
181
184
|
default="default.db",
|
|
182
185
|
description="데이터베이스 파일명 (/app/data/ 폴더 내)",
|
|
@@ -248,7 +251,7 @@ class SQLiteNode(BaseNode):
|
|
|
248
251
|
"Upsert support via 'on_conflict' column in simple mode — ideal for idempotent state updates",
|
|
249
252
|
"Outputs rows (list), affected_count (int), and last_insert_id (int) to cover all read/write patterns",
|
|
250
253
|
"is_tool_enabled=True — AI Agent can use SQLiteNode as a tool to read or write local state",
|
|
251
|
-
"
|
|
254
|
+
"The host injects storage_dir (default /app/data); db_name selects the file. storage_scope=execution prefixes a stable host execution identity (or workflow ID for standalone use), survives process restarts, and separates managed account executions. Default shared preserves existing filenames. Keep the host directory on durable storage and do not reset reservations on startup.",
|
|
252
255
|
"Has a dedicated replay adapter (execute_sqlite) and takes no external recording; it runs against a file-backed database rooted at the run's storage directory",
|
|
253
256
|
"State written on one tick or event frame persists to that database and stays visible on later frames within the run, so a durable duplicate guard can be built on it",
|
|
254
257
|
"Each execution runs exactly ONE SQL statement (execute_query and every simple-mode action call db.execute once); 'CREATE TABLE …; INSERT …' in one query fails with 'You can only execute one statement at a time'",
|
|
@@ -426,6 +429,12 @@ class SQLiteNode(BaseNode):
|
|
|
426
429
|
def get_field_schema(cls) -> Dict[str, "FieldSchema"]:
|
|
427
430
|
from programgarden_core.models.field_binding import FieldSchema, FieldType, FieldCategory, ExpressionMode, UIComponent
|
|
428
431
|
return {
|
|
432
|
+
"storage_scope": FieldSchema(
|
|
433
|
+
name="storage_scope", type=FieldType.ENUM,
|
|
434
|
+
description="i18n:fields.SQLiteNode.storage_scope", default="shared",
|
|
435
|
+
enum_values=["shared", "execution"], category=FieldCategory.PARAMETERS,
|
|
436
|
+
expression_mode=ExpressionMode.FIXED_ONLY,
|
|
437
|
+
),
|
|
429
438
|
# === PARAMETERS: 기본 설정 ===
|
|
430
439
|
"db_name": FieldSchema(
|
|
431
440
|
name="db_name",
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/realtime_futures.py
RENAMED
|
@@ -601,8 +601,16 @@ class OverseasFuturesRealOrderEventNode(BaseNode):
|
|
|
601
601
|
|
|
602
602
|
_inputs: List[InputPort] = []
|
|
603
603
|
_outputs: List[OutputPort] = [
|
|
604
|
+
OutputPort(name="status", type="string", description="Subscription status; subscribed only after successful registration."),
|
|
605
|
+
OutputPort(name="error", type="string", description="Subscription failure when unavailable."),
|
|
604
606
|
OutputPort(name="accepted", type="order_event", description="i18n:ports.accepted", fields=ORDER_EVENT_FIELDS),
|
|
605
|
-
OutputPort(name="filled", type="order_event", description="i18n:ports.filled", fields=ORDER_EVENT_FIELDS
|
|
607
|
+
OutputPort(name="filled", type="order_event", description="i18n:ports.filled", fields=ORDER_EVENT_FIELDS + [
|
|
608
|
+
{"name": "tr_cd", "type": "string", "description": "Native stream identifier (TC3 for executions)."},
|
|
609
|
+
{"name": "svc_id", "type": "string", "description": "Native service classifier; require CH01 for a positive execution."},
|
|
610
|
+
{"name": "order_date", "type": "string", "description": "Observed broker order date, YYYYMMDD; no local date fallback."},
|
|
611
|
+
{"name": "fill_no", "type": "string", "description": "Observed TC3 execution identity; never equate with REST execution numbers."},
|
|
612
|
+
{"name": "fill_time", "type": "string", "description": "Observed TC3 execution time."},
|
|
613
|
+
]),
|
|
606
614
|
OutputPort(name="modified", type="order_event", description="i18n:ports.modified", fields=ORDER_EVENT_FIELDS),
|
|
607
615
|
OutputPort(name="cancelled", type="order_event", description="i18n:ports.cancelled", fields=ORDER_EVENT_FIELDS),
|
|
608
616
|
OutputPort(name="rejected", type="order_event", description="i18n:ports.rejected", fields=ORDER_EVENT_FIELDS),
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/session_gate.py
RENAMED
|
@@ -43,7 +43,7 @@ class SessionGateNode(BaseNode):
|
|
|
43
43
|
windows: list[SessionWindow] = Field(..., min_length=1, description='i18n:nodes.SessionGateNode.windows')
|
|
44
44
|
days: list[Literal['mon','tue','wed','thu','fri','sat','sun']] = Field(..., min_length=1, description='i18n:nodes.SessionGateNode.days')
|
|
45
45
|
closed_dates: list[str] = Field(default_factory=list, description='i18n:nodes.SessionGateNode.closed_dates')
|
|
46
|
-
exchange_calendar: Literal['XNYS', 'XNAS'] | None = Field(default=None, description='i18n:nodes.SessionGateNode.exchange_calendar')
|
|
46
|
+
exchange_calendar: Literal['XNYS', 'XNAS', 'XHKG'] | None = Field(default=None, description='i18n:nodes.SessionGateNode.exchange_calendar')
|
|
47
47
|
|
|
48
48
|
_inputs: list[InputPort] = [InputPort(name='trigger',type='signal',required=False,description='i18n:nodes.SessionGateNode.trigger')]
|
|
49
49
|
_outputs: list[OutputPort] = [OutputPort(name=k,type=t,description=d) for k,t,d in [
|
|
@@ -53,15 +53,15 @@ class SessionGateNode(BaseNode):
|
|
|
53
53
|
('local_time','string','i18n:nodes.SessionGateNode.local_time'),
|
|
54
54
|
('reason','string','i18n:nodes.SessionGateNode.reason'),
|
|
55
55
|
]]
|
|
56
|
-
_change_note: ClassVar[str] = 'Add
|
|
57
|
-
_version: ClassVar[str] = '1.
|
|
58
|
-
_updated_at: ClassVar[str] = '2026-
|
|
56
|
+
_change_note: ClassVar[str] = 'Add the XHKG cash-session intersection, including lunch breaks; this is not a derivatives calendar.'
|
|
57
|
+
_version: ClassVar[str] = '1.2.0'
|
|
58
|
+
_updated_at: ClassVar[str] = '2026-10-03'
|
|
59
59
|
_usage: ClassVar[dict[str,Any]] = {
|
|
60
60
|
'when_to_use':['Check a market-local order window immediately before submission.','Handle overnight sessions, breaks and daylight-saving time.'],
|
|
61
61
|
'when_not_to_use':['Live trading halts or new emergency closures must be observed.','Wait until opening: use TradingHoursFilterNode.'],
|
|
62
62
|
'typical_scenarios':['ScheduleNode -> SessionGateNode -> IfNode(allowed) -> strategy','Reservation -> SessionGateNode -> IfNode(allowed) -> OrderNode'],
|
|
63
63
|
}
|
|
64
|
-
_features: ClassVar[list[str]] = ['No credentials or network.', 'Optional exchange_calendar XNYS/XNAS intersects user windows with scheduled holidays and early closes; missing/broken calendar data blocks entry. Default null preserves explicit-window behavior.','No sleeping and no dry-run bypass.','IANA timezone/DST and opening-weekday semantics.','Explicit IfNode controls downstream work.','Output is a pure function of the evaluation instant and the configuration (windows are start-inclusive and end-exclusive, plus days, closed_dates and the IANA timezone); replay evaluates it at the scenario as_of.','Two frames at the same instant produce the same allowed value; an outside-window scenario must sit at an instant outside the window.','allowed skips nothing by itself; bind it to an IfNode and hang the order chain on the IfNode true edge.']
|
|
64
|
+
_features: ClassVar[list[str]] = ['No credentials or network.', 'Optional exchange_calendar XNYS/XNAS/XHKG intersects user windows with scheduled holidays, breaks and early closes; XHKG is the cash calendar, not all futures sessions; missing/broken calendar data blocks entry. Default null preserves explicit-window behavior.','No sleeping and no dry-run bypass.','IANA timezone/DST and opening-weekday semantics.','Explicit IfNode controls downstream work.','Output is a pure function of the evaluation instant and the configuration (windows are start-inclusive and end-exclusive, plus days, closed_dates and the IANA timezone); replay evaluates it at the scenario as_of.','Two frames at the same instant produce the same allowed value; an outside-window scenario must sit at an instant outside the window.','allowed skips nothing by itself; bind it to an IfNode and hang the order chain on the IfNode true edge.']
|
|
65
65
|
_anti_patterns: ClassVar[list[dict[str,str]]] = [{'pattern':'Connect directly to an order and assume an ordinary edge checks allowed.','reason':'Edges sequence execution; false output does not automatically skip successors.','alternative':'Bind allowed to IfNode and use its true edge.'}]
|
|
66
66
|
_node_guide: ClassVar[dict[str,Any]] = {
|
|
67
67
|
'input_handling':'Configure timezone, windows, days and optional closed_dates. No current-time override is accepted from workflow data.',
|
|
@@ -122,7 +122,7 @@ class SessionGateNode(BaseNode):
|
|
|
122
122
|
fields['exchange_calendar'] = FieldSchema(
|
|
123
123
|
name='exchange_calendar', type=FieldType.STRING,
|
|
124
124
|
description=cls.model_fields['exchange_calendar'].description, required=False,
|
|
125
|
-
enum_values=['XNYS', 'XNAS'], category=FieldCategory.PARAMETERS,
|
|
125
|
+
enum_values=['XNYS', 'XNAS', 'XHKG'], category=FieldCategory.PARAMETERS,
|
|
126
126
|
expression_mode=ExpressionMode.FIXED_ONLY,
|
|
127
127
|
)
|
|
128
128
|
return fields
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/node_registry.py
RENAMED
|
@@ -195,7 +195,7 @@ class NodeTypeRegistry:
|
|
|
195
195
|
OverseasFuturesMarketDataNode, OverseasFuturesHistoricalDataNode,
|
|
196
196
|
OverseasFuturesRealMarketDataNode,
|
|
197
197
|
OverseasFuturesSymbolQueryNode,
|
|
198
|
-
FuturesContractNode,
|
|
198
|
+
FuturesContractNode, OverseasFuturesContractInfoNode,
|
|
199
199
|
# Account - Stock (해외주식)
|
|
200
200
|
OverseasStockAccountNode, OverseasStockRealAccountNode, OverseasStockRealOrderEventNode,
|
|
201
201
|
# Account - Futures (해외선물)
|
|
@@ -239,7 +239,7 @@ class NodeTypeRegistry:
|
|
|
239
239
|
OverseasFuturesMarketDataNode, OverseasFuturesHistoricalDataNode,
|
|
240
240
|
OverseasFuturesRealMarketDataNode,
|
|
241
241
|
OverseasFuturesSymbolQueryNode,
|
|
242
|
-
FuturesContractNode,
|
|
242
|
+
FuturesContractNode, OverseasFuturesContractInfoNode,
|
|
243
243
|
# Account - Stock (해외주식)
|
|
244
244
|
OverseasStockAccountNode, OverseasStockRealAccountNode, OverseasStockRealOrderEventNode,
|
|
245
245
|
# Account - Futures (해외선물)
|
|
@@ -5,7 +5,7 @@ authors = [
|
|
|
5
5
|
homepage = "https://programgarden.com"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
name = "programgarden-core"
|
|
8
|
-
version = "2.
|
|
8
|
+
version = "2.6.0"
|
|
9
9
|
license = "AGPL-3.0-or-later"
|
|
10
10
|
description = "ProgramGarden Core - 노드 기반 DSL 핵심 타입 정의"
|
|
11
11
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/bases/components.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
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/__init__.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/evaluator.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/expression/reference.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/connection_rule.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/credential.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/field_binding.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/order_diagnostics.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/plugin_resource.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/resilience.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/models/validation.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/account_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/account_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/backtest_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/calculation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_futures.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_korea_stock.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/data_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/fundamental_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/open_orders_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/realtime_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_futures.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_korea_stock.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/nodes/symbol_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/__init__.py
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/news_analyst.json
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/risk_manager.json
RENAMED
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/presets/strategist.json
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-2.5.3 → programgarden_core-2.6.0}/programgarden_core/registry/plugin_registry.py
RENAMED
|
File without changes
|
|
File without changes
|