Skip to content

Commit c177845

Browse files
authored
fix: CLI snapshot panic + at_time time format conversion (#182)
Fix CLI snapshot panic + at_time time format. Fixes #180, #181.
1 parent 1f7b455 commit c177845

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

tools/cli/src/main.rs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,23 @@ fn parse_symbols(s: &str) -> Vec<&str> {
162162
.collect()
163163
}
164164

165+
/// Normalize time_of_day: if all digits (ms since midnight), convert to hh:mm:ss.SSS.
166+
/// The v3 server expects hh:mm:ss.SSS format, but users may pass milliseconds.
167+
fn normalize_time(s: &str) -> String {
168+
if s.contains(':') {
169+
return s.to_string();
170+
}
171+
if let Ok(ms) = s.parse::<u64>() {
172+
let h = ms / 3_600_000;
173+
let m = (ms % 3_600_000) / 60_000;
174+
let sec = (ms % 60_000) / 1_000;
175+
let frac = ms % 1_000;
176+
format!("{h:02}:{m:02}:{sec:02}.{frac:03}")
177+
} else {
178+
s.to_string()
179+
}
180+
}
181+
165182
/// Normalize option right to the uppercase single-letter format the API expects.
166183
fn normalize_right(s: &str) -> Result<&'static str, thetadatadx::Error> {
167184
match s.to_ascii_uppercase().as_str() {
@@ -203,22 +220,22 @@ async fn dispatch_endpoint(
203220

204221
// ── Stock Snapshot ──────────────────────────────────────────
205222
"stock_snapshot_ohlc" => {
206-
let syms = parse_symbols(get_arg(m, "symbols"));
223+
let syms = parse_symbols(get_arg(m, "symbol"));
207224
let ticks = client.stock_snapshot_ohlc(&syms).await?;
208225
render_ohlc(&ticks, fmt);
209226
}
210227
"stock_snapshot_trade" => {
211-
let syms = parse_symbols(get_arg(m, "symbols"));
228+
let syms = parse_symbols(get_arg(m, "symbol"));
212229
let ticks = client.stock_snapshot_trade(&syms).await?;
213230
render_trades(&ticks, fmt);
214231
}
215232
"stock_snapshot_quote" => {
216-
let syms = parse_symbols(get_arg(m, "symbols"));
233+
let syms = parse_symbols(get_arg(m, "symbol"));
217234
let ticks = client.stock_snapshot_quote(&syms).await?;
218235
render_quotes(&ticks, fmt);
219236
}
220237
"stock_snapshot_market_value" => {
221-
let syms = parse_symbols(get_arg(m, "symbols"));
238+
let syms = parse_symbols(get_arg(m, "symbol"));
222239
let ticks = client.stock_snapshot_market_value(&syms).await?;
223240
render_market_value(&ticks, fmt);
224241
}
@@ -273,16 +290,16 @@ async fn dispatch_endpoint(
273290
let sym = get_arg(m, "symbol");
274291
let start = get_arg(m, "start_date");
275292
let end = get_arg(m, "end_date");
276-
let tod = get_arg(m, "time_of_day");
277-
let ticks = client.stock_at_time_trade(sym, start, end, tod).await?;
293+
let tod = normalize_time(get_arg(m, "time_of_day"));
294+
let ticks = client.stock_at_time_trade(sym, start, end, &tod).await?;
278295
render_trades(&ticks, fmt);
279296
}
280297
"stock_at_time_quote" => {
281298
let sym = get_arg(m, "symbol");
282299
let start = get_arg(m, "start_date");
283300
let end = get_arg(m, "end_date");
284-
let tod = get_arg(m, "time_of_day");
285-
let ticks = client.stock_at_time_quote(sym, start, end, tod).await?;
301+
let tod = normalize_time(get_arg(m, "time_of_day"));
302+
let ticks = client.stock_at_time_quote(sym, start, end, &tod).await?;
286303
render_quotes(&ticks, fmt);
287304
}
288305

@@ -545,19 +562,19 @@ async fn dispatch_endpoint(
545562
let (sym, exp, strike, right) = option_contract_args(m)?;
546563
let start = get_arg(m, "start_date");
547564
let end = get_arg(m, "end_date");
548-
let tod = get_arg(m, "time_of_day");
565+
let tod = normalize_time(get_arg(m, "time_of_day"));
549566
let ticks = client
550-
.option_at_time_trade(sym, exp, strike, right, start, end, tod)
567+
.option_at_time_trade(sym, exp, strike, right, start, end, &tod)
551568
.await?;
552569
render_trades(&ticks, fmt);
553570
}
554571
"option_at_time_quote" => {
555572
let (sym, exp, strike, right) = option_contract_args(m)?;
556573
let start = get_arg(m, "start_date");
557574
let end = get_arg(m, "end_date");
558-
let tod = get_arg(m, "time_of_day");
575+
let tod = normalize_time(get_arg(m, "time_of_day"));
559576
let ticks = client
560-
.option_at_time_quote(sym, exp, strike, right, start, end, tod)
577+
.option_at_time_quote(sym, exp, strike, right, start, end, &tod)
561578
.await?;
562579
render_quotes(&ticks, fmt);
563580
}
@@ -575,17 +592,17 @@ async fn dispatch_endpoint(
575592

576593
// ── Index Snapshot ──────────────────────────────────────────
577594
"index_snapshot_ohlc" => {
578-
let syms = parse_symbols(get_arg(m, "symbols"));
595+
let syms = parse_symbols(get_arg(m, "symbol"));
579596
let ticks = client.index_snapshot_ohlc(&syms).await?;
580597
render_ohlc(&ticks, fmt);
581598
}
582599
"index_snapshot_price" => {
583-
let syms = parse_symbols(get_arg(m, "symbols"));
600+
let syms = parse_symbols(get_arg(m, "symbol"));
584601
let ticks = client.index_snapshot_price(&syms).await?;
585602
render_price(&ticks, fmt);
586603
}
587604
"index_snapshot_market_value" => {
588-
let syms = parse_symbols(get_arg(m, "symbols"));
605+
let syms = parse_symbols(get_arg(m, "symbol"));
589606
let ticks = client.index_snapshot_market_value(&syms).await?;
590607
render_market_value(&ticks, fmt);
591608
}
@@ -619,8 +636,8 @@ async fn dispatch_endpoint(
619636
let sym = get_arg(m, "symbol");
620637
let start = get_arg(m, "start_date");
621638
let end = get_arg(m, "end_date");
622-
let tod = get_arg(m, "time_of_day");
623-
let ticks = client.index_at_time_price(sym, start, end, tod).await?;
639+
let tod = normalize_time(get_arg(m, "time_of_day"));
640+
let ticks = client.index_at_time_price(sym, start, end, &tod).await?;
624641
render_price(&ticks, fmt);
625642
}
626643

0 commit comments

Comments
 (0)