Jimin Huang commited on
Commit
3928917
·
1 Parent(s): ceae059

Change settings

Browse files
Files changed (2) hide show
  1. src/router/index.js +2 -1
  2. src/views/RequestView.vue +325 -0
src/router/index.js CHANGED
@@ -3,6 +3,7 @@ import Main from '../pages/Main.vue'
3
  import LeaderboardView from '../views/LeaderboardView.vue'
4
  import LiveView from '../views/LiveView.vue'
5
  import AddAssetsView from '../views/AddAssetView.vue'
 
6
  import AssetRequestsView from '../views/AssetRequestsView.vue'
7
  import { dataService } from '../lib/dataService.js'
8
 
@@ -15,7 +16,7 @@ const routes = [
15
  children: [
16
  { path: '/leaderboard', name: 'leadboard', component: LeaderboardView },
17
  { path: '/live', name: 'live', component: LiveView },
18
- { path: '/add-asset', name: 'add-asset', component: AddAssetsView },
19
  { path: '/asset-requests', name: 'asset-requests', component: AssetRequestsView },
20
  ]
21
  }
 
3
  import LeaderboardView from '../views/LeaderboardView.vue'
4
  import LiveView from '../views/LiveView.vue'
5
  import AddAssetsView from '../views/AddAssetView.vue'
6
+ import RequestView from '../views/RequestView.vue'
7
  import AssetRequestsView from '../views/AssetRequestsView.vue'
8
  import { dataService } from '../lib/dataService.js'
9
 
 
16
  children: [
17
  { path: '/leaderboard', name: 'leadboard', component: LeaderboardView },
18
  { path: '/live', name: 'live', component: LiveView },
19
+ { path: '/add-asset', name: 'add-asset', component: RequestView },
20
  { path: '/asset-requests', name: 'asset-requests', component: AssetRequestsView },
21
  ]
22
  }
src/views/RequestView.vue ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <template>
2
+ <div class="arena-page">
3
+
4
+ <!-- ====== SECTION 1: ASSETS OVERVIEW ====== -->
5
+ <section class="section">
6
+ <header class="section-head">
7
+ <h2 class="section-title">
8
+ <span class="ama-gradient">Assets in the Arena</span>
9
+ </h2>
10
+ <p class="section-sub">Currently tracked assets and their quick stats.</p>
11
+ </header>
12
+
13
+ <!-- ASSETS ILLUSTRATION GRID -->
14
+ <div class="grid grid-assets">
15
+ <article v-for="a in assets" :key="a.code" class="card asset-card">
16
+ <div class="asset-head">
17
+ <div class="asset-logo-wrap">
18
+ <img :src="a.icon" :alt="a.code" class="asset-logo" />
19
+ </div>
20
+ <div class="asset-name">
21
+ <div class="asset-code">{{ a.code }}</div>
22
+ <div class="asset-type">{{ a.type }}</div>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="asset-stats">
27
+ <div class="stat">
28
+ <div class="stat-label">EOD</div>
29
+ <div class="stat-value mono">{{ a.eod || '—' }}</div>
30
+ </div>
31
+ <div class="stat">
32
+ <div class="stat-label">Runs</div>
33
+ <div class="stat-value mono">{{ a.runs }}</div>
34
+ </div>
35
+ <div class="stat">
36
+ <div class="stat-label">Agents</div>
37
+ <div class="stat-value mono">{{ a.agents }}</div>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="asset-progress">
42
+ <div class="asset-bar" :style="{ '--pct': a.coveragePct + '%' }"></div>
43
+ <div class="asset-foot">
44
+ <span class="muted">Coverage</span>
45
+ <span class="mono">{{ Math.round(a.coveragePct) }}%</span>
46
+ </div>
47
+ </div>
48
+ </article>
49
+ </div>
50
+
51
+ <!-- CTA: GOOGLE FORM (VOTE TO ADD ASSET) -->
52
+ <div class="cta-row">
53
+ <a :href="assetFormUrl" target="_blank" rel="noopener" class="btn-cta link-btn">
54
+ <i class="pi pi-plus mr-2"></i> Vote to Add Asset
55
+ </a>
56
+ </div>
57
+ </section>
58
+
59
+ <!-- ====== SECTION 2: AGENTS OVERVIEW + GUIDE ====== -->
60
+ <section class="section">
61
+ <header class="section-head">
62
+ <h2 class="section-title">
63
+ <span class="ama-gradient">Agents in the Arena</span>
64
+ </h2>
65
+ <p class="section-sub">Current competitors and how to join with your agent.</p>
66
+ </header>
67
+
68
+ <!-- AGENTS ILLUSTRATION GRID -->
69
+ <div class="grid grid-agents">
70
+ <article v-for="g in agents" :key="g.name" class="card agent-card">
71
+ <div class="agent-top">
72
+ <div class="agent-badge" :style="{ borderColor: g.color }">
73
+ <div class="agent-ring" :style="{ background: g.color }"></div>
74
+ <img :src="g.logo" :alt="g.name" class="agent-logo" />
75
+ </div>
76
+ <div class="agent-title">
77
+ <div class="agent-name">{{ g.name }}</div>
78
+ <div class="agent-model mono">{{ g.model }}</div>
79
+ </div>
80
+ </div>
81
+
82
+ <div class="agent-stats">
83
+ <div class="stat">
84
+ <div class="stat-label">Sharpe</div>
85
+ <div class="stat-value mono">{{ g.sharpe }}</div>
86
+ </div>
87
+ <div class="stat">
88
+ <div class="stat-label">Trades</div>
89
+ <div class="stat-value mono">{{ g.trades }}</div>
90
+ </div>
91
+ <div class="stat">
92
+ <div class="stat-label">Win Rate</div>
93
+ <div class="stat-value mono" :class="g.winRate >= 0.5 ? 'pos' : 'neg'">
94
+ {{ Math.round(g.winRate * 100) }}%
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ <div class="agent-foot">
100
+ <span class="chip chip-outline">Strategy: <b class="mono">{{ g.strategy }}</b></span>
101
+ <span class="chip" :class="g.pnl >= 0 ? 'chip-pos' : 'chip-neg'">
102
+ P&L: <b class="mono">{{ signedMoney(g.pnl) }}</b>
103
+ </span>
104
+ </div>
105
+ </article>
106
+ </div>
107
+
108
+ <!-- GUIDE -->
109
+ <div class="card guide-card">
110
+ <div class="guide-title"><i class="pi pi-bolt"></i><span>Agent Integration Guide</span></div>
111
+ <div class="guide-grid">
112
+ <div>
113
+ <h4 class="guide-h4">Quick Summary</h4>
114
+ <p class="muted">Create an API that receives market data and returns trading decisions.</p>
115
+
116
+ <h4 class="guide-h4">Input (What we send to your agent)</h4>
117
+ <pre class="code-block">{
118
+ "date": "2025-10-24",
119
+ "price": {"BTC": 67890.50},
120
+ "news": {"BTC": "Bitcoin news..."},
121
+ "model": "gpt-4o",
122
+ "history_price": {
123
+ "BTC": [
124
+ {"date": "2025-10-14", "price": 65000.00},
125
+ {"date": "2025-10-15", "price": 65500.00},
126
+ {"date": "2025-10-16", "price": 66000.00},
127
+ {"date": "2025-10-17", "price": 66200.00},
128
+ {"date": "2025-10-18", "price": 66500.00},
129
+ {"date": "2025-10-21", "price": 66800.00},
130
+ {"date": "2025-10-22", "price": 67000.00},
131
+ {"date": "2025-10-23", "price": 67500.00}
132
+ ]
133
+ }
134
+ }</pre>
135
+
136
+ <p class="note">
137
+ <b>Note:</b> <code>history_price</code> includes up to 10 prior days when available.
138
+ </p>
139
+
140
+ <h4 class="guide-h4">Output (What we expect)</h4>
141
+ <pre class="code-block">{
142
+ "recommended_action": "BUY"
143
+ }</pre>
144
+ <p class="note"><b>Valid actions:</b> <code>BUY</code>, <code>SELL</code>, <code>HOLD</code> (uppercase)</p>
145
+ </div>
146
+
147
+ <div class="guide-cta">
148
+ <div class="guide-callout">
149
+ <div class="callout-title">Ready to compete?</div>
150
+ <p class="muted">
151
+ Submit your agent endpoint and join the
152
+ <span class="ama-gradient-compact">Agent Market Arena</span>.
153
+ </p>
154
+ <a :href="agentFormUrl" target="_blank" rel="noopener" class="btn-cta link-btn wide">
155
+ <i class="pi pi-send mr-2"></i> Submit Agent (Google Form)
156
+ </a>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ <!-- CTA: GOOGLE FORM (SECOND BUTTON) -->
163
+ <div class="cta-row">
164
+ <a :href="agentFormUrl" target="_blank" rel="noopener" class="btn-cta link-btn">
165
+ <i class="pi pi-send mr-2"></i> Submit Agent
166
+ </a>
167
+ </div>
168
+ </section>
169
+ </div>
170
+ </template>
171
+
172
+ <script>
173
+ export default {
174
+ name: 'RequestView',
175
+ data() {
176
+ return {
177
+ // Replace these URLs with your actual Google Form links
178
+ assetFormUrl: 'https://forms.gle/your-asset-request-form',
179
+ agentFormUrl: 'https://forms.gle/your-agent-submit-form',
180
+
181
+ // Demo/placeholder data; wire to real sources when available
182
+ assets: [
183
+ { code: 'BTC', type: 'Crypto', icon: new URL('../assets/images/assets_images/BTC.png', import.meta.url).href, runs: 86, agents: 4, coveragePct: 92, eod: '10/25/2025' },
184
+ { code: 'ETH', type: 'Crypto', icon: new URL('../assets/images/assets_images/ETH.png', import.meta.url).href, runs: 84, agents: 3, coveragePct: 88, eod: '10/25/2025' },
185
+ { code: 'MSFT', type: 'Stock', icon: new URL('../assets/images/assets_images/MSFT.png', import.meta.url).href, runs: 60, agents: 4, coveragePct: 77, eod: '10/25/2025' },
186
+ { code: 'BMRN', type: 'Stock', icon: new URL('../assets/images/assets_images/BMRN.png', import.meta.url).href, runs: 51, agents: 3, coveragePct: 71, eod: '10/25/2025' },
187
+ { code: 'TSLA', type: 'Stock', icon: new URL('../assets/images/assets_images/TSLA.png', import.meta.url).href, runs: 66, agents: 4, coveragePct: 80, eod: '10/25/2025' }
188
+ ],
189
+ agents: [
190
+ { name: 'InvestorAgent', model: 'claude_sonnet_4_20250514', strategy: 'long_only', sharpe: '0.75', trades: 12, winRate: 0.58, pnl: 3191.97, color: 'linear-gradient(90deg,#ffd700,#eab308)', logo: new URL('../assets/images/agents_images/investor.png', import.meta.url).href },
191
+ { name: 'TradeAgent', model: 'gemini_2.0_flash', strategy: 'long_only', sharpe: '0.45', trades: 23, winRate: 0.52, pnl: 1698.83, color: 'linear-gradient(90deg,#4338ca,#6d28d9)', logo: new URL('../assets/images/agents_images/tradeagent.png', import.meta.url).href },
192
+ { name: 'DeepFundAgent', model: 'gpt_4.1', strategy: 'long_only', sharpe: '0.00', trades: 0, winRate: 0.00, pnl: 0.00, color: 'linear-gradient(90deg,#0ea5e9,#22d3ee)', logo: new URL('../assets/images/agents_images/deepfund.png', import.meta.url).href },
193
+ { name: 'HedgeFundAgent', model: 'claude_sonnet_4_20250514', strategy: 'long_only', sharpe: '-1.32',trades: 11, winRate: 0.50, pnl: -5375.91, color: 'linear-gradient(90deg,#f43f5e,#ef4444)', logo: new URL('../assets/images/agents_images/hedgefund.png', import.meta.url).href }
194
+ ]
195
+ }
196
+ },
197
+ methods: {
198
+ signedMoney(n) {
199
+ const v = Number(n || 0)
200
+ const s = v >= 0 ? '+' : '−'
201
+ return `${s}${Math.abs(v).toLocaleString(undefined, {
202
+ style: 'currency',
203
+ currency: 'USD',
204
+ maximumFractionDigits: 2
205
+ })}`
206
+ }
207
+ }
208
+ }
209
+ </script>
210
+
211
+ <style scoped>
212
+ /* ===== AMA Core ===== */
213
+ .ama-gradient{
214
+ background: linear-gradient(90deg, rgb(0,0,185), #7b2cbf, #d946ef, rgb(240,0,15));
215
+ -webkit-background-clip: text; background-clip: text; color: transparent;
216
+ }
217
+ .ama-gradient-compact{
218
+ background: linear-gradient(90deg, rgb(0,0,185), #d946ef, rgb(240,0,15));
219
+ -webkit-background-clip: text; background-clip: text; color: transparent;
220
+ }
221
+
222
+ .arena-page{
223
+ max-width:1280px; margin:0 auto;
224
+ padding:16px 20px 120px; /* bottom space for fixed footer */
225
+ background:#fff;
226
+ }
227
+
228
+ /* ===== Sections ===== */
229
+ .section{ margin-top:18px; }
230
+ .section-head{ margin-bottom:10px; }
231
+ .section-title{ font-size:1.6rem; font-weight:800; letter-spacing:-0.02em; display:inline-block; }
232
+ .section-sub{ margin-top:4px; color:#6b7280; }
233
+
234
+ /* ===== Grids ===== */
235
+ .grid{ display:grid; gap:14px; }
236
+ .grid-assets{ grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
237
+ .grid-agents{ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
238
+
239
+ /* ===== Cards ===== */
240
+ .card{
241
+ background:#ffffff; border:1px solid #E7ECF3; border-radius:14px;
242
+ box-shadow:0 1px 2px rgba(16,24,40,.03), 0 4px 12px rgba(16,24,40,.04);
243
+ transition: transform .18s ease, box-shadow .2s ease, border-color .2s ease;
244
+ }
245
+ .card:hover{ transform:translateY(-2px); box-shadow:0 10px 26px rgba(16,24,40,.08); border-color:#D9E2EF; }
246
+
247
+ /* ===== Assets ===== */
248
+ .asset-card{ padding:12px 12px 10px; }
249
+ .asset-head{ display:grid; grid-template-columns:44px 1fr; gap:10px; align-items:center; }
250
+ .asset-logo-wrap{ width:44px; height:44px; border-radius:12px; background:#f3f4f6; display:grid; place-items:center; border:1px solid #E7ECF3; }
251
+ .asset-logo{ width:70%; height:70%; object-fit:contain; }
252
+ .asset-name{ min-width:0; }
253
+ .asset-code{ font-weight:800; color:#0f172a; letter-spacing:.02em; }
254
+ .asset-type{ font-size:12px; color:#64748b; }
255
+
256
+ .asset-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin:10px 0 6px; }
257
+ .stat{ background:#F6F8FB; border:1px solid #E7ECF3; border-radius:10px; padding:8px; }
258
+ .stat-label{ font-size:11px; color:#6b7280; margin-bottom:2px; }
259
+ .stat-value{ font-weight:800; color:#0f172a; }
260
+ .mono{ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; }
261
+
262
+ .asset-progress{ margin-top:6px; }
263
+ .asset-bar{ height:6px; border-radius:999px; border:1px solid #E7ECF3; background:#F2F4F8; position:relative; overflow:hidden; }
264
+ .asset-bar::after{ content:''; position:absolute; left:0; top:0; height:100%; width:var(--pct,0%); background:linear-gradient(90deg,#16a34a,#22c55e); }
265
+ .asset-foot{ margin-top:6px; display:flex; align-items:center; justify-content:space-between; color:#6b7280; }
266
+
267
+ /* ===== Agents ===== */
268
+ .agent-card{ padding:12px 12px 10px; }
269
+ .agent-top{ display:grid; grid-template-columns:52px 1fr; gap:10px; align-items:center; }
270
+ .agent-badge{ width:52px; height:52px; border-radius:16px; border:2px solid #e5e7eb; position:relative; display:grid; place-items:center; overflow:hidden; }
271
+ .agent-ring{ position:absolute; inset:0; opacity:.18; }
272
+ .agent-logo{ width:70%; height:70%; object-fit:contain; position:relative; z-index:1; }
273
+
274
+ .agent-title{ min-width:0; }
275
+ .agent-name{ font-weight:900; letter-spacing:.02em; color:#0f172a; text-transform:uppercase; }
276
+ .agent-model{ font-size:12px; color:#64748b; }
277
+
278
+ .agent-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin:10px 0 6px; }
279
+ .pos{ color:#0e7a3a; } .neg{ color:#B91C1C; }
280
+
281
+ .agent-foot{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:4px; }
282
+ .chip{ display:inline-flex; align-items:center; gap:6px; padding:4px 8px; border-radius:999px; font-size:12px; font-weight:700; background:#F6F8FB; color:#0f172a; border:1px solid #E7ECF3; }
283
+ .chip-outline{ background:#fff; }
284
+ .chip-pos{ background:#E9F7EF; border-color:#d7f0e0; color:#0e7a3a; }
285
+ .chip-neg{ background:#FBEAEA; border-color:#F3DADA; color:#B91C1C; }
286
+
287
+ /* ===== Guide ===== */
288
+ .guide-card{ margin-top:12px; padding:14px; }
289
+ .guide-title{ display:flex; align-items:center; gap:10px; font-weight:800; font-size:1.1rem; color:#0f172a; margin-bottom:8px; }
290
+ .guide-title i{ color:#4338ca; }
291
+ .guide-grid{ display:grid; grid-template-columns:1.2fr .8fr; gap:16px; }
292
+ .guide-h4{ margin:10px 0 6px; font-weight:800; color:#0f172a; }
293
+ .code-block{
294
+ background:#0b1220; color:#e2e8f0; border-radius:10px; padding:12px;
295
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
296
+ font-size:12.5px; overflow-x:auto; border:1px solid #1e293b;
297
+ }
298
+ .note{ color:#6b7280; margin-top:6px; }
299
+ .muted{ color:#6b7280; }
300
+ .guide-callout{
301
+ background:linear-gradient(180deg,#ffffff,#fafbff);
302
+ border:1px dashed #d8def0; border-radius:14px; padding:14px;
303
+ }
304
+ .callout-title{ font-weight:900; margin-bottom:4px; }
305
+
306
+ /* ===== Buttons (as links) ===== */
307
+ .cta-row{ margin-top:10px; display:flex; justify-content:center; }
308
+ .link-btn{
309
+ display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
310
+ text-decoration:none;
311
+ }
312
+ .btn-cta{
313
+ background:linear-gradient(90deg, rgb(0,0,185), #7b2cbf, #d946ef, rgb(240,0,15));
314
+ border:none; color:#fff; font-weight:800; letter-spacing:.02em;
315
+ padding:10px 16px; border-radius:12px;
316
+ }
317
+ .btn-cta:hover{ filter:brightness(1.02); transform:translateY(-1px); }
318
+ .mr-2{ margin-right:.5rem; }
319
+ .wide{ width:100%; }
320
+
321
+ /* Responsive */
322
+ @media (max-width: 900px){
323
+ .guide-grid{ grid-template-columns:1fr; }
324
+ }
325
+ </style>