@@ -563,7 +563,8 @@ def _data_get(self,
563563 page_token = None
564564 total_items = 0
565565 limit = kwargs .get ('limit' )
566- is_multi_symbol = not isinstance (symbol_or_symbols , str )
566+ is_multi_symbol = api_version == 'v1beta3' or \
567+ not isinstance (symbol_or_symbols , str )
567568 if resp_grouped_by_symbol is None :
568569 resp_grouped_by_symbol = is_multi_symbol
569570 while True :
@@ -578,7 +579,7 @@ def _data_get(self,
578579 path = f'/{ endpoint_base } '
579580 if loc :
580581 path += f'/{ loc } '
581- if api_version == 'v1beta3' or is_multi_symbol :
582+ if is_multi_symbol :
582583 data ['symbols' ] = _join_with_commas (symbol_or_symbols )
583584 elif symbol_or_symbols :
584585 path += f'/{ symbol_or_symbols } '
@@ -611,13 +612,15 @@ def get_trades_iter(self,
611612 limit : int = None ,
612613 feed : Optional [str ] = None ,
613614 asof : Optional [str ] = None ,
615+ sort : Optional [Sort ] = None ,
614616 raw = False ) -> TradeIterator :
615617 trades = self ._data_get ('trades' , symbol ,
616618 start = start ,
617619 end = end ,
618620 limit = limit ,
619621 feed = feed ,
620622 asof = asof ,
623+ sort = sort ,
621624 )
622625 for trade in trades :
623626 if raw :
@@ -632,13 +635,15 @@ def get_trades(self,
632635 limit : int = None ,
633636 feed : Optional [str ] = None ,
634637 asof : Optional [str ] = None ,
638+ sort : Optional [Sort ] = None ,
635639 ) -> TradesV2 :
636640 trades = list (self .get_trades_iter (symbol ,
637641 start = start ,
638642 end = end ,
639643 limit = limit ,
640644 feed = feed ,
641645 asof = asof ,
646+ sort = sort ,
642647 raw = True ))
643648 return TradesV2 (trades )
644649
@@ -649,13 +654,15 @@ def get_quotes_iter(self,
649654 limit : int = None ,
650655 feed : Optional [str ] = None ,
651656 asof : Optional [str ] = None ,
657+ sort : Optional [Sort ] = None ,
652658 raw = False ) -> QuoteIterator :
653659 quotes = self ._data_get ('quotes' , symbol ,
654660 start = start ,
655661 end = end ,
656662 limit = limit ,
657663 feed = feed ,
658664 asof = asof ,
665+ sort = sort ,
659666 )
660667 for quote in quotes :
661668 if raw :
@@ -670,6 +677,7 @@ def get_quotes(self,
670677 limit : int = None ,
671678 feed : Optional [str ] = None ,
672679 asof : Optional [str ] = None ,
680+ sort : Optional [Sort ] = None ,
673681 ) -> QuotesV2 :
674682 quotes = list (self .get_quotes_iter (symbol = symbol ,
675683 start = start ,
@@ -678,6 +686,7 @@ def get_quotes(self,
678686 feed = feed ,
679687 raw = True ,
680688 asof = asof ,
689+ sort = sort ,
681690 ))
682691 return QuotesV2 (quotes )
683692
@@ -690,6 +699,7 @@ def get_bars_iter(self,
690699 limit : int = None ,
691700 feed : Optional [str ] = None ,
692701 asof : Optional [str ] = None ,
702+ sort : Optional [Sort ] = None ,
693703 raw = False ) -> BarIterator :
694704 bars = self ._data_get ('bars' , symbol ,
695705 timeframe = timeframe ,
@@ -698,7 +708,9 @@ def get_bars_iter(self,
698708 end = end ,
699709 limit = limit ,
700710 feed = feed ,
701- asof = asof )
711+ asof = asof ,
712+ sort = sort ,
713+ )
702714 for bar in bars :
703715 if raw :
704716 yield bar
@@ -714,6 +726,7 @@ def get_bars(self,
714726 limit : int = None ,
715727 feed : Optional [str ] = None ,
716728 asof : Optional [str ] = None ,
729+ sort : Optional [Sort ] = None ,
717730 ) -> BarsV2 :
718731 bars = list (self .get_bars_iter (symbol ,
719732 timeframe ,
@@ -723,6 +736,7 @@ def get_bars(self,
723736 limit ,
724737 feed = feed ,
725738 asof = asof ,
739+ sort = sort ,
726740 raw = True ))
727741 return BarsV2 (bars )
728742
@@ -789,42 +803,75 @@ def get_snapshots(self, symbols: List[str],
789803 return self .response_wrapper (resp , SnapshotsV2 )
790804
791805 def get_crypto_trades_iter (self ,
792- symbol : str ,
806+ symbol : Union [ str , List [ str ]] ,
793807 start : Optional [str ] = None ,
794808 end : Optional [str ] = None ,
795809 limit : int = None ,
810+ sort : Optional [Sort ] = None ,
796811 loc : str = "us" ,
797812 raw = False ) -> TradeIterator :
798813 trades = self ._data_get ('trades' , symbol ,
799814 api_version = 'v1beta3' , endpoint_base = 'crypto' ,
800- start = start , end = end , limit = limit , loc = loc )
815+ start = start , end = end , limit = limit , sort = sort ,
816+ loc = loc )
801817 for trade in trades :
802818 if raw :
803819 yield trade
804820 else :
805821 yield self .response_wrapper (trade , Trade )
806822
807823 def get_crypto_trades (self ,
808- symbol : str ,
824+ symbol : Union [ str , List [ str ]] ,
809825 start : Optional [str ] = None ,
810826 end : Optional [str ] = None ,
811827 limit : int = None ,
828+ sort : Optional [Sort ] = None ,
812829 loc : str = "us" ) -> TradesV2 :
813830 return TradesV2 (list (self .get_crypto_trades_iter (
814- symbol , start , end , limit , loc , raw = True )))
831+ symbol , start , end , limit , sort , loc , raw = True )))
832+
833+ def get_crypto_quotes_iter (self ,
834+ symbol : Union [str , List [str ]],
835+ start : Optional [str ] = None ,
836+ end : Optional [str ] = None ,
837+ limit : int = None ,
838+ sort : Optional [Sort ] = None ,
839+ loc : str = "us" ,
840+ raw = False ) -> QuoteIterator :
841+ quotes = self ._data_get ('quotes' , symbol ,
842+ api_version = 'v1beta3' , endpoint_base = 'crypto' ,
843+ start = start , end = end , limit = limit , sort = sort ,
844+ loc = loc )
845+ for quote in quotes :
846+ if raw :
847+ yield quote
848+ else :
849+ yield self .response_wrapper (quote , Quote )
850+
851+ def get_crypto_quotes (self ,
852+ symbol : Union [str , List [str ]],
853+ start : Optional [str ] = None ,
854+ end : Optional [str ] = None ,
855+ limit : int = None ,
856+ sort : Optional [Sort ] = None ,
857+ loc : str = "us" ) -> QuotesV2 :
858+ return QuotesV2 (list (self .get_crypto_quotes_iter (
859+ symbol , start , end , limit , sort , loc , raw = True )))
815860
816861 def get_crypto_bars_iter (self ,
817862 symbol : Union [str , List [str ]],
818863 timeframe : TimeFrame ,
819864 start : Optional [str ] = None ,
820865 end : Optional [str ] = None ,
821866 limit : int = None ,
867+ sort : Optional [Sort ] = None ,
822868 loc : str = "us" ,
823869 raw = False ) -> BarIterator :
824870 bars = self ._data_get ('bars' , symbol ,
825871 api_version = 'v1beta3' , endpoint_base = 'crypto' ,
826872 timeframe = timeframe ,
827- start = start , end = end , limit = limit , loc = loc )
873+ start = start , end = end , limit = limit , sort = sort ,
874+ loc = loc )
828875 for bar in bars :
829876 if raw :
830877 yield bar
@@ -837,9 +884,10 @@ def get_crypto_bars(self,
837884 start : Optional [str ] = None ,
838885 end : Optional [str ] = None ,
839886 limit : int = None ,
887+ sort : Optional [Sort ] = None ,
840888 loc : str = "us" ) -> BarsV2 :
841889 return BarsV2 (list (self .get_crypto_bars_iter (
842- symbol , timeframe , start , end , limit , loc , raw = True )))
890+ symbol , timeframe , start , end , limit , sort , loc , raw = True )))
843891
844892 def get_latest_crypto_bars (self , symbols : List [str ],
845893 loc : str = "us" ) -> LatestBarsV2 :
@@ -1124,7 +1172,7 @@ def response_wrapper(self, obj, entity: Entity):
11241172 return entity (obj )
11251173
11261174
1127- def _join_with_commas (lst : List [str ]) -> str :
1128- if isinstance (lst , str ):
1129- raise ValueError ( 'expected list, str found' )
1130- return ',' .join (lst )
1175+ def _join_with_commas (x : Union [ str , List [str ] ]) -> str :
1176+ if isinstance (x , str ):
1177+ return x
1178+ return ',' .join (x )
0 commit comments