programgarden-core 1.28.0__tar.gz → 1.28.2__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-1.28.0 → programgarden_core-1.28.2}/PKG-INFO +1 -1
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/listener.py +3 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/__init__.py +10 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/order_diagnostics.py +84 -2
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/order.py +13 -1
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/pyproject.toml +1 -1
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/README.md +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/client.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/components.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/mixins.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/products.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/sql.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/storage.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/code_node.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/exceptions.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/expression/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/expression/evaluator.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/locales/en.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/locales/ko.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/translator.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/korea_alias.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/connection_rule.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/credential.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/edge.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/event.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/exchange.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/field_binding.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/job.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/plugin_resource.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/resilience.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/resource.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/validation.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/workflow.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/account_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/account_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/account_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/ai.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/base.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/broker.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/calculation.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/code.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/condition.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/display.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/event.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/fundamental_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/fundamental_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/infra.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/market_external.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/market_status.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/open_orders_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/open_orders_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/open_orders_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/portfolio.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/realtime_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/realtime_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/realtime_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/risk.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol_futures.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol_korea_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol_stock.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/trigger.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/news_analyst.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/risk_manager.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/strategist.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/technical_analyst.json +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/__init__.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/credential_registry.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/node_registry.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/plugin_registry.py +0 -0
- {programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/retry_executor.py +0 -0
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/listener.py
RENAMED
|
@@ -409,6 +409,9 @@ class WorkflowPnLEvent:
|
|
|
409
409
|
competition_account_overseas_futures_pnl_amount: Optional[Union[Decimal, float]] = None
|
|
410
410
|
competition_account_korea_stock_pnl_rate: Optional[Union[Decimal, float]] = None
|
|
411
411
|
competition_account_korea_stock_pnl_amount: Optional[Union[Decimal, float]] = None
|
|
412
|
+
# Open-position money, independent of closed-trade personal metrics.
|
|
413
|
+
account_valuation: Optional[Dict[str, Any]] = None
|
|
414
|
+
workflow_valuation: Optional[Dict[str, Any]] = None
|
|
412
415
|
|
|
413
416
|
|
|
414
417
|
# ============================================================
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/__init__.py
RENAMED
|
@@ -99,6 +99,11 @@ from programgarden_core.models.order_diagnostics import (
|
|
|
99
99
|
EmptyOrderReason,
|
|
100
100
|
map_reject_code,
|
|
101
101
|
diagnose_missing_order_no,
|
|
102
|
+
unsupported_market_reject,
|
|
103
|
+
looks_like_otc_ticker,
|
|
104
|
+
LS_OVERSEAS_DESK_PHONE,
|
|
105
|
+
OVERSEAS_STOCK_ORDER_MARKET_CODES,
|
|
106
|
+
UNSUPPORTED_MARKET_RSP_CD,
|
|
102
107
|
ORDER_ACCEPTED_RSP_CDS,
|
|
103
108
|
OVERSEAS_STOCK_REJECT_CODES,
|
|
104
109
|
OVERSEAS_FUTURES_REJECT_CODES,
|
|
@@ -196,6 +201,11 @@ __all__ = [
|
|
|
196
201
|
"EmptyOrderReason",
|
|
197
202
|
"map_reject_code",
|
|
198
203
|
"diagnose_missing_order_no",
|
|
204
|
+
"unsupported_market_reject",
|
|
205
|
+
"looks_like_otc_ticker",
|
|
206
|
+
"LS_OVERSEAS_DESK_PHONE",
|
|
207
|
+
"OVERSEAS_STOCK_ORDER_MARKET_CODES",
|
|
208
|
+
"UNSUPPORTED_MARKET_RSP_CD",
|
|
199
209
|
"ORDER_ACCEPTED_RSP_CDS",
|
|
200
210
|
"OVERSEAS_STOCK_REJECT_CODES",
|
|
201
211
|
"OVERSEAS_FUTURES_REJECT_CODES",
|
|
@@ -124,6 +124,12 @@ class EmptyOrderReason(str, Enum):
|
|
|
124
124
|
(fractional balances measured on a real LS account, prod 2026-08-24)."""
|
|
125
125
|
|
|
126
126
|
|
|
127
|
+
LS_OVERSEAS_DESK_PHONE = "02-3779-8888"
|
|
128
|
+
"""LS Securities overseas-stock desk. An OTC holding can only be sold by calling this
|
|
129
|
+
number: LS finds a local broker to take the shares during US regular hours
|
|
130
|
+
(confirmed by LS support, relayed by the account owner 2026-09-14)."""
|
|
131
|
+
|
|
132
|
+
|
|
127
133
|
# ---------------------------------------------------------------------------
|
|
128
134
|
# Market-specific reject-code tables.
|
|
129
135
|
#
|
|
@@ -160,10 +166,26 @@ OVERSEAS_STOCK_REJECT_CODES: Dict[str, Dict[str, str]] = {
|
|
|
160
166
|
"the number may be wrong or the order may already be gone."
|
|
161
167
|
),
|
|
162
168
|
},
|
|
169
|
+
# Live-verified 2026-09-14 on a real LS overseas-stock account. A held OTC
|
|
170
|
+
# issue (ZOMDF) was sent as a limit sell under BOTH accepted market codes —
|
|
171
|
+
# "82" (NASDAQ) and "81" (NYSE/AMEX) — and each came back 03053. LS support
|
|
172
|
+
# confirmed the reason by phone: **OTC issues cannot be traded through the
|
|
173
|
+
# API at all; they must be ordered by calling LS Securities.** So this code
|
|
174
|
+
# is not only "typo in the ticker" — for a symbol the account actually holds,
|
|
175
|
+
# it means the symbol is not tradable on either supported market.
|
|
163
176
|
"03053": {
|
|
164
177
|
"retry": RetryAdvice.DO_NOT_RETRY.value,
|
|
165
|
-
"cause":
|
|
166
|
-
|
|
178
|
+
"cause": (
|
|
179
|
+
"The broker does not recognize the symbol on the market the order was sent to. "
|
|
180
|
+
"For a symbol the account already holds, this means it is not listed on either "
|
|
181
|
+
"market the order API accepts (NYSE/AMEX or NASDAQ) — an OTC issue, for example."
|
|
182
|
+
),
|
|
183
|
+
"tip": (
|
|
184
|
+
"If the account does not hold this symbol, check the ticker spelling and its exchange. "
|
|
185
|
+
"If the account does hold it, the symbol is most likely OTC and the API cannot trade it "
|
|
186
|
+
f"at all — call the LS Securities overseas desk at {LS_OVERSEAS_DESK_PHONE} and ask them "
|
|
187
|
+
"to sell it; LS finds a local broker during US regular hours."
|
|
188
|
+
),
|
|
167
189
|
},
|
|
168
190
|
"03759": {
|
|
169
191
|
"retry": RetryAdvice.DO_NOT_RETRY.value,
|
|
@@ -211,6 +233,66 @@ KOREA_STOCK_REJECT_CODES: Dict[str, Dict[str, str]] = {
|
|
|
211
233
|
},
|
|
212
234
|
}
|
|
213
235
|
|
|
236
|
+
# Markets the LS overseas-stock order TRs accept. COSAT00301's ``OrdMktCode`` and
|
|
237
|
+
# g3101's ``exchcd`` are both ``Literal["81", "82"]`` — there is no third value to
|
|
238
|
+
# try, so a holding on any other market cannot be ordered through this API.
|
|
239
|
+
OVERSEAS_STOCK_ORDER_MARKET_CODES: Dict[str, str] = {
|
|
240
|
+
"NYSE": "81", "AMEX": "81", "NASDAQ": "82", "81": "81", "82": "82",
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
UNSUPPORTED_MARKET_RSP_CD = "PG_UNSUPPORTED_MARKET"
|
|
244
|
+
"""Sentinel used in place of a broker response code.
|
|
245
|
+
|
|
246
|
+
This rejection is raised by us **before** any request reaches LS, so there is no
|
|
247
|
+
``rsp_cd`` to report. The sentinel keeps the field populated (never a bare "")
|
|
248
|
+
and is prefixed ``PG_`` so a consumer can tell at a glance that it did not come
|
|
249
|
+
from the broker.
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def looks_like_otc_ticker(symbol: object) -> bool:
|
|
254
|
+
"""Heuristic from LS support: a 5-letter ticker ending in ``F`` usually means the
|
|
255
|
+
issue has moved to OTC (e.g. ``ZOMDF``).
|
|
256
|
+
|
|
257
|
+
⚠️ LS explicitly said this is **not always true**, so it must never gate an order.
|
|
258
|
+
Use it only to make a message more helpful — the authoritative signal is the market
|
|
259
|
+
code, which the order API rejects on its own.
|
|
260
|
+
"""
|
|
261
|
+
s = str(symbol or "").strip().upper()
|
|
262
|
+
return len(s) == 5 and s.endswith("F") and s.isalpha()
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def unsupported_market_reject(exchange: object, symbol: str = "") -> OrderRejectInfo:
|
|
266
|
+
"""Diagnostic for a symbol whose market the order API cannot address.
|
|
267
|
+
|
|
268
|
+
Live-verified 2026-09-14: a held OTC issue is reported by the balance TR with
|
|
269
|
+
a market code outside {81, 82}, and both accepted codes are rejected with
|
|
270
|
+
``03053``. Blocking before the request keeps the real cause visible — sending
|
|
271
|
+
a substituted code instead makes the broker answer "해당 종목번호가 없습니다",
|
|
272
|
+
which reads like a mistyped ticker and hides that the symbol is untradable.
|
|
273
|
+
"""
|
|
274
|
+
shown = str(exchange) if exchange not in (None, "") else "unknown"
|
|
275
|
+
otc_hint = (
|
|
276
|
+
" The ticker is 5 letters ending in F, which usually means the issue moved to OTC."
|
|
277
|
+
if looks_like_otc_ticker(symbol) else ""
|
|
278
|
+
)
|
|
279
|
+
return OrderRejectInfo(
|
|
280
|
+
rsp_cd=UNSUPPORTED_MARKET_RSP_CD,
|
|
281
|
+
cause=(
|
|
282
|
+
f"This symbol's market ({shown}) is not one the order API can address — "
|
|
283
|
+
f"it accepts NYSE/AMEX and NASDAQ only. OTC issues arrive this way.{otc_hint}"
|
|
284
|
+
),
|
|
285
|
+
tip=(
|
|
286
|
+
"ProgramGarden cannot place this order. Call the LS Securities overseas desk at "
|
|
287
|
+
f"{LS_OVERSEAS_DESK_PHONE} and ask them to sell it — LS finds a local broker to "
|
|
288
|
+
"take the shares during US regular hours. Automation cannot reach this symbol."
|
|
289
|
+
),
|
|
290
|
+
raw_msg="",
|
|
291
|
+
retry=RetryAdvice.DO_NOT_RETRY,
|
|
292
|
+
known=True,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
|
|
214
296
|
_MARKET_TABLES: Dict[str, Dict[str, Dict[str, str]]] = {
|
|
215
297
|
"overseas_stock": OVERSEAS_STOCK_REJECT_CODES,
|
|
216
298
|
"overseas_futures": OVERSEAS_FUTURES_REJECT_CODES,
|
|
@@ -367,7 +367,7 @@ class OverseasStockNewOrderNode(BaseOrderNode):
|
|
|
367
367
|
],
|
|
368
368
|
"typical_scenarios": [
|
|
369
369
|
"ConditionNode.result → PositionSizingNode → OverseasStockNewOrderNode (signal-driven buy)",
|
|
370
|
-
"OverseasStockAccountNode.
|
|
370
|
+
"OverseasStockAccountNode.positions → ConditionNode (stop-loss) → SymbolFilterNode (intersection with positions) → OverseasStockNewOrderNode (sell, limit, price={{ item.current_price }})",
|
|
371
371
|
"ScreenerNode.symbols → SplitNode → PositionSizingNode → OverseasStockNewOrderNode (basket order)",
|
|
372
372
|
],
|
|
373
373
|
}
|
|
@@ -377,6 +377,8 @@ class OverseasStockNewOrderNode(BaseOrderNode):
|
|
|
377
377
|
"Supports extended price_type options: LOO, LOC, MOO, MOC for open/close auction orders",
|
|
378
378
|
"is_tool_enabled=True — AI Agent can call this node as a tool to place orders autonomously",
|
|
379
379
|
"retry is disabled by default (resilience.retry.enabled=False); only pure network-connection failures may be retried, never a submitted order",
|
|
380
|
+
"US daytime (Blue Ocean) session accepts LIMIT orders only — a market order is refused at intake with rsp_cd=00891 and no order number. A workflow scheduled across both the daytime and the regular overnight session must therefore use order_type='limit' for it to work in both.",
|
|
381
|
+
"A limit order needs a price. Buy orders fall back to a current-price lookup, and so do sell orders since engine 1.37.3, but that lookup (g3101) only accepts exchange codes 81/82 — it fails for a holding listed on any other market. Prefer feeding the price the account balance already carries: price='{{ item.current_price }}'.",
|
|
380
382
|
]
|
|
381
383
|
_anti_patterns: ClassVar[List[Dict[str, str]]] = [
|
|
382
384
|
{
|
|
@@ -394,6 +396,16 @@ class OverseasStockNewOrderNode(BaseOrderNode):
|
|
|
394
396
|
"reason": "Every tick would trigger an order attempt; rate-limit rules block this and raise a connection error at validation time.",
|
|
395
397
|
"alternative": "Insert a ThrottleNode between the realtime source and the order node to control firing rate.",
|
|
396
398
|
},
|
|
399
|
+
{
|
|
400
|
+
"pattern": "order_type='market' on a stop-loss / take-profit sell that can run during US daytime (Blue Ocean) hours",
|
|
401
|
+
"reason": "That session refuses market orders at intake (rsp_cd=00891, empty order number), so the stop-loss silently never executes while the schedule covers daytime hours.",
|
|
402
|
+
"alternative": "Use order_type='limit' and supply the price from the account snapshot: price='{{ item.current_price }}'. Note a limit order is not guaranteed to fill.",
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"pattern": "Wiring an order node to ConditionNode.symbols or AccountNode.held_symbols for a close/sell order",
|
|
406
|
+
"reason": "`symbols` lists every evaluated symbol, not the ones that passed, and neither port carries `quantity` or `current_price` — the order node cannot build an order and skips the item.",
|
|
407
|
+
"alternative": "Use `passed_symbols` for the pass list, and to recover quantity and price put a SymbolFilterNode (operation='intersection', input_a='{{ nodes.account.positions }}', input_b='{{ nodes.cond.passed_symbols }}') in between — intersection preserves input_a's full position dicts.",
|
|
408
|
+
},
|
|
397
409
|
{
|
|
398
410
|
"pattern": "Using a dict-keyed positions object {symbol: {...}} from a RealAccountNode output as order input",
|
|
399
411
|
"reason": "All position outputs in ProgramGarden are list[dict] with `symbol`/`exchange` keys. Dict-keyed access will fail at runtime.",
|
|
@@ -5,7 +5,7 @@ authors = [
|
|
|
5
5
|
homepage = "https://programgarden.com"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
name = "programgarden-core"
|
|
8
|
-
version = "1.28.
|
|
8
|
+
version = "1.28.2"
|
|
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-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/components.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/bases/products.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/expression/__init__.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/expression/evaluator.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/locales/en.json
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/locales/ko.json
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/i18n/translator.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/connection_rule.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/credential.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/exchange.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/field_binding.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/plugin_resource.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/resilience.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/resource.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/validation.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/models/workflow.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/__init__.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/account_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/account_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/backtest_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/calculation.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/condition.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_futures.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_korea_stock.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/data_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/market_external.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/market_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/portfolio.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/realtime_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/realtime_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol_futures.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/nodes/symbol_stock.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/__init__.py
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/news_analyst.json
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/risk_manager.json
RENAMED
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/presets/strategist.json
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/registry/node_registry.py
RENAMED
|
File without changes
|
|
File without changes
|
{programgarden_core-1.28.0 → programgarden_core-1.28.2}/programgarden_core/retry_executor.py
RENAMED
|
File without changes
|