@@ -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.
166183fn 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