2929class TestQuoteClient (unittest .TestCase ):
3030
3131 def setUp (self ):
32- self .is_mock = False
32+ self .is_mock = True
3333 current_dir = os .path .dirname (__file__ )
3434 self .client_config = TigerOpenClientConfig (
3535 props_path = os .path .join (current_dir , ".config/prod_20150899/" ))
@@ -344,32 +344,7 @@ def test_get_timeline(self):
344344 "period" : "day" ,
345345 "preClose" : 229.09 ,
346346 "intraday" : {
347- "items" : [{
348- "time" : 1754919000000 ,
349- "volume" : 1656620 ,
350- "price" : 226.75 ,
351- "avgPrice" : 227.75438
352- }, {
353- "time" : 1754919060000 ,
354- "volume" : 426781 ,
355- "price" : 226.6 ,
356- "avgPrice" : 227.51157
357- }, {
358- "time" : 1754919120000 ,
359- "volume" : 267382 ,
360- "price" : 226.31 ,
361- "avgPrice" : 227.40694
362- }, {
363- "time" : 1754919180000 ,
364- "volume" : 322976 ,
365- "price" : 226.045 ,
366- "avgPrice" : 227.25978
367- }, {
368- "time" : 1754919240000 ,
369- "volume" : 229321 ,
370- "price" : 226.06 ,
371- "avgPrice" : 226.0
372- }],
347+ "items" : [{"time" : 1754919000000 , "volume" : 1656620 , "price" : 226.75 , "avgPrice" : 227.75438 }, {"time" : 1754919060000 , "volume" : 426781 , "price" : 226.6 , "avgPrice" : 227.51157 }, {"time" : 1754919120000 , "volume" : 267382 , "price" : 226.31 , "avgPrice" : 227.40694 }, {"time" : 1754919180000 , "volume" : 322976 , "price" : 226.045 , "avgPrice" : 227.25978 }, {"time" : 1754919240000 , "volume" : 229321 , "price" : 226.06 , "avgPrice" : 226.0 }],
373348 "beginTime" :
374349 - 1 ,
375350 "endTime" :
@@ -400,48 +375,20 @@ def test_get_timeline(self):
400375 self .assertEqual (first_row ['volume' ], 1656620 )
401376 self .assertEqual (first_row ['trading_session' ], 'regular' )
402377 else :
403- result = self .client .get_timeline (symbols = ['AAPL' ])
378+ result = self .client .get_timeline (symbols = ['AAPL' ],
379+ # trade_session=TradingSession.OverNight
380+ )
404381 logger .debug (f"Timeline (real):\n { result } " )
405382
406383 def test_get_timeline_history (self ):
407- if not self .is_mock :
384+ if self .is_mock :
408385 mock_data = {
409- "code" :
410- 0 ,
411- "message" :
412- "success" ,
413- "timestamp" :
414- 1754990360538 ,
415- "data" : [{
416- "symbol" :
417- "AAPL" ,
418- "items" : [{
419- "time" : 1698845400000 ,
420- "volume" : 654691 ,
421- "price" : 171.1 ,
422- "avgPrice" : 171.0484
423- }, {
424- "time" : 1698845460000 ,
425- "volume" : 175598 ,
426- "price" : 170.595 ,
427- "avgPrice" : 171.01788
428- }, {
429- "time" : 1698845520000 ,
430- "volume" : 186093 ,
431- "price" : 170.535 ,
432- "avgPrice" : 170.9575
433- }, {
434- "time" : 1698845580000 ,
435- "volume" : 145550 ,
436- "price" : 170.2719 ,
437- "avgPrice" : 170.90828
438- }, {
439- "time" : 1698845640000 ,
440- "volume" : 221063 ,
441- "price" : 170.41 ,
442- "avgPrice" : 170.82759
443- }]
444- }]
386+ "code" : 0 , "message" : "success" , "timestamp" : 1754990360538 , "data" : [{"symbol" : "AAPL" , "items" : [
387+ {"time" : 1698845400000 , "volume" : 654691 , "price" : 171.1 , "avgPrice" : 171.0484 },
388+ {"time" : 1698845460000 , "volume" : 175598 , "price" : 170.595 , "avgPrice" : 171.01788 },
389+ {"time" : 1698845520000 , "volume" : 186093 , "price" : 170.535 , "avgPrice" : 170.9575 },
390+ {"time" : 1698845580000 , "volume" : 145550 , "price" : 170.2719 , "avgPrice" : 170.90828 },
391+ {"time" : 1698845640000 , "volume" : 221063 , "price" : 170.41 , "avgPrice" : 170.82759 }]}]
445392 }
446393
447394 web_utils .do_request = MagicMock (
@@ -465,64 +412,15 @@ def test_get_timeline_history(self):
465412 self .assertEqual (first_row ['volume' ], 654691 )
466413 else :
467414 result = self .client .get_timeline_history (symbols = ['AAPL' ],
468- date = "2023-11-01" )
415+ date = "2025-08-21" ,
416+ # trade_session=TradingSession.OverNight
417+ )
469418 logger .debug (f"Timeline History (real):\n { result } " )
470419
471420 def test_get_bars (self ):
472421 if self .is_mock :
473422 mock_data = {
474- "code" :
475- 0 ,
476- "message" :
477- "success" ,
478- "timestamp" :
479- 1754990841014 ,
480- "data" : [{
481- "symbol" :
482- "AAPL" ,
483- "period" :
484- "day" ,
485- "items" : [{
486- "time" : 1754366400000 ,
487- "volume" : 44155079 ,
488- "open" : 203.4 ,
489- "close" : 202.92 ,
490- "high" : 205.34 ,
491- "low" : 202.16 ,
492- "amount" : 8.987659222543882E9
493- }, {
494- "time" : 1754452800000 ,
495- "volume" : 108483103 ,
496- "open" : 205.63 ,
497- "close" : 213.25 ,
498- "high" : 215.38 ,
499- "low" : 205.59 ,
500- "amount" : 2.315468887474085E10
501- }, {
502- "time" : 1754539200000 ,
503- "volume" : 90224834 ,
504- "open" : 218.875 ,
505- "close" : 220.03 ,
506- "high" : 220.85 ,
507- "low" : 216.58 ,
508- "amount" : 1.9798494559887737E10
509- }, {
510- "time" : 1754625600000 ,
511- "volume" : 113853967 ,
512- "open" : 220.83 ,
513- "close" : 229.35 ,
514- "high" : 231.0 ,
515- "low" : 219.25 ,
516- "amount" : 2.589128470726625E10
517- }, {
518- "time" : 1754884800000 ,
519- "volume" : 61806132 ,
520- "open" : 227.92 ,
521- "close" : 227.18 ,
522- "high" : 229.56 ,
523- "low" : 224.76 ,
524- "amount" : 1.4164248430829714E10
525- }]
423+ "code" : 0 , "message" : "success" , "timestamp" : 1754990841014 , "data" : [{"symbol" : "AAPL" , "period" : "day" , "items" : [{"time" : 1754366400000 , "volume" : 44155079 , "open" : 203.4 , "close" : 202.92 , "high" : 205.34 , "low" : 202.16 , "amount" : 8.987659222543882E9 }, {"time" : 1754452800000 , "volume" : 108483103 , "open" : 205.63 , "close" : 213.25 , "high" : 215.38 , "low" : 205.59 , "amount" : 2.315468887474085E10 }, {"time" : 1754539200000 , "volume" : 90224834 , "open" : 218.875 , "close" : 220.03 , "high" : 220.85 , "low" : 216.58 , "amount" : 1.9798494559887737E10 }, {"time" : 1754625600000 , "volume" : 113853967 , "open" : 220.83 , "close" : 229.35 , "high" : 231.0 , "low" : 219.25 , "amount" : 2.589128470726625E10 }, {"time" : 1754884800000 , "volume" : 61806132 , "open" : 227.92 , "close" : 227.18 , "high" : 229.56 , "low" : 224.76 , "amount" : 1.4164248430829714E10 }]
526424 }]
527425 }
528426 web_utils .do_request = MagicMock (
@@ -575,7 +473,9 @@ def test_get_bars(self):
575473 result = self .client .get_bars (symbols = ['AAPL' , 'MSFT' ],
576474 period = BarPeriod .DAY ,
577475 limit = 10 ,
578- page_token = '' )
476+ page_token = '' ,
477+ # trade_session=TradingSession.OverNight
478+ )
579479 logger .debug (f"Bars (real):\n { result } " )
580480
581481 def test_get_trade_ticks (self ):
@@ -588,33 +488,8 @@ def test_get_trade_ticks(self):
588488 "timestamp" :
589489 1754991710630 ,
590490 "data" : [{
591- "symbol" :
592- "AAPL" ,
593- "beginIndex" :
594- 482299 ,
595- "endIndex" :
596- 482499 ,
597- "items" : [{
598- "time" : 1754942403109 ,
599- "volume" : 406 ,
600- "price" : 227.18 ,
601- "type" : "-"
602- }, {
603- "time" : 1754942403109 ,
604- "volume" : 26215 ,
605- "price" : 227.18 ,
606- "type" : "-"
607- }, {
608- "time" : 1754942403109 ,
609- "volume" : 884 ,
610- "price" : 227.18 ,
611- "type" : "-"
612- }, {
613- "time" : 1754942403109 ,
614- "volume" : 200 ,
615- "price" : 227.18 ,
616- "type" : "-"
617- }]
491+ "symbol" : "AAPL" , "beginIndex" : 482299 , "endIndex" : 482499 ,
492+ "items" : [{"time" : 1754942403109 , "volume" : 406 , "price" : 227.18 , "type" : "-" }, {"time" : 1754942403109 , "volume" : 26215 , "price" : 227.18 , "type" : "-" }, {"time" : 1754942403109 , "volume" : 884 , "price" : 227.18 , "type" : "-" }, {"time" : 1754942403109 , "volume" : 200 , "price" : 227.18 , "type" : "-" }]
618493 }]
619494 }
620495 web_utils .do_request = MagicMock (
@@ -654,7 +529,9 @@ def test_get_trade_ticks(self):
654529 self .assertEqual (second_row ['direction' ], '-' )
655530 self .assertEqual (second_row ['index' ], 482300 )
656531 else :
657- result = self .client .get_trade_ticks (symbols = ['AAPL' ])
532+ result = self .client .get_trade_ticks (symbols = ['AAPL' ],
533+ # trade_session=TradingSession.OverNight
534+ )
658535 logger .debug (f"Trade Ticks (real): \n { result } " )
659536
660537 def test_get_short_interest (self ):
@@ -764,7 +641,9 @@ def test_get_depth_quote(self):
764641 else :
765642 # 实际调用API
766643 result = self .client .get_depth_quote (symbols = ['AAPL' , 'MSFT' ],
767- market = Market .US )
644+ market = Market .US ,
645+ # trade_session=TradingSession.OverNight
646+ )
768647 logger .debug (f"Depth Quote (real):\n { result } " )
769648
770649 def test_get_option_expirations (self ):
@@ -1013,8 +892,12 @@ def test_get_option_bars(self):
1013892 self .assertEqual (second_bar ['open_interest' ], 9 )
1014893
1015894 else :
895+ # result = self.client.get_option_bars(
896+ # identifiers=['AAPL 250815C00200000'], period=BarPeriod.DAY, limit=5)
1016897 result = self .client .get_option_bars (
1017- identifiers = ['AAPL 250815C00200000' ], period = BarPeriod .DAY , limit = 5 )
898+ identifiers = ['TCH.HK250828C00590000' ], period = BarPeriod .DAY , limit = 5 ,
899+ end_time = '2025-08-22' , timezone = 'Asia/Hong_Kong'
900+ )
1018901 logger .debug (f"Option Bars (real):\n { result } " )
1019902
1020903 def test_get_option_trade_ticks (self ):
@@ -1062,21 +945,15 @@ def test_get_option_trade_ticks(self):
1062945 self .assertEqual (first_tick ['price' ], 30.0 )
1063946 self .assertEqual (first_tick ['volume' ], 2 )
1064947
1065- # 验证第三条逐笔成交数据
1066- third_tick = mock_result .iloc [2 ]
1067- self .assertEqual (third_tick ['time' ], 1755005515034 )
1068- self .assertEqual (third_tick ['price' ], 30.2 )
1069- self .assertEqual (third_tick ['volume' ], 3 )
1070-
1071948 # 验证最后一条逐笔成交数据
1072- last_tick = mock_result .iloc [5 ]
949+ last_tick = mock_result .iloc [- 1 ]
1073950 self .assertEqual (last_tick ['time' ], 1755005863136 )
1074951 self .assertEqual (last_tick ['price' ], 28.6 )
1075952 self .assertEqual (last_tick ['volume' ], 1 )
1076953
1077954 else :
1078955 result = self .client .get_option_trade_ticks (
1079- identifiers = ['AAPL 250815C00200000 ' ])
956+ identifiers = ['AAPL250829P00200000 ' ])
1080957 logger .debug (f"Option Trade Ticks (real):\n { result } " )
1081958
1082959 def test_get_option_symbols (self ):
@@ -1827,6 +1704,63 @@ def test_get_future_brief(self):
18271704 result = self .client .get_future_brief (identifiers = ['ES2509' ])
18281705 logger .debug (f"Future Brief: \n { result } " )
18291706
1707+ def test_get_future_depth (self ):
1708+ if self .is_mock :
1709+ mock_data = {"code" : 0 , "message" : "success" , "timestamp" : 1755847046112 , "data" : [
1710+ {"contractId" : "d2cf66f761354eda8ddbecc242f6d245" , "contractCode" : "ES2509" ,
1711+ "ask" : [{"price" : 6385.00 , "volume" : 1 }, {"price" : 6385.25 , "volume" : 23 },
1712+ {"price" : 6385.50 , "volume" : 30 }, {"price" : 6385.75 , "volume" : 26 }],
1713+ "bid" : [{"price" : 6384.75 , "volume" : 22 }, {"price" : 6384.50 , "volume" : 28 },
1714+ {"price" : 6384.25 , "volume" : 36 }, {"price" : 6384.00 , "volume" : 33 }]},
1715+ {"contractId" : "2971d762658f43c7bb26d353cc314b4d" , "contractCode" : "ES2512" ,
1716+ "ask" : [{"price" : 6440.75 , "volume" : 2 }, {"price" : 6441.00 , "volume" : 3 }],
1717+ "bid" : [{"price" : 6439.75 , "volume" : 1 }, {"price" : 6439.50 , "volume" : 2 }]}]}
1718+ web_utils .do_request = MagicMock (
1719+ return_value = json .dumps (mock_data ).encode ())
1720+
1721+ # {'identifier': 'ES2509', 'asks': [(6385.0, 1), (6385.25, 23), (6385.5, 30), (6385.75, 26), (6386.0, 43), (6386.25, 37), (6386.5, 31), (6386.75, 39), (6387.0, 39), (6387.25, 30)], 'bids': [(6384.75, 22), (6384.5, 28), (6384.25, 36), (6384.0, 33), (6383.75, 44), (6383.5, 32), (6383.25, 35), (6383.0, 38), (6382.75, 33), (6382.5, 42)]}
1722+ result_single = self .client .get_future_depth (identifiers = ['ES2509' ])
1723+
1724+ logger .debug (f"Future Depth (single): \n { result_single } " )
1725+ # Verify the result
1726+ self .assertIsNotNone (result_single )
1727+ self .assertIsInstance (result_single , dict )
1728+ self .assertIn ('ES2509' , result_single )
1729+ self .assertIn ('asks' , result_single ['ES2509' ])
1730+ self .assertIn ('bids' , result_single ['ES2509' ])
1731+ self .assertEqual (len (result_single ['ES2509' ]['asks' ]), 4 )
1732+ self .assertEqual (len (result_single ['ES2509' ]['bids' ]), 4 )
1733+ self .assertEqual (result_single ['ES2509' ]['identifier' ], 'ES2509' )
1734+ self .assertEqual (result_single ['ES2509' ]['asks' ][0 ], (6385.00 , 1 ))
1735+ self .assertEqual (result_single ['ES2509' ]['bids' ][0 ], (6384.75 , 22 ))
1736+
1737+ # {'ES2509': {'identifier': 'ES2509', 'asks': [(6385.0, 1), (6385.25, 23), (6385.5, 30), (6385.75, 26), (6386.0, 43), (6386.25, 37), (6386.5, 31), (6386.75, 39), (6387.0, 39), (6387.25, 30)], 'bids': [(6384.75, 22), (6384.5, 28), (6384.25, 36), (6384.0, 33), (6383.75, 44), (6383.5, 32), (6383.25, 35), (6383.0, 38), (6382.75, 33), (6382.5, 42)]}, 'ES2512': {'identifier': 'ES2512', 'asks': [(6440.75, 2), (6441.0, 3), (6441.25, 2), (6441.5, 2), (6441.75, 2), (6442.0, 4), (6442.25, 2), (6442.5, 1), (6442.75, 3), (6443.0, 4)], 'bids': [(6439.75, 1), (6439.5, 2), (6439.25, 1), (6439.0, 4), (6438.75, 2), (6438.5, 2), (6438.25, 2), (6438.0, 4), (6437.75, 2), (6437.5, 2)]}}
1738+ result_multi = self .client .get_future_depth (identifiers = ['ES2509' , 'ES2512' ])
1739+
1740+ # Verify the result
1741+ self .assertIsNotNone (result_multi )
1742+ self .assertIsInstance (result_multi , dict )
1743+ self .assertIn ('ES2509' , result_multi )
1744+ self .assertIn ('ES2512' , result_multi )
1745+ self .assertIn ('asks' , result_multi ['ES2509' ])
1746+ self .assertIn ('bids' , result_multi ['ES2509' ])
1747+ self .assertIn ('asks' , result_multi ['ES2512' ])
1748+ self .assertIn ('bids' , result_multi ['ES2512' ])
1749+ self .assertEqual (len (result_multi ['ES2509' ]['asks' ]), 4 )
1750+ self .assertEqual (len (result_multi ['ES2509' ]['bids' ]), 4 )
1751+ self .assertEqual (len (result_multi ['ES2512' ]['asks' ]), 2 )
1752+ self .assertEqual (len (result_multi ['ES2512' ]['bids' ]), 2 )
1753+ self .assertEqual (result_multi ['ES2509' ]['identifier' ], 'ES2509' )
1754+ self .assertEqual (result_multi ['ES2512' ]['identifier' ], 'ES2512' )
1755+ self .assertEqual (result_multi ['ES2509' ]['asks' ][0 ], (6385.00 , 1 ))
1756+ self .assertEqual (result_multi ['ES2509' ]['bids' ][0 ], (6384.75 , 22 ))
1757+ self .assertEqual (result_multi ['ES2512' ]['asks' ][0 ], (6440.75 , 2 ))
1758+ self .assertEqual (result_multi ['ES2512' ]['bids' ][0 ], (6439.75 , 1 ))
1759+
1760+ else :
1761+ result = self .client .get_future_depth (identifiers = ['ES2509' , 'ES2512' ])
1762+ logger .debug (f"Future Depth: \n { result } " )
1763+
18301764 def test_get_trading_calendar (self ):
18311765 if self .is_mock :
18321766 mock_data = {"code" : 0 , "message" : "success" , "timestamp" : 1755068224574 ,
@@ -1983,7 +1917,6 @@ def test_get_broker_hold(self):
19831917 result = self .client .get_broker_hold ()
19841918 logger .debug (f"Broker Hold:\n { result } " )
19851919
1986-
19871920 def test_market_scanner (self ):
19881921 """测试市场扫描器功能"""
19891922 if self .is_mock :
0 commit comments