New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

quantstats

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quantstats - pypi Package Compare versions

Comparing version
0.0.75
to
0.0.76
+1
-1
PKG-INFO
Metadata-Version: 2.4
Name: QuantStats
Version: 0.0.75
Version: 0.0.76
Summary: Portfolio analytics for quants

@@ -5,0 +5,0 @@ Home-page: https://github.com/ranaroussi/quantstats

Metadata-Version: 2.4
Name: QuantStats
Version: 0.0.75
Version: 0.0.76
Summary: Portfolio analytics for quants

@@ -5,0 +5,0 @@ Home-page: https://github.com/ranaroussi/quantstats

@@ -61,2 +61,32 @@ #!/usr/bin/env python

def normalize_timezone(data: Union[pd.Series, pd.DataFrame]) -> Union[pd.Series, pd.DataFrame]:
"""
Normalize timezone information for consistent comparisons.
If data has timezone info, converts to UTC then removes timezone info.
This ensures all data can be compared regardless of original timezone.
Parameters
----------
data : pd.Series or pd.DataFrame
Time series data with DatetimeIndex
Returns
-------
pd.Series or pd.DataFrame
Data with timezone-naive DatetimeIndex
"""
if not isinstance(data.index, pd.DatetimeIndex):
return data
# If timezone aware, convert to UTC then make naive
if data.index.tz is not None:
result = data.copy()
result.index = result.index.tz_convert('UTC').tz_localize(None)
return result
# Already timezone naive, return as is
return data
def safe_resample(data: Union[pd.Series, pd.DataFrame],

@@ -71,3 +101,4 @@ freq: str,

frequency aliases and aggregation methods that are compatible across
different pandas versions.
different pandas versions. It also normalizes timezones to ensure
consistent comparisons.

@@ -89,3 +120,4 @@ Parameters

pd.Series or pd.DataFrame
The resampled data with the specified frequency and aggregation
The resampled data with the specified frequency and aggregation,
with timezone normalized to UTC if present, or naive if not

@@ -109,30 +141,34 @@ Examples

# This approach avoids deprecation warnings and ensures compatibility
result = None
if isinstance(func_name, str):
# Map common aggregation functions to their pandas methods
if func_name == "sum":
return resampler.sum(**kwargs)
result = resampler.sum(**kwargs)
elif func_name == "mean":
return resampler.mean(**kwargs)
result = resampler.mean(**kwargs)
elif func_name == "std":
return resampler.std(**kwargs)
result = resampler.std(**kwargs)
elif func_name == "count":
return resampler.count(**kwargs)
result = resampler.count(**kwargs)
elif func_name == "min":
return resampler.min(**kwargs)
result = resampler.min(**kwargs)
elif func_name == "max":
return resampler.max(**kwargs)
result = resampler.max(**kwargs)
elif func_name == "first":
return resampler.first(**kwargs)
result = resampler.first(**kwargs)
elif func_name == "last":
return resampler.last(**kwargs)
result = resampler.last(**kwargs)
else:
# Try to find the method on the resampler object
if hasattr(resampler, func_name):
return getattr(resampler, func_name)(**kwargs)
result = getattr(resampler, func_name)(**kwargs)
else:
# Fallback to apply for custom string functions
return resampler.apply(func_name, **kwargs)
result = resampler.apply(func_name, **kwargs)
else:
# For callable functions, use apply method
return resampler.apply(func_name, **kwargs)
result = resampler.apply(func_name, **kwargs)
# Normalize timezone to ensure consistent comparisons
return normalize_timezone(result)

@@ -139,0 +175,0 @@

@@ -164,3 +164,3 @@ #!/usr/bin/env python

# Convert to portfolio format and calculate percentage changes
returns = _utils.make_portfolio(returns.dropna(), 1, mode).pct_change().fillna(0)
returns = _utils.make_portfolio(returns.dropna(), 1, mode).pct_change(fill_method=None).fillna(0)

@@ -167,0 +167,0 @@ # Use current figure size if not specified

@@ -455,2 +455,7 @@ #!/usr/bin/env python

"""
# Normalize timezone for consistency before aggregation
# Convert to UTC if timezone-aware, then make naive
if hasattr(returns.index, 'tz') and returns.index.tz is not None:
returns = returns.tz_convert('UTC').tz_localize(None)
# Return original data if no period specified or daily period

@@ -566,4 +571,6 @@ if period is None or "day" in period:

# Remove timezone information for consistency
data = data.tz_localize(None)
# Normalize timezone information for consistency
# Convert to UTC if timezone-aware, then make naive
if hasattr(data.index, 'tz') and data.index.tz is not None:
data = data.tz_convert('UTC').tz_localize(None)
return data

@@ -608,6 +615,6 @@

if col_clean.min() >= 0 and col_clean.max() > 1:
data[col] = data[col].pct_change()
data[col] = data[col].pct_change(fill_method=None)
# Process Series data
elif data.min() >= 0 and data.max() > 1:
data = data.pct_change()
data = data.pct_change(fill_method=None)

@@ -640,4 +647,6 @@ # cleanup data - replace infinite values with NaN

# Remove timezone information for consistency
data = data.tz_localize(None)
# Normalize timezone information for consistency
# Convert to UTC if timezone-aware, then make naive
if hasattr(data.index, 'tz') and data.index.tz is not None:
data = data.tz_convert('UTC').tz_localize(None)

@@ -686,4 +695,4 @@ # Cache the result

# Download data and calculate returns
df = safe_yfinance_download(proxy=proxy, **params)["Close"].pct_change() # type: ignore
df = df.tz_localize(None)
df = safe_yfinance_download(proxy=proxy, **params)["Close"].pct_change(fill_method=None) # type: ignore
df = df.fillna(0).tz_localize(None)
return df

@@ -719,3 +728,3 @@

.reindex(period)
.pct_change()
.pct_change(fill_method=None)
.fillna(0)

@@ -725,4 +734,7 @@ )

# Remove timezone information
benchmark = benchmark.tz_localize(None)
# Normalize timezone information for consistent comparisons
# Convert to UTC if timezone-aware, then make naive
if hasattr(benchmark.index, 'tz') and benchmark.index.tz is not None:
benchmark = benchmark.tz_convert('UTC').tz_localize(None)
# If already timezone-naive, no action needed

@@ -729,0 +741,0 @@ # Prepare returns or return raw data

@@ -1,1 +0,1 @@

version = "0.0.75"
version = "0.0.76"

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display