@bitget-ai/getagent-skill 0.2.1

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.
Files changed (57) hide show
  1. package/.claude-plugin/marketplace.json +28 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/README.md +99 -0
  4. package/VERSION +1 -0
  5. package/bin/getagent-skill.js +140 -0
  6. package/package.json +45 -0
  7. package/skills/getagent/SKILL.md +129 -0
  8. package/skills/getagent/examples/btc-ema-cross-demo/README.md +61 -0
  9. package/skills/getagent/examples/btc-ema-cross-demo/backtest.yaml +33 -0
  10. package/skills/getagent/examples/btc-ema-cross-demo/manifest.yaml +94 -0
  11. package/skills/getagent/examples/btc-ema-cross-demo/src/main.py +88 -0
  12. package/skills/getagent/examples/btc-ema-cross-demo/src/strategy.py +118 -0
  13. package/skills/getagent/references/api/enable.md +95 -0
  14. package/skills/getagent/references/api/error-responses.md +77 -0
  15. package/skills/getagent/references/api/index.md +38 -0
  16. package/skills/getagent/references/api/list.md +80 -0
  17. package/skills/getagent/references/api/my-playbooks.md +41 -0
  18. package/skills/getagent/references/api/publish.md +76 -0
  19. package/skills/getagent/references/api/run.md +149 -0
  20. package/skills/getagent/references/api/upload.md +76 -0
  21. package/skills/getagent/references/backtest-engine.md +438 -0
  22. package/skills/getagent/references/package-schema.md +552 -0
  23. package/skills/getagent/references/sandbox-runtime.md +201 -0
  24. package/skills/getagent/references/sdk/backtest/catalog.md +208 -0
  25. package/skills/getagent/references/sdk/data/arxiv.md +41 -0
  26. package/skills/getagent/references/sdk/data/catalog.md +56 -0
  27. package/skills/getagent/references/sdk/data/commodity.md +226 -0
  28. package/skills/getagent/references/sdk/data/coverage.md +82 -0
  29. package/skills/getagent/references/sdk/data/crypto.md +2906 -0
  30. package/skills/getagent/references/sdk/data/currency.md +123 -0
  31. package/skills/getagent/references/sdk/data/derivatives.md +269 -0
  32. package/skills/getagent/references/sdk/data/economy.md +1348 -0
  33. package/skills/getagent/references/sdk/data/equity.md +2120 -0
  34. package/skills/getagent/references/sdk/data/etf.md +372 -0
  35. package/skills/getagent/references/sdk/data/famafrench.md +201 -0
  36. package/skills/getagent/references/sdk/data/fixedincome.md +804 -0
  37. package/skills/getagent/references/sdk/data/imf_utils.md +225 -0
  38. package/skills/getagent/references/sdk/data/index.md +216 -0
  39. package/skills/getagent/references/sdk/data/news.md +149 -0
  40. package/skills/getagent/references/sdk/data/playbook-supported.md +9871 -0
  41. package/skills/getagent/references/sdk/data/regulators.md +299 -0
  42. package/skills/getagent/references/sdk/data/sentiment.md +323 -0
  43. package/skills/getagent/references/sdk/data/uscongress.md +126 -0
  44. package/skills/getagent/references/sdk/data/web_search.md +68 -0
  45. package/skills/getagent/references/sdk/data/wikipedia.md +97 -0
  46. package/skills/getagent/references/sdk/llm/catalog.md +117 -0
  47. package/skills/getagent/references/sdk/runtime/catalog.md +195 -0
  48. package/skills/getagent/references/sdk/trade/account.md +61 -0
  49. package/skills/getagent/references/sdk/trade/catalog.md +35 -0
  50. package/skills/getagent/references/sdk/trade/contract.md +331 -0
  51. package/skills/getagent/references/sdk/trade/helpers.md +466 -0
  52. package/skills/getagent/references/sdk/trade/market.md +28 -0
  53. package/skills/getagent/references/sdk/trade/patterns.md +102 -0
  54. package/skills/getagent/references/sdk/trade/spot.md +165 -0
  55. package/skills/getagent/references/sdk.md +198 -0
  56. package/skills/getagent/scripts/validate.py +965 -0
  57. package/skills/getagent/scripts/version_check.sh +62 -0
@@ -0,0 +1,126 @@
1
+ # Uscongress Data Reference
2
+
3
+ Use this file when an agent needs detailed signatures and parameter
4
+ rules for one DataSDK domain. All generated `getagent.data` endpoints
5
+ are callable through the DataSDK wrapper.
6
+
7
+ ## Contents
8
+ - [`uscongress.bill_info`](#uscongressbill-info)
9
+ - [`uscongress.bill_text`](#uscongressbill-text)
10
+ - [`uscongress.bill_text_urls`](#uscongressbill-text-urls)
11
+ - [`uscongress.bills`](#uscongressbills)
12
+
13
+ ## Endpoint reference
14
+
15
+ ### `uscongress.bill_info`
16
+
17
+ ```python
18
+ data.uscongress.bill_info(bill_url=None, provider='congress_gov')
19
+ ```
20
+
21
+ Summary: Bill Info
22
+
23
+ | Field | Value |
24
+ |---|---|
25
+ | Endpoint ID | `uscongress.bill_info` |
26
+ | HTTP | `GET` |
27
+ | Path | `/inner/v1/agent-data/uscongress/bill_info` |
28
+ | Default provider | `congress_gov` |
29
+ | SDK | `supported` |
30
+ | Host | `supported` |
31
+ | Notes | - |
32
+
33
+ #### Query parameters
34
+
35
+ | Param | Required | Type | Default | Notes |
36
+ |---|---|---|---|---|
37
+ | `bill_url` | `no` | `string | null` | `-` | Enter a base URL of a bill (e.g., 'https://api.congress.gov/v3/bill/119/s/1947?format=json'). Alternatively, you can enter a bill number (e.g., '119/s/1947'). (provider: congress_gov) |
38
+ | `provider` | `no` | `string` | `congress_gov` | - |
39
+
40
+ ---
41
+
42
+ ### `uscongress.bill_text`
43
+
44
+ ```python
45
+ data.uscongress.bill_text(provider='congress_gov', body=...)
46
+ ```
47
+
48
+ Summary: Bill Text
49
+
50
+ | Field | Value |
51
+ |---|---|
52
+ | Endpoint ID | `uscongress.bill_text` |
53
+ | HTTP | `POST` |
54
+ | Path | `/inner/v1/agent-data/uscongress/bill_text` |
55
+ | Default provider | `congress_gov` |
56
+ | SDK | `supported` |
57
+ | Host | `supported` |
58
+ | Notes | - |
59
+
60
+ #### Query parameters
61
+
62
+ | Param | Required | Type | Default | Notes |
63
+ |---|---|---|---|---|
64
+ | `provider` | `no` | `string` | `congress_gov` | - |
65
+ | `body` | `no` | `string | array | object | null` | `-` | List of direct bill URLs to download. Multiple comma separated items allowed. (provider: congress_gov) |
66
+
67
+ ---
68
+
69
+ ### `uscongress.bill_text_urls`
70
+
71
+ ```python
72
+ data.uscongress.bill_text_urls(bill_url=..., is_workspace=False, provider='congress_gov')
73
+ ```
74
+
75
+ Summary: Bill Text Urls
76
+
77
+ | Field | Value |
78
+ |---|---|
79
+ | Endpoint ID | `uscongress.bill_text_urls` |
80
+ | HTTP | `GET` |
81
+ | Path | `/inner/v1/agent-data/uscongress/bill_text_urls` |
82
+ | Default provider | `congress_gov` |
83
+ | SDK | `supported` |
84
+ | Host | `supported` |
85
+ | Notes | - |
86
+
87
+ #### Query parameters
88
+
89
+ | Param | Required | Type | Default | Notes |
90
+ |---|---|---|---|---|
91
+ | `bill_url` | `yes` | `string` | `-` | - |
92
+ | `is_workspace` | `no` | `boolean` | `false` | - |
93
+ | `provider` | `no` | `string` | `congress_gov` | - |
94
+
95
+ ---
96
+
97
+ ### `uscongress.bills`
98
+
99
+ ```python
100
+ data.uscongress.bills(congress=None, bill_type=None, start_date=None, end_date=None, limit=None, offset=None, sort_by='desc', provider='congress_gov')
101
+ ```
102
+
103
+ Summary: Bills
104
+
105
+ | Field | Value |
106
+ |---|---|
107
+ | Endpoint ID | `uscongress.bills` |
108
+ | HTTP | `GET` |
109
+ | Path | `/inner/v1/agent-data/uscongress/bills` |
110
+ | Default provider | `congress_gov` |
111
+ | SDK | `supported` |
112
+ | Host | `supported` |
113
+ | Notes | - |
114
+
115
+ #### Query parameters
116
+
117
+ | Param | Required | Type | Default | Notes |
118
+ |---|---|---|---|---|
119
+ | `congress` | `no` | `integer | null` | `-` | Congress number (e.g., 118 for the 118th Congress). The 103rd Congress started in 1993, which is the earliest date supporting full text versions. Each Congress spans two years, starting in odd-numbered years. (provider: congress_gov) |
120
+ | `bill_type` | `no` | `string | null` | `-` | Bill type (e.g., "hr" for House bills). Must be one of: hr, s, hjres, sjres, hconres, sconres, hres, sres. Bills ----- A bill is the form used for most legislation, whether permanent or temporary, general or special, public or private. A bill originating in the House of Representatives is designated by the letters “H.R.”, signifying “House of Representatives”, followed by a number that it retains throughout all its parliamentary stages. Bills are presented to the President for action when approved in identical form by both the House of Representatives and the Senate. Joint Resolutions ----------------- Joint resolutions may originate either in the House of Representatives or in the Senate. There is little practical difference between a bill and a joint resolution. Both are subject to the same procedure, except for a joint resolution proposing an amendment to the Constitution. On approval of such a resolution by two-thirds of both the House and Senate, it is sent directly to the Administrator of General Services for submission to the individual states for ratification. It is not presented to the President for approval. A joint resolution originating in the House of Representatives is designated “H.J.Res.” followed by its individual number. Joint resolutions become law in the same manner as bills. Concurrent Resolutions ---------------------- Matters affecting the operations of both the House of Representatives and Senate are usually initiated by means of concurrent resolutions. A concurrent resolution originating in the House of Representatives is designated “H.Con.Res.” followed by its individual number. On approval by both the House of Representatives and Senate, they are signed by the Clerk of the House and the Secretary of the Senate. They are not presented to the President for action. Simple Resolutions ------------------ A matter concerning the operation of either the House of Representatives or Senate alone is initiated by a simple resolution. A resolution affecting the House of Representatives is designated “H.Res.” followed by its number. They are not presented to the President for action. (provider: congress_gov) |
121
+ | `start_date` | `no` | `string | null` | `-` | Start date of the data, in YYYY-MM-DD format. Filters bills by the last updated date. (provider: congress_gov) |
122
+ | `end_date` | `no` | `string | null` | `-` | End date of the data, in YYYY-MM-DD format. Filters bills by the last updated date. (provider: congress_gov) |
123
+ | `limit` | `no` | `integer | null` | `-` | The number of data entries to return. When None, default sets to 100 (max 250). Set to 0 for no limit (must be used with 'bill_type' and 'congress'). Setting to 0 will nullify the start_date, end_date, and offset parameters. (provider: congress_gov) |
124
+ | `offset` | `no` | `integer | null` | `-` | The starting record returned. 0 is the first record. (provider: congress_gov) |
125
+ | `sort_by` | `no` | `string` | `desc` | Sort by update date. Default is latest first. (provider: congress_gov) |
126
+ | `provider` | `no` | `string` | `congress_gov` | - |
@@ -0,0 +1,68 @@
1
+ # Web_Search Data Reference
2
+
3
+ Use this file when an agent needs detailed signatures and parameter
4
+ rules for one DataSDK domain. All generated `getagent.data` endpoints
5
+ are callable through the DataSDK wrapper.
6
+
7
+ ## Contents
8
+ - [`web_search.news`](#web-searchnews)
9
+ - [`web_search.web`](#web-searchweb)
10
+
11
+ ## Endpoint reference
12
+
13
+ ### `web_search.news`
14
+
15
+ ```python
16
+ data.web_search.news(query=..., max_results=10, page=1, provider='bravesearch')
17
+ ```
18
+
19
+ Summary: News
20
+
21
+ | Field | Value |
22
+ |---|---|
23
+ | Endpoint ID | `web_search.news` |
24
+ | HTTP | `GET` |
25
+ | Path | `/inner/v1/agent-data/web_search/news` |
26
+ | Default provider | `bravesearch` |
27
+ | SDK | `supported` |
28
+ | Host | `supported` |
29
+ | Notes | - |
30
+
31
+ #### Query parameters
32
+
33
+ | Param | Required | Type | Default | Notes |
34
+ |---|---|---|---|---|
35
+ | `query` | `yes` | `string` | `-` | Search query string. |
36
+ | `max_results` | `no` | `integer` | `10` | Maximum number of news results to return. |
37
+ | `page` | `no` | `integer` | `1` | Page number for pagination, starting at 1. |
38
+ | `provider` | `no` | `string` | `bravesearch` | - |
39
+
40
+ ---
41
+
42
+ ### `web_search.web`
43
+
44
+ ```python
45
+ data.web_search.web(query=..., max_results=10, page=1, backend='auto', provider=...)
46
+ ```
47
+
48
+ Summary: Web
49
+
50
+ | Field | Value |
51
+ |---|---|
52
+ | Endpoint ID | `web_search.web` |
53
+ | HTTP | `GET` |
54
+ | Path | `/inner/v1/agent-data/web_search/web` |
55
+ | Default provider | - |
56
+ | SDK | `supported` |
57
+ | Host | `supported` |
58
+ | Notes | - |
59
+
60
+ #### Query parameters
61
+
62
+ | Param | Required | Type | Default | Notes |
63
+ |---|---|---|---|---|
64
+ | `query` | `yes` | `string` | `-` | Search query string. |
65
+ | `max_results` | `no` | `integer` | `10` | Maximum number of results to return. |
66
+ | `page` | `no` | `integer` | `1` | Page number for pagination, starting at 1. |
67
+ | `backend` | `no` | `string` | `auto` | enum: auto, duckduckgo, google, bing, brave, yandex, yahoo, wikipedia, grokipedia, mojeek Search engine backend. 'auto' queries multiple engines with automatic fallback for resilience. (provider: ddgs) |
68
+ | `provider` | `yes` | `string` | `-` | enum: bravesearch, ddgs |
@@ -0,0 +1,97 @@
1
+ # Wikipedia Data Reference
2
+
3
+ Use this file when an agent needs detailed signatures and parameter
4
+ rules for one DataSDK domain. All generated `getagent.data` endpoints
5
+ are callable through the DataSDK wrapper.
6
+
7
+ ## Contents
8
+ - [`wikipedia.content`](#wikipediacontent)
9
+ - [`wikipedia.search`](#wikipediasearch)
10
+ - [`wikipedia.summary`](#wikipediasummary)
11
+
12
+ ## Endpoint reference
13
+
14
+ ### `wikipedia.content`
15
+
16
+ ```python
17
+ data.wikipedia.content(title=None, lang='en', intro_only=False, provider='wikipedia')
18
+ ```
19
+
20
+ Summary: Content
21
+
22
+ | Field | Value |
23
+ |---|---|
24
+ | Endpoint ID | `wikipedia.content` |
25
+ | HTTP | `GET` |
26
+ | Path | `/inner/v1/agent-data/wikipedia/content` |
27
+ | Default provider | `wikipedia` |
28
+ | SDK | `supported` |
29
+ | Host | `supported` |
30
+ | Notes | - |
31
+
32
+ #### Query parameters
33
+
34
+ | Param | Required | Type | Default | Notes |
35
+ |---|---|---|---|---|
36
+ | `title` | `no` | `string | null` | `-` | Wikipedia article title to retrieve. (provider: wikipedia) |
37
+ | `lang` | `no` | `string` | `en` | Wikipedia language edition. (provider: wikipedia) |
38
+ | `intro_only` | `no` | `boolean` | `false` | Return only the introductory section instead of the full article. (provider: wikipedia) |
39
+ | `provider` | `no` | `string` | `wikipedia` | - |
40
+
41
+ ---
42
+
43
+ ### `wikipedia.search`
44
+
45
+ ```python
46
+ data.wikipedia.search(query=None, max_results=10, page=1, lang='en', provider='wikipedia')
47
+ ```
48
+
49
+ Summary: Search
50
+
51
+ | Field | Value |
52
+ |---|---|
53
+ | Endpoint ID | `wikipedia.search` |
54
+ | HTTP | `GET` |
55
+ | Path | `/inner/v1/agent-data/wikipedia/search` |
56
+ | Default provider | `wikipedia` |
57
+ | SDK | `supported` |
58
+ | Host | `supported` |
59
+ | Notes | - |
60
+
61
+ #### Query parameters
62
+
63
+ | Param | Required | Type | Default | Notes |
64
+ |---|---|---|---|---|
65
+ | `query` | `no` | `string | null` | `-` | Search query string. (provider: wikipedia) |
66
+ | `max_results` | `no` | `integer` | `10` | Maximum number of results. (provider: wikipedia) |
67
+ | `page` | `no` | `integer` | `1` | Page number, starting at 1. (provider: wikipedia) |
68
+ | `lang` | `no` | `string` | `en` | Wikipedia language edition. (provider: wikipedia) |
69
+ | `provider` | `no` | `string` | `wikipedia` | - |
70
+
71
+ ---
72
+
73
+ ### `wikipedia.summary`
74
+
75
+ ```python
76
+ data.wikipedia.summary(title=None, lang='en', provider='wikipedia')
77
+ ```
78
+
79
+ Summary: Summary
80
+
81
+ | Field | Value |
82
+ |---|---|
83
+ | Endpoint ID | `wikipedia.summary` |
84
+ | HTTP | `GET` |
85
+ | Path | `/inner/v1/agent-data/wikipedia/summary` |
86
+ | Default provider | `wikipedia` |
87
+ | SDK | `supported` |
88
+ | Host | `supported` |
89
+ | Notes | - |
90
+
91
+ #### Query parameters
92
+
93
+ | Param | Required | Type | Default | Notes |
94
+ |---|---|---|---|---|
95
+ | `title` | `no` | `string | null` | `-` | Wikipedia article title to retrieve. (provider: wikipedia) |
96
+ | `lang` | `no` | `string` | `en` | Wikipedia language edition. (provider: wikipedia) |
97
+ | `provider` | `no` | `string` | `wikipedia` | - |
@@ -0,0 +1,117 @@
1
+ # `getagent.llm`
2
+
3
+ Author-facing bounded LLM surface for live-only Playbooks.
4
+
5
+ ## When to use
6
+
7
+ Use `getagent.llm` when the strategy depends on runner-managed model reasoning
8
+ that cannot be fairly replayed from historical market data alone.
9
+
10
+ Typical fit:
11
+
12
+ - `runtime_profile: llm_bounded`
13
+ - `backtest_support: none`
14
+ - live/paper evidence instead of historical backtest claims
15
+
16
+ Do **not** use `getagent.llm` for replayable logic that should stay in
17
+ `getagent.backtest`.
18
+
19
+ ## Public API
20
+
21
+ ### Availability
22
+
23
+ - `llm.is_available() -> bool`
24
+ - Returns whether the current sandbox run injected bounded LLM access
25
+ - `False` in deterministic runs
26
+
27
+ ### Calls
28
+
29
+ - `llm.complete(prompt, *, system=None, max_tokens=None, temperature=None) -> LLMResult`
30
+ - `llm.chat(messages, *, system=None, max_tokens=None, temperature=None) -> LLMResult`
31
+
32
+ `messages` accepts either:
33
+
34
+ - `llm.LLMMessage(role="user", content="...")`
35
+ - plain dicts like `{"role": "user", "content": "..."}`
36
+
37
+ ### Result shape
38
+
39
+ `LLMResult` exposes:
40
+
41
+ - `content`
42
+ - `model`
43
+ - `request_id`
44
+ - `finish_reason`
45
+ - `usage`
46
+ - `raw`
47
+
48
+ `raw` currently carries lightweight provider metadata such as reasoning text or
49
+ estimated cost when available.
50
+
51
+ ## Runtime boundaries
52
+
53
+ The bounded runtime is intentionally narrow:
54
+
55
+ - one runner-managed model only
56
+ - no free model switching from Playbook code
57
+ - no tool calls
58
+ - no direct `httpx` / `requests` / `litellm` usage from Playbook source
59
+ - fixed limits for:
60
+ - calls per run
61
+ - prompt characters
62
+ - output tokens
63
+ - timeout
64
+
65
+ If a request exceeds those limits, `getagent.llm` raises a typed runtime error
66
+ instead of silently falling back.
67
+
68
+ ## Errors
69
+
70
+ The module raises explicit `RuntimeError` subclasses:
71
+
72
+ - `LLMRuntimeUnavailableError` — this run is not `llm_bounded`
73
+ - `LLMConfigurationError` — runner-side LLM config is missing or invalid
74
+ - `LLMInputError` — caller input is malformed
75
+ - `LLMBudgetExceededError` — bounded runtime budget exceeded
76
+ - `LLMError` — upstream/provider call failed
77
+
78
+ ## Example
79
+
80
+ ```python
81
+ from getagent import llm, runtime
82
+
83
+ if not llm.is_available():
84
+ raise RuntimeError("This playbook requires runtime_profile=llm_bounded")
85
+
86
+ summary = llm.complete(
87
+ "Summarize today's macro risk for BTC in 3 sentences.",
88
+ system="You are a cautious crypto macro analyst.",
89
+ max_tokens=300,
90
+ )
91
+
92
+ runtime.emit_signal(
93
+ action="watch",
94
+ symbol="BTCUSDT",
95
+ confidence=0.55,
96
+ meta={
97
+ "llm_summary": summary.content,
98
+ "llm_model": summary.model,
99
+ },
100
+ )
101
+ ```
102
+
103
+ ## Hard rules
104
+
105
+ - Keep LLM outputs as bounded inputs into trading logic, not as an open-ended
106
+ agent loop
107
+ - Do not claim historical replayability for `llm_bounded` strategies
108
+ - Do not read `GETAGENT_LLM_*` env vars directly unless debugging a runtime issue
109
+ - Do not import internal implementation modules such as `getall`, `litellm`, or
110
+ `httpx`
111
+
112
+ ## Related docs
113
+
114
+ - [`../../package-schema.md`](../../package-schema.md)
115
+ - [`../../sandbox-runtime.md`](../../sandbox-runtime.md)
116
+ - [`../../api/publish.md`](../../api/publish.md)
117
+ - [`../../api/enable.md`](../../api/enable.md)
@@ -0,0 +1,195 @@
1
+ # `getagent.runtime`
2
+
3
+ Author-facing runtime protocol for Playbooks.
4
+
5
+ ## When to use
6
+
7
+ Use `getagent.runtime` whenever Playbook code needs runner-injected context or
8
+ needs to emit managed signal output back to the platform.
9
+
10
+ Typical fit:
11
+
12
+ - read package metadata from `manifest.yaml`
13
+ - read the explicit Nautilus replay spec from `backtest.yaml`
14
+ - branch between historical and live execution
15
+ - access the current run ID
16
+ - emit one or more signals in the platform format
17
+
18
+ `getagent.runtime` is the boundary between strategy code and the managed runner.
19
+ It is not a planner, memory system, trading client, or persistence layer.
20
+
21
+ ## Public API
22
+
23
+ ### Context
24
+
25
+ - `runtime.manifest`
26
+ - lazy mapping backed by `/workspace/manifest.yaml`
27
+ - use for package fields such as symbols, schedule, metadata, and `strategy_config`
28
+
29
+ - `runtime.backtest_spec`
30
+ - lazy mapping backed by `/workspace/backtest.yaml`
31
+ - only meaningful when `manifest.yaml` sets `backtest_support: full`
32
+ - carries the explicit Nautilus replay spec: `venue`, `instrument` or
33
+ `instruments`, `strategy`, optional `execution`, and optional
34
+ `data_requirements`
35
+
36
+ - `runtime.run_id`
37
+ - runner-injected identifier for the current execution
38
+
39
+ - `runtime.evaluation_mode`
40
+ - runner-injected execution mode
41
+ - currently `"historical"` for `POST /api/v1/playbook/run`
42
+ - currently `"live"` for follow/subscription schedule executions
43
+
44
+ - `runtime.is_historical() -> bool`
45
+ - true when this execution should use historical/backtest semantics
46
+
47
+ - `runtime.is_live() -> bool`
48
+ - true when this execution should use live market/trading semantics
49
+
50
+ - `runtime.execution_mode() -> str`
51
+ - returns the injected subscription mode, currently `"signal_only"` or
52
+ `"follow_trade"`
53
+
54
+ - `runtime.is_signal_only() -> bool`
55
+ - true when live execution should emit signals but never place orders
56
+
57
+ - `runtime.is_follow_trade() -> bool`
58
+ - true when live execution may place orders after emitting the signal
59
+
60
+ - `runtime.is_actionable_signal(signal_or_action) -> bool`
61
+ - true when the signal action is not `watch`, `hold`, `noop`, `none`, or empty
62
+
63
+ - `runtime.should_follow_trade(signal_or_action) -> bool`
64
+ - true only when the current subscription is `"follow_trade"` and the signal
65
+ action is actionable
66
+
67
+ - `runtime.emit_signal_or_follow(..., execute_trade=None) -> FollowTradeResult`
68
+ - emits a managed signal and automatically decides whether to call the
69
+ `execute_trade` callback based on `execution_mode` and signal action
70
+
71
+ ### Output
72
+
73
+ - `runtime.emit_signal(action, symbol="", confidence=0.0, metrics=None, meta=None) -> SignalPayload`
74
+ - `runtime.get_emitted_signals() -> list[SignalPayload]`
75
+
76
+ `emit_signal(...)` does three things:
77
+
78
+ 1. returns a typed `SignalPayload`
79
+ 2. prints one JSON record to stdout
80
+ 3. appends the record to `/workspace/output/signal.json`
81
+
82
+ ## Historical / Live Split
83
+
84
+ Do not put `run_mode` in `manifest.yaml`. A package is immutable and should run
85
+ both modes from the same uploaded version. Branch on `runtime.evaluation_mode` in
86
+ `src/main.py`:
87
+
88
+ ```python
89
+ from getagent import runtime
90
+ from . import main_backtest, main_live
91
+
92
+ if runtime.is_historical():
93
+ main_backtest.run()
94
+ elif runtime.is_live():
95
+ main_live.run()
96
+ else:
97
+ raise ValueError(f"unsupported evaluation_mode={runtime.evaluation_mode!r}")
98
+ ```
99
+
100
+ Keep shared feature engineering in a neutral module like `features.py`.
101
+ `main_backtest.py` must not import live trading code or call `getagent.trade`.
102
+ `main_live.py` may call `getagent.trade` and can place real orders when the
103
+ current subscription is in follow-trade mode.
104
+
105
+ Live code must separate decision output from trade execution:
106
+
107
+ ```python
108
+ from getagent import runtime, trade
109
+
110
+
111
+ def run() -> None:
112
+ decision = build_live_decision()
113
+
114
+ runtime.emit_signal_or_follow(
115
+ action=decision.action,
116
+ symbol=decision.symbol,
117
+ confidence=decision.confidence,
118
+ metrics=decision.metrics,
119
+ meta=decision.meta,
120
+ execute_trade=lambda: execute_trade(decision),
121
+ )
122
+ ```
123
+
124
+ Signal-only runs should complete after emitting the signal. Do not call
125
+ `trade.contract.*` or `trade.spot.*` mutation APIs and rely on the SDK safety
126
+ guard to fail.
127
+
128
+ ## Output Contract
129
+
130
+ Use `runtime.emit_signal(...)` for strategy conclusions that should be persisted
131
+ as managed Playbook output.
132
+
133
+ Arguments:
134
+
135
+ - `action` — signal action such as `long`, `short`, `close`, `hold`, or `watch`
136
+ - `symbol` — target instrument, usually something like `BTCUSDT`
137
+ - `confidence` — float confidence score
138
+ - `metrics` — structured numeric summary
139
+ - `meta` — extra non-core context for downstream inspection
140
+
141
+ The runner collects `/workspace/output/signal.json` automatically. Do not write
142
+ that file yourself unless you are debugging the runtime contract.
143
+
144
+ If a live run emits an actionable trade signal and then emits a `watch` summary,
145
+ the platform treats the last actionable signal as primary. Use `watch` for final
146
+ summary context, not as a replacement for `long`, `short`, or `close`.
147
+
148
+ ## Example
149
+
150
+ ```python
151
+ from getagent import runtime
152
+
153
+ primary_symbol = runtime.manifest.get("trading_symbols", ["BTCUSDT"])[0]
154
+ config = runtime.manifest.get("strategy_config", {})
155
+
156
+ if runtime.is_historical():
157
+ runtime.emit_signal(
158
+ action="watch",
159
+ symbol=primary_symbol,
160
+ confidence=0.5,
161
+ metrics={"mode": "historical", "lookback_hours": config.get("lookback_hours", 360)},
162
+ meta={"run_id": runtime.run_id},
163
+ )
164
+ else:
165
+ runtime.emit_signal(
166
+ action="long",
167
+ symbol=primary_symbol,
168
+ confidence=0.72,
169
+ metrics={"mode": "live"},
170
+ meta={"run_id": runtime.run_id},
171
+ )
172
+ ```
173
+
174
+ ## Hard Rules
175
+
176
+ - Treat `runtime.manifest` as the source of truth for package contract fields.
177
+ - Read every user-editable strategy parameter from
178
+ `runtime.manifest.get("strategy_config", {})`; do not hardcode values that
179
+ appear in `user_config_schema`.
180
+ - Treat `runtime.backtest_spec` as optional; do not assume it exists.
181
+ - Use `runtime.evaluation_mode` / `runtime.is_historical()` / `runtime.is_live()` for mode routing.
182
+ - Prefer `runtime.emit_signal_or_follow(...)` for live signal-only vs
183
+ follow-trade routing.
184
+ - Use `runtime.emit_signal(...)` instead of inventing your own signal schema.
185
+ - Emit the signal before placing follow-trade orders. Signal-only runs must
186
+ return after `emit_signal(...)`.
187
+ - Do not expect `runtime` to expose trading, data, or LLM clients.
188
+ - Do not use `runtime` as a hidden persistence layer beyond emitted signals.
189
+
190
+ ## Related Docs
191
+
192
+ - [`../../package-schema.md`](../../package-schema.md)
193
+ - [`../../sandbox-runtime.md`](../../sandbox-runtime.md)
194
+ - [`../../backtest-engine.md`](../../backtest-engine.md)
195
+ - [`../llm/catalog.md`](../llm/catalog.md)
@@ -0,0 +1,61 @@
1
+ # Trade Account Reference
2
+
3
+ Account queries and internal balance transfers.
4
+
5
+ These signatures are written against the `getagent.trade` public contract.
6
+ Runner-managed identity kwargs (`user_id`, `channel`, `trace_id`) are
7
+ intentionally omitted from the author-facing signatures below.
8
+
9
+ ## Contents
10
+ - [`trade.account.subaccount_exists`](#tradeaccountsubaccount-exists)
11
+ - [`trade.account.total_value`](#tradeaccounttotal-value)
12
+ - [`trade.account.transfer`](#tradeaccounttransfer)
13
+
14
+ ## Method reference
15
+
16
+ ### `trade.account.subaccount_exists`
17
+
18
+ ```python
19
+ trade.account.subaccount_exists()
20
+ ```
21
+
22
+ Summary: Return True when the trade-proxy subaccount for ``user_id`` exists.
23
+
24
+ No author-supplied parameters.
25
+
26
+ Returns: `bool`
27
+
28
+ ---
29
+
30
+ ### `trade.account.total_value`
31
+
32
+ ```python
33
+ trade.account.total_value()
34
+ ```
35
+
36
+ Summary: Query the unified total-asset snapshot for the current user.
37
+
38
+ No author-supplied parameters.
39
+
40
+ Returns: `TotalValueResult`
41
+
42
+ ---
43
+
44
+ ### `trade.account.transfer`
45
+
46
+ ```python
47
+ trade.account.transfer(from_type, to_type, amount, coin)
48
+ ```
49
+
50
+ Summary: Move funds between ``spot`` and ``usdt_futures`` sub-wallets.
51
+
52
+ | Param | Required | Type | Default |
53
+ |---|---|---|---|
54
+ | `from_type` | `yes` | `AccountTypeLiteral` | - |
55
+ | `to_type` | `yes` | `AccountTypeLiteral` | - |
56
+ | `amount` | `yes` | `Any` | - |
57
+ | `coin` | `yes` | `str` | - |
58
+
59
+ Returns: `TransferResult`
60
+
61
+ ---