2929
3030import multitasking as _multitasking
3131import pandas as _pd
32+ import numpy as _np
3233from curl_cffi import requests
3334
3435from . import Ticker , utils
@@ -204,15 +205,13 @@ def _download_impl(ctx, tickers, start=None, end=None, actions=False, threads=Tr
204205 for tkr , df in ctx .dfs .items ():
205206 if df is not None and df .shape [0 ] > 0 :
206207 df .index = df .index .tz_localize (None )
207-
208+ ctx . dfs = reindex_dfs ( ctx . dfs , ignore_tz )
208209 try :
209210 data = _pd .concat (ctx .dfs .values (), axis = 1 , sort = True ,
210211 keys = ctx .dfs .keys (), names = ['Ticker' , 'Price' ])
211212 except Exception :
212- _realign_dfs (ctx )
213213 data = _pd .concat (ctx .dfs .values (), axis = 1 , sort = True ,
214214 keys = ctx .dfs .keys (), names = ['Ticker' , 'Price' ])
215- data .index = _pd .to_datetime (data .index , utc = not ignore_tz )
216215 data .rename (columns = ctx .isins , inplace = True )
217216
218217 if group_by == 'column' :
@@ -224,28 +223,32 @@ def _download_impl(ctx, tickers, start=None, end=None, actions=False, threads=Tr
224223
225224 return data
226225
227-
228- def _realign_dfs (ctx ):
229- idx_len = 0
230- idx = None
231-
232- for df in ctx .dfs .values ():
233- if len (df ) > idx_len :
234- idx_len = len (df )
235- idx = df .index
236-
237- for key in list (ctx .dfs .keys ()):
238- try :
239- ctx .dfs [key ] = _pd .DataFrame (
240- index = idx , data = ctx .dfs [key ]).drop_duplicates ()
241- except Exception :
242- ctx .dfs [key ] = _pd .concat ([
243- utils .empty_df (idx ), ctx .dfs [key ].dropna ()
244- ], axis = 0 , sort = True )
245-
246- ctx .dfs [key ] = ctx .dfs [key ].loc [
247- ~ ctx .dfs [key ].index .duplicated (keep = 'last' )]
248-
226+ def reindex_dfs (dfs , ignore_tz ):
227+ if ignore_tz :
228+ for tkr in dfs .keys ():
229+ if (dfs [tkr ] is not None ) and (not dfs [tkr ].empty ):
230+ dfs [tkr ].index = dfs [tkr ].index .tz_localize (None )
231+ else :
232+ # Align each df to most common timezone.
233+ # Compare strings since np.unique can't handle tz objects
234+ tzs = [str (df .index .tz ) for df in dfs .values () if df is not None and not df .empty ]
235+ if tzs :
236+ # Find most common timezone
237+ unique_tzs , counts = _np .unique (tzs , return_counts = True )
238+ tz_mode = unique_tzs [counts .argmax ()]
239+ for tkr in dfs .keys ():
240+ if (dfs [tkr ] is not None ) and (not dfs [tkr ].empty ):
241+ dfs [tkr ].index = dfs [tkr ].index .tz_convert (tz_mode )
242+
243+ all_indices = set ()
244+ for df in dfs .values ():
245+ all_indices .update (df .index )
246+ idx = sorted (all_indices )
247+ idx = _pd .to_datetime (idx )
248+ for key , df in dfs .items ():
249+ dfs [key ] = df .reindex (idx )
250+
251+ return dfs
249252
250253@_multitasking .task
251254def _download_one_threaded (ctx , ticker , start = None , end = None ,
0 commit comments