opentradex 0.1.1 → 0.1.4

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.
package/.env.example CHANGED
@@ -9,6 +9,8 @@ OPENTRADEX_PRIMARY_MARKET=kalshi
9
9
  OPENTRADEX_ENABLED_MARKETS=kalshi
10
10
  OPENTRADEX_ENABLED_INTEGRATIONS=apify,rss
11
11
  OPENTRADEX_LIVE_EXECUTION_MARKET=kalshi
12
+ OPENTRADEX_DASHBOARD_SURFACE=chat
13
+ OPENTRADEX_CHANNELS=command,markets,feeds,risk,execution
12
14
  NEWS_PROVIDER=apify,rss
13
15
 
14
16
  # Risk configuration
@@ -32,6 +34,12 @@ POLYMARKET_PRIVATE_KEY=
32
34
  TRADINGVIEW_USERNAME=
33
35
  TRADINGVIEW_PASSWORD=
34
36
  TRADINGVIEW_WATCHLIST=SPY,QQQ,BTCUSD,NQ1!
37
+ TRADINGVIEW_CONNECTOR_MODE=watchlist
38
+ TRADINGVIEW_MCP_ENABLED=false
39
+ TRADINGVIEW_MCP_TRANSPORT=stdio
40
+ TRADINGVIEW_MCP_COMMAND=
41
+ TRADINGVIEW_MCP_ARGS=
42
+ TRADINGVIEW_MCP_URL=
35
43
 
36
44
  # Robinhood and Groww
37
45
  ROBINHOOD_USERNAME=
package/README.md CHANGED
@@ -36,8 +36,10 @@ During onboarding you can choose:
36
36
  - Your agent runtime profile
37
37
  - Your primary market rail
38
38
  - Extra rails like `polymarket`, `tradingview`, `robinhood`, or `groww`
39
+ - Your dashboard surface and operator messaging channels
39
40
  - Optional data integrations like `apify`, `rss`, `reddit`, `twitter`, `truthsocial`, and `tiktok`
40
41
  - Your package manager for local web workflows
42
+ - TradingView in watchlist mode or via an optional local MCP connector
41
43
 
42
44
  ### CLI Commands
43
45
 
@@ -56,7 +58,7 @@ opentradex web # launch the Next.js dashboard
56
58
  |---|---|
57
59
  | Kalshi | Best live execution path |
58
60
  | Polymarket | Public market discovery and comparison |
59
- | TradingView | Watchlist and chart context |
61
+ | TradingView | Watchlist context or optional local MCP-backed chart context |
60
62
  | Robinhood | Broker profile placeholder |
61
63
  | Groww | Broker profile placeholder |
62
64
 
package/main.py CHANGED
@@ -42,6 +42,11 @@ def build_runtime_context() -> str:
42
42
  primary_market = os.getenv("OPENTRADEX_PRIMARY_MARKET", "kalshi")
43
43
  enabled_markets = parse_csv_env("OPENTRADEX_ENABLED_MARKETS", primary_market)
44
44
  integrations = parse_csv_env("OPENTRADEX_ENABLED_INTEGRATIONS", "apify,rss")
45
+ dashboard_surface = os.getenv("OPENTRADEX_DASHBOARD_SURFACE", "chat")
46
+ channels = parse_csv_env("OPENTRADEX_CHANNELS", "command,markets,feeds,risk,execution")
47
+ tradingview_connector_mode = os.getenv("TRADINGVIEW_CONNECTOR_MODE", "watchlist").strip().lower()
48
+ tradingview_mcp_enabled = os.getenv("TRADINGVIEW_MCP_ENABLED", "false").strip().lower() == "true"
49
+ tradingview_mcp_transport = os.getenv("TRADINGVIEW_MCP_TRANSPORT", "stdio").strip().lower()
45
50
 
46
51
  lines = [
47
52
  "Workspace profile:",
@@ -49,6 +54,8 @@ def build_runtime_context() -> str:
49
54
  f"- Primary market: {primary_market}",
50
55
  f"- Enabled market rails: {', '.join(enabled_markets)}",
51
56
  f"- Enabled data integrations: {', '.join(integrations)}",
57
+ f"- Dashboard surface: {dashboard_surface}",
58
+ f"- Operator channels: {', '.join(channels)}",
52
59
  "- Use only the rails enabled in this workspace.",
53
60
  "- Live execution is currently routed through Kalshi only. Other rails are for discovery, research, and cross-market context unless explicitly extended.",
54
61
  "",
@@ -76,13 +83,23 @@ def build_runtime_context() -> str:
76
83
  )
77
84
 
78
85
  if "tradingview" in enabled_markets:
79
- lines.extend(
80
- [
81
- "- TradingView watchlist rail:",
82
- " Read `TRADINGVIEW_WATCHLIST` from `.env` and use it to focus macro/equity/crypto research.",
83
- " Treat this as a watchlist/context source unless a dedicated adapter is added.",
84
- ]
85
- )
86
+ if tradingview_connector_mode == "mcp" and tradingview_mcp_enabled:
87
+ lines.extend(
88
+ [
89
+ "- TradingView MCP rail:",
90
+ f" Transport: {tradingview_mcp_transport}",
91
+ " If the local Claude session has the TradingView MCP server available, use it for richer chart and symbol context.",
92
+ " Fall back to `TRADINGVIEW_WATCHLIST` if the MCP server is unavailable or incomplete.",
93
+ ]
94
+ )
95
+ else:
96
+ lines.extend(
97
+ [
98
+ "- TradingView watchlist rail:",
99
+ " Read `TRADINGVIEW_WATCHLIST` from `.env` and use it to focus macro/equity/crypto research.",
100
+ " Treat this as a watchlist/context source unless a dedicated adapter is added.",
101
+ ]
102
+ )
86
103
 
87
104
  if "robinhood" in enabled_markets:
88
105
  lines.append("- Robinhood is enabled as a broker profile placeholder. Use it for planning and watchlist context unless you add a dedicated execution adapter.")
@@ -98,9 +115,21 @@ def build_runtime_context() -> str:
98
115
  return "\n".join(lines)
99
116
 
100
117
 
118
+ def build_harness_protocol() -> str:
119
+ return """Operator harness for this cycle:
120
+ - Scout lane: scan enabled rails fast and surface the best 3-5 candidates.
121
+ - Quant lane: extract the hard numbers, implied price, probability gap, and what actually changed.
122
+ - Risk lane: kill weak, speculative, thin, or unsupported setups early. If the evidence is soft, size down or pass.
123
+ - Executor lane: act only on the best 1-2 ideas, then record the reasoning clearly for the next cycle.
124
+
125
+ Always think in that order: scout -> quantify -> challenge -> execute."""
126
+
127
+
101
128
  def build_cycle_prompt() -> str:
102
129
  return f"""{build_runtime_context()}
103
130
 
131
+ {build_harness_protocol()}
132
+
104
133
  Read SOUL.md for your identity and strategy principles.
105
134
  Read data/strategy_notes.md for lessons from past sessions.
106
135
  Check data/user_rationales.json for any pending user theses to research.
@@ -155,6 +184,8 @@ EXECUTION DISCIPLINE:
155
184
  def build_rationale_prompt(rationale: str) -> str:
156
185
  return f"""{build_runtime_context()}
157
186
 
187
+ {build_harness_protocol()}
188
+
158
189
  Read SOUL.md for your identity and strategy principles.
159
190
 
160
191
  A user has submitted this thesis for you to research and potentially trade on:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opentradex",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "OpenTradex CLI, onboarding flow, and market-rail toolkit for AI-assisted trading workflows.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/catalog.mjs CHANGED
@@ -2,7 +2,7 @@ export const PACKAGE_MANAGER_OPTIONS = [
2
2
  {
3
3
  id: "npm",
4
4
  label: "npm",
5
- description: "Default Node workflow for installs and the dashboard.",
5
+ description: "Default Node workflow for installs, scripts, and the local harness.",
6
6
  installHint: "npm install -g opentradex@latest",
7
7
  },
8
8
  {
@@ -17,7 +17,7 @@ export const RUNTIME_OPTIONS = [
17
17
  {
18
18
  id: "claude-code",
19
19
  label: "Claude Code",
20
- description: "Production-ready local tool-using runtime.",
20
+ description: "Production-ready local tool-using runtime for the current harness.",
21
21
  support: "working",
22
22
  },
23
23
  {
@@ -56,13 +56,13 @@ export const MARKET_OPTIONS = [
56
56
  {
57
57
  id: "robinhood",
58
58
  label: "Robinhood",
59
- description: "US broker profile placeholder.",
59
+ description: "US broker profile placeholder for future adapter work.",
60
60
  support: "profile",
61
61
  },
62
62
  {
63
63
  id: "groww",
64
64
  label: "Groww",
65
- description: "India-focused broker profile placeholder.",
65
+ description: "India-focused broker profile placeholder for future adapter work.",
66
66
  support: "profile",
67
67
  },
68
68
  ];
@@ -100,6 +100,78 @@ export const INTEGRATION_OPTIONS = [
100
100
  },
101
101
  ];
102
102
 
103
+ export const CHANNEL_OPTIONS = [
104
+ {
105
+ id: "command",
106
+ label: "Command",
107
+ description: "Primary operator chat lane for direct prompts and mission launches.",
108
+ },
109
+ {
110
+ id: "markets",
111
+ label: "Markets",
112
+ description: "Cross-market scanning across Kalshi, Polymarket, and active rails.",
113
+ },
114
+ {
115
+ id: "feeds",
116
+ label: "Feeds",
117
+ description: "News, social, and alert ingestion for live context.",
118
+ },
119
+ {
120
+ id: "risk",
121
+ label: "Risk",
122
+ description: "Position review, exposure control, and exit discipline.",
123
+ },
124
+ {
125
+ id: "execution",
126
+ label: "Execution",
127
+ description: "Trade routing, fills, and cycle outcomes.",
128
+ },
129
+ {
130
+ id: "tradingview",
131
+ label: "TradingView",
132
+ description: "Watchlist and chart-context lane for symbols and macro instruments.",
133
+ },
134
+ ];
135
+
136
+ export const DASHBOARD_SURFACE_OPTIONS = [
137
+ {
138
+ id: "chat",
139
+ label: "Chat cockpit",
140
+ description: "Channel-based operator chat inside the local dashboard.",
141
+ },
142
+ {
143
+ id: "stream",
144
+ label: "Stream log",
145
+ description: "Lean terminal-style stream without the full chat cockpit framing.",
146
+ },
147
+ ];
148
+
149
+ export const TRADINGVIEW_CONNECTOR_OPTIONS = [
150
+ {
151
+ id: "watchlist",
152
+ label: "Watchlist only",
153
+ description: "Use TradingView symbols as context without an MCP connector.",
154
+ },
155
+ {
156
+ id: "mcp",
157
+ label: "TradingView MCP",
158
+ description: "Route TradingView context through your local MCP server when available.",
159
+ },
160
+ ];
161
+
162
+ export const MCP_TRANSPORT_OPTIONS = [
163
+ {
164
+ id: "stdio",
165
+ label: "stdio",
166
+ description: "Spawn a local MCP command such as a node, bun, or python process.",
167
+ },
168
+ {
169
+ id: "http",
170
+ label: "http",
171
+ description: "Connect to an MCP endpoint exposed over HTTP.",
172
+ },
173
+ ];
174
+
103
175
  export function getOptionById(options, id, fallbackId) {
104
176
  const fallback = options.find((item) => item.id === fallbackId) || options[0];
105
177
  if (!id) {
package/src/cli.mjs CHANGED
@@ -1,4 +1,13 @@
1
1
  import process from "node:process";
2
+ import {
3
+ CHANNEL_OPTIONS,
4
+ DASHBOARD_SURFACE_OPTIONS,
5
+ INTEGRATION_OPTIONS,
6
+ MARKET_OPTIONS,
7
+ PACKAGE_MANAGER_OPTIONS,
8
+ RUNTIME_OPTIONS,
9
+ labelsForIds,
10
+ } from "./catalog.mjs";
2
11
  import {
3
12
  collectDoctor,
4
13
  formatDoctorReport,
@@ -22,25 +31,32 @@ export async function runCli(argv = process.argv.slice(2)) {
22
31
  return;
23
32
  case "onboard": {
24
33
  const result = await onboard(options);
34
+ if (!result) {
35
+ printLines(["OpenTradex onboarding cancelled."]);
36
+ return;
37
+ }
38
+
25
39
  printLines([
26
- "Welcome to OpenTradex.",
40
+ "OpenTradex profile written.",
27
41
  "Our implementation. Your strategy.",
28
42
  "",
29
- "OpenTradex is ready.",
30
- `workspace: ${result.workspace}`,
31
- `mode: ${result.mode}`,
32
- `runtime: ${result.profile.runtime}`,
33
- `primary market: ${result.profile.primaryMarket}`,
34
- `market rails: ${result.profile.enabledMarkets.join(", ")}`,
35
- `integrations: ${result.profile.integrations.join(", ")}`,
36
- `package manager: ${result.profile.packageManager}`,
43
+ "Local harness configured:",
44
+ ` workspace: ${result.workspace}`,
45
+ ` mode: ${result.mode}`,
46
+ ` runtime: ${labelsForIds(RUNTIME_OPTIONS, [result.profile.runtime]).join(", ")}`,
47
+ ` primary market: ${labelsForIds(MARKET_OPTIONS, [result.profile.primaryMarket]).join(", ")}`,
48
+ ` market rails: ${labelsForIds(MARKET_OPTIONS, result.profile.enabledMarkets).join(", ") || "none"}`,
49
+ ` integrations: ${labelsForIds(INTEGRATION_OPTIONS, result.profile.integrations).join(", ") || "none"}`,
50
+ ` dashboard: ${labelsForIds(DASHBOARD_SURFACE_OPTIONS, [result.profile.dashboardSurface]).join(", ")}`,
51
+ ` channels: ${labelsForIds(CHANNEL_OPTIONS, result.profile.channels).join(", ") || "none"}`,
52
+ ` package manager: ${labelsForIds(PACKAGE_MANAGER_OPTIONS, [result.profile.packageManager]).join(", ")}`,
37
53
  ...(result.notes.length > 0 ? ["", "Notes:", ...result.notes.map((note) => ` - ${note}`)] : []),
38
54
  "",
39
- "Next commands:",
40
- " opentradex doctor",
41
- " opentradex start",
42
- " opentradex web",
43
- " opentradex providers",
55
+ "Next:",
56
+ " 1. opentradex doctor",
57
+ " 2. opentradex web",
58
+ " 3. opentradex start",
59
+ " 4. opentradex providers",
44
60
  ]);
45
61
  return;
46
62
  }
@@ -71,6 +87,8 @@ export async function runCli(argv = process.argv.slice(2)) {
71
87
 
72
88
  function parseArgs(argv) {
73
89
  const options = {};
90
+ const booleanFlags = new Set(["skip-install", "yes", "install", "force", "paper", "live"]);
91
+ const dashValueKeys = new Set(["tradingview-mcp-args"]);
74
92
 
75
93
  for (let index = 0; index < argv.length; index += 1) {
76
94
  const token = argv[index];
@@ -89,12 +107,18 @@ function parseArgs(argv) {
89
107
  continue;
90
108
  }
91
109
 
92
- if (["skip-install", "yes", "install", "force", "paper", "live"].includes(key)) {
110
+ if (booleanFlags.has(key)) {
93
111
  options[toCamel(key)] = true;
94
112
  continue;
95
113
  }
96
114
 
97
115
  const next = argv[index + 1];
116
+ if (dashValueKeys.has(key) && next) {
117
+ options[toCamel(key)] = next;
118
+ index += 1;
119
+ continue;
120
+ }
121
+
98
122
  if (!next || next.startsWith("--")) {
99
123
  options[toCamel(key)] = true;
100
124
  continue;
@@ -115,10 +139,11 @@ function printHelp() {
115
139
  printLines([
116
140
  "opentradex",
117
141
  "",
118
- "Welcome to OpenTradex. Our implementation. Your strategy.",
142
+ "OpenTradex CLI",
143
+ "Our implementation. Your strategy.",
119
144
  "",
120
145
  "Commands:",
121
- " opentradex onboard [--workspace <dir>] [--paper|--live] [--llm <id>] [--primary-market <id>]",
146
+ " opentradex onboard [--workspace <dir>] [--paper|--live] [--llm <id>] [--primary-market <id>] [--dashboard-surface <id>]",
122
147
  " opentradex doctor [--workspace <dir>]",
123
148
  " opentradex providers",
124
149
  " opentradex start [--workspace <dir>] [--interval <seconds>] [--rationale <text>]",
@@ -129,7 +154,8 @@ function printHelp() {
129
154
  "Examples:",
130
155
  " npm install -g opentradex@latest",
131
156
  " bunx opentradex@latest onboard",
132
- " opentradex onboard --llm claude-code --primary-market kalshi --markets polymarket,tradingview",
157
+ " opentradex web",
158
+ " opentradex onboard --llm claude-code --primary-market kalshi --markets polymarket,tradingview --dashboard-surface chat",
133
159
  " opentradex doctor",
134
160
  " opentradex providers",
135
161
  " opentradex cycle --rationale \"Tariffs will escalate next week\"",