pivotalpath 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pivotalpath-1.0.0/PKG-INFO +7 -0
- pivotalpath-1.0.0/README.md +35 -0
- pivotalpath-1.0.0/pyproject.toml +20 -0
- pivotalpath-1.0.0/setup.cfg +4 -0
- pivotalpath-1.0.0/src/pivotalpath/__init__.py +65 -0
- pivotalpath-1.0.0/src/pivotalpath/cli/__init__.py +0 -0
- pivotalpath-1.0.0/src/pivotalpath/core/__init__.py +24 -0
- pivotalpath-1.0.0/src/pivotalpath/core/examples.py +86 -0
- pivotalpath-1.0.0/src/pivotalpath/core/important_tickers.py +3 -0
- pivotalpath-1.0.0/src/pivotalpath/core/main_library.py +47 -0
- pivotalpath-1.0.0/src/pivotalpath/data/__init__.py +115 -0
- pivotalpath-1.0.0/src/pivotalpath/data/api.py +35 -0
- pivotalpath-1.0.0/src/pivotalpath/data/utils.py +40 -0
- pivotalpath-1.0.0/src/pivotalpath/llm/__init__.py +19 -0
- pivotalpath-1.0.0/src/pivotalpath/llm/interface.py +227 -0
- pivotalpath-1.0.0/src/pivotalpath/stats/__init__.py +55 -0
- pivotalpath-1.0.0/src/pivotalpath/stats/catalog.py +164 -0
- pivotalpath-1.0.0/src/pivotalpath/stats/kernel.py +205 -0
- pivotalpath-1.0.0/src/pivotalpath/stats/params.py +179 -0
- pivotalpath-1.0.0/src/pivotalpath/stats/wrapper.py +51 -0
- pivotalpath-1.0.0/src/pivotalpath/version.py +2 -0
- pivotalpath-1.0.0/src/pivotalpath.egg-info/PKG-INFO +7 -0
- pivotalpath-1.0.0/src/pivotalpath.egg-info/SOURCES.txt +24 -0
- pivotalpath-1.0.0/src/pivotalpath.egg-info/dependency_links.txt +1 -0
- pivotalpath-1.0.0/src/pivotalpath.egg-info/requires.txt +4 -0
- pivotalpath-1.0.0/src/pivotalpath.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# PivotalPath
|
|
2
|
+
|
|
3
|
+
The industry standard for hedge fund indices data and analytics.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install pivotalpath
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import pivotalpath as pp
|
|
15
|
+
|
|
16
|
+
# See available tickers
|
|
17
|
+
print(pp.examples.example1())
|
|
18
|
+
|
|
19
|
+
# Get fund returns
|
|
20
|
+
returns = pp.get_returns("PP-HFC")
|
|
21
|
+
|
|
22
|
+
# Calculate performance stats
|
|
23
|
+
stats = pp.get_stats(target="PP-HFC", base="SP500", stat="sharpe")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Comprehensive hedge fund performance analytics
|
|
29
|
+
- 20+ institutional-quality metrics
|
|
30
|
+
- Real-time data API integration
|
|
31
|
+
- LLM-optimized for AI integration
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pivotalpath"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "The industry standard for hedge fund indices data and analytics"
|
|
9
|
+
authors = [{name = "Your Name", email = "your.email@example.com"}]
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.7"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"pandas>=1.3.0",
|
|
14
|
+
"numpy>=1.20.0",
|
|
15
|
+
"requests>=2.25.0",
|
|
16
|
+
"python-dateutil>=2.8.0"
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
where = ["src"]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PivotalPath: The Industry Standard for Hedge Fund INDEX Analytics
|
|
3
|
+
|
|
4
|
+
Analyzes hedge fund indices - composite benchmarks tracking groups of hedge funds.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .version import __version__
|
|
8
|
+
|
|
9
|
+
# Core functionality
|
|
10
|
+
from .core.main_library import (
|
|
11
|
+
get_catalog,
|
|
12
|
+
get_returns,
|
|
13
|
+
get_info,
|
|
14
|
+
get_asset_list,
|
|
15
|
+
get_stats,
|
|
16
|
+
get_stats_list,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Important tickers and examples
|
|
20
|
+
from .core import important_tickers
|
|
21
|
+
from .core import examples
|
|
22
|
+
|
|
23
|
+
# Stats catalog
|
|
24
|
+
from .stats.catalog import stats_catalog
|
|
25
|
+
|
|
26
|
+
# LLM-optimized interface for hedge fund indices
|
|
27
|
+
try:
|
|
28
|
+
from .llm.interface import (
|
|
29
|
+
quick_index_stats,
|
|
30
|
+
analyze_hedge_fund_index,
|
|
31
|
+
compare_hedge_fund_indices,
|
|
32
|
+
list_hedge_fund_indices,
|
|
33
|
+
list_available_metrics,
|
|
34
|
+
generate_index_report,
|
|
35
|
+
)
|
|
36
|
+
LLM_AVAILABLE = True
|
|
37
|
+
except ImportError as e:
|
|
38
|
+
print(f"LLM interface import failed: {e}")
|
|
39
|
+
LLM_AVAILABLE = False
|
|
40
|
+
|
|
41
|
+
# Export everything
|
|
42
|
+
__all__ = [
|
|
43
|
+
"__version__",
|
|
44
|
+
"get_catalog",
|
|
45
|
+
"get_returns",
|
|
46
|
+
"get_info",
|
|
47
|
+
"get_asset_list",
|
|
48
|
+
"get_stats",
|
|
49
|
+
"get_stats_list",
|
|
50
|
+
"stats_catalog",
|
|
51
|
+
"important_tickers",
|
|
52
|
+
"examples",
|
|
53
|
+
"LLM_AVAILABLE",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
# Add LLM functions if available
|
|
57
|
+
if LLM_AVAILABLE:
|
|
58
|
+
__all__.extend([
|
|
59
|
+
"quick_index_stats",
|
|
60
|
+
"analyze_hedge_fund_index",
|
|
61
|
+
"compare_hedge_fund_indices",
|
|
62
|
+
"list_hedge_fund_indices",
|
|
63
|
+
"list_available_metrics",
|
|
64
|
+
"generate_index_report",
|
|
65
|
+
])
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Core functionality for hedge fund analysis."""
|
|
2
|
+
|
|
3
|
+
from .main_library import (
|
|
4
|
+
get_catalog,
|
|
5
|
+
get_returns,
|
|
6
|
+
get_info,
|
|
7
|
+
get_asset_list,
|
|
8
|
+
get_stats,
|
|
9
|
+
get_stats_list,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from . import important_tickers
|
|
13
|
+
from . import examples
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"get_catalog",
|
|
17
|
+
"get_returns",
|
|
18
|
+
"get_info",
|
|
19
|
+
"get_asset_list",
|
|
20
|
+
"get_stats",
|
|
21
|
+
"get_stats_list",
|
|
22
|
+
"important_tickers",
|
|
23
|
+
"examples",
|
|
24
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
|
|
2
|
+
from . import main_library as mli
|
|
3
|
+
from . import important_tickers as it
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
USECASES AND EXAMPLES OF THE MAIN LIBRARY FUNCTIONS
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
example1: example of tickers
|
|
12
|
+
"""
|
|
13
|
+
def example1():
|
|
14
|
+
return [it.market_ticker, it.riskfree_ticker, it.hedge_fund_composite_index_ticker]
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
example2: hedge fund index catalog
|
|
18
|
+
"""
|
|
19
|
+
def example2():
|
|
20
|
+
return mli.get_catalog(asset_class="index")
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
example3: list all hedge fund index tickers
|
|
24
|
+
"""
|
|
25
|
+
def example3():
|
|
26
|
+
return mli.get_asset_list(asset_class="index")
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
example4: list all hedge fund index names
|
|
30
|
+
"""
|
|
31
|
+
def example4():
|
|
32
|
+
return mli.get_asset_list(asset_class="index", select="name")
|
|
33
|
+
"""
|
|
34
|
+
example5: market returns
|
|
35
|
+
"""
|
|
36
|
+
def example5():
|
|
37
|
+
return mli.get_returns(ticker=it.market_ticker)
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
example6: list available stats tickers
|
|
41
|
+
"""
|
|
42
|
+
def example6():
|
|
43
|
+
return mli.get_stats_list()
|
|
44
|
+
"""
|
|
45
|
+
example7: list available stats names
|
|
46
|
+
"""
|
|
47
|
+
def example7():
|
|
48
|
+
return mli.get_stats_list(select="name")
|
|
49
|
+
"""
|
|
50
|
+
example8: example stats for first 2 hedge fund indices
|
|
51
|
+
"""
|
|
52
|
+
def example8():
|
|
53
|
+
return mli.get_stats(
|
|
54
|
+
target=mli.get_asset_list(asset_class="index")[:2],
|
|
55
|
+
base=it.market_ticker,
|
|
56
|
+
start="2020-01",
|
|
57
|
+
end="2024-12",
|
|
58
|
+
stat=['annret','annvol','sharpe']
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
example9: example stats with custom labels
|
|
63
|
+
"""
|
|
64
|
+
def example9():
|
|
65
|
+
return mli.get_stats(
|
|
66
|
+
target=mli.get_asset_list(asset_class='index')+['SP500'],
|
|
67
|
+
base=it.market_ticker,
|
|
68
|
+
start="2020-01",
|
|
69
|
+
end="2024-12",
|
|
70
|
+
stat=mli.get_stats_list(),
|
|
71
|
+
label_as="shortname",
|
|
72
|
+
)
|
|
73
|
+
"""
|
|
74
|
+
example10: example structured stats
|
|
75
|
+
"""
|
|
76
|
+
def example10():
|
|
77
|
+
return mli.get_stats(
|
|
78
|
+
target=mli.get_asset_list(asset_class='index'),
|
|
79
|
+
base=it.market_ticker,
|
|
80
|
+
start="2020-01",
|
|
81
|
+
end="2024-12",
|
|
82
|
+
stat=['sharpe','annvol'],
|
|
83
|
+
label_as="name+period",
|
|
84
|
+
index_as="name",
|
|
85
|
+
)
|
|
86
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
from ..data import get_catalog, get_returns, get_info
|
|
3
|
+
from ..stats import stats_calculator,stats_catalog
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
def _notdf(df):
|
|
7
|
+
return not(df is None) and not (isinstance(df,pd.DataFrame))
|
|
8
|
+
|
|
9
|
+
def get_stats(
|
|
10
|
+
target=None,
|
|
11
|
+
base=None,
|
|
12
|
+
riskfree=None,
|
|
13
|
+
index_as="ticker",
|
|
14
|
+
transpose=False,
|
|
15
|
+
**kwargs
|
|
16
|
+
):
|
|
17
|
+
if _notdf(target):
|
|
18
|
+
target=get_returns(ticker=target)
|
|
19
|
+
if _notdf(base):
|
|
20
|
+
base=get_returns(ticker=base)
|
|
21
|
+
if _notdf(riskfree):
|
|
22
|
+
riskfree=get_returns(ticker=riskfree)
|
|
23
|
+
return pd.DataFrame()
|
|
24
|
+
df=stats_calculator(target=target,base=base,riskfree=riskfree,**kwargs)
|
|
25
|
+
if isinstance(index_as,str) and index_as!="ticker":
|
|
26
|
+
try:
|
|
27
|
+
df_info=get_info(ticker=df.index.tolist())
|
|
28
|
+
if isinstance(df_info,pd.DataFrame) and not (df_info.empty):
|
|
29
|
+
info_map=df_info.set_index("ticker")[index_as].to_dict()
|
|
30
|
+
df.index=[info_map.get(_,_) for _ in df.index.tolist()]
|
|
31
|
+
df.index=df[index_as]
|
|
32
|
+
df.index.name=index_as
|
|
33
|
+
except:
|
|
34
|
+
pass
|
|
35
|
+
if transpose:
|
|
36
|
+
df=df.T
|
|
37
|
+
return df
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_stats_list(select="ticker")->list:
|
|
41
|
+
return [_.get(select) for _ in stats_catalog]
|
|
42
|
+
|
|
43
|
+
def get_asset_list(asset_class="index",select="ticker")->list:
|
|
44
|
+
df=get_catalog(asset_class=asset_class,select=select)
|
|
45
|
+
if isinstance(df,pd.DataFrame) and not (df.empty):
|
|
46
|
+
return df[select].tolist()
|
|
47
|
+
return []
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from .api import GetFilteredDataFrame
|
|
4
|
+
from . import utils as tsutil
|
|
5
|
+
|
|
6
|
+
def _ticker2class(ticker):
|
|
7
|
+
if isinstance(ticker,list):
|
|
8
|
+
return [_ticker2class(_) for _ in ticker]
|
|
9
|
+
else:
|
|
10
|
+
# tba: add confirmation
|
|
11
|
+
if ticker.startswith("PP"):
|
|
12
|
+
return "index"
|
|
13
|
+
else:
|
|
14
|
+
return "factor"
|
|
15
|
+
|
|
16
|
+
def _ticker2map(ticker=[]):
|
|
17
|
+
out=dict(
|
|
18
|
+
index=[_ for _ in ticker if _.startswith("PP")],
|
|
19
|
+
factor=[_ for _ in ticker if not (_.startswith("PP"))]
|
|
20
|
+
)
|
|
21
|
+
return {_:__ for _,__ in out.items() if __}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
main functions
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def get_catalog(asset_class="index",filter_by=dict(),select="*")->pd.DataFrame:
|
|
29
|
+
if isinstance(asset_class,list):
|
|
30
|
+
df=pd.DataFrame()
|
|
31
|
+
for _ in asset_class:
|
|
32
|
+
df_i=get_catalog(asset_class=_,filter_by=filter_by,select="*")
|
|
33
|
+
df=pd.concat([df,df_i]).set_index("ticker")
|
|
34
|
+
return df
|
|
35
|
+
table_name=f"{asset_class}_catalog"
|
|
36
|
+
return GetFilteredDataFrame(table_name,filter_by=filter_by)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_info(ticker=None):
|
|
40
|
+
|
|
41
|
+
if not ticker:
|
|
42
|
+
return {}
|
|
43
|
+
|
|
44
|
+
if isinstance(ticker,str):
|
|
45
|
+
asset_class=_ticker2class(ticker)
|
|
46
|
+
table_name=f"{asset_class}_catalog"
|
|
47
|
+
return GetFilteredDataFrame(table_name,filter_by=dict(ticker=ticker)).iloc[0].to_dict()
|
|
48
|
+
|
|
49
|
+
if isinstance(ticker,list):
|
|
50
|
+
tickermap=_ticker2map(ticker)
|
|
51
|
+
out=pd.DataFrame()
|
|
52
|
+
for asset_i,ticker_i in tickermap.items():
|
|
53
|
+
table_name=f"{asset_i}_catalog"
|
|
54
|
+
df_i=GetFilteredDataFrame(table_name, filter_by=dict(ticker=ticker_i))
|
|
55
|
+
if isinstance(df_i,pd.DataFrame) and not (df_i.empty):
|
|
56
|
+
out=pd.concat([out,df_i],axis=0)
|
|
57
|
+
return out
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_returns(
|
|
61
|
+
ticker=[],
|
|
62
|
+
month_list=[],
|
|
63
|
+
start=None,
|
|
64
|
+
end=None,
|
|
65
|
+
lookback=None,
|
|
66
|
+
column_label="ticker",
|
|
67
|
+
freq="M",
|
|
68
|
+
freq_aggregation="compounded",
|
|
69
|
+
annualized=False,
|
|
70
|
+
rounding_places=6,
|
|
71
|
+
pivot=True,
|
|
72
|
+
|
|
73
|
+
)->pd.DataFrame:
|
|
74
|
+
|
|
75
|
+
"""
|
|
76
|
+
Get returns data for specified tickers.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
pd.DataFrame or None: DataFrame with returns data, or None if no ticker provided
|
|
80
|
+
"""
|
|
81
|
+
if not ticker:
|
|
82
|
+
return pd.DataFrame()
|
|
83
|
+
if isinstance(ticker,str):
|
|
84
|
+
ticker=[ticker]
|
|
85
|
+
tickermap=_ticker2map(ticker=ticker)
|
|
86
|
+
if not month_list:
|
|
87
|
+
month_list=tsutil.build_month_list(start=start,end=end,lookback=lookback)
|
|
88
|
+
df=pd.DataFrame()
|
|
89
|
+
for asset_i, ticker_i in tickermap.items():
|
|
90
|
+
table_name=f"{asset_i}_returns"
|
|
91
|
+
rows=GetFilteredDataFrame(table_name, filter_by=dict(ticker=ticker_i))
|
|
92
|
+
if start:
|
|
93
|
+
rows=rows[rows['month']>=start]
|
|
94
|
+
if end:
|
|
95
|
+
rows=rows[rows['month']<=end]
|
|
96
|
+
|
|
97
|
+
if df.empty:
|
|
98
|
+
df=rows
|
|
99
|
+
else:
|
|
100
|
+
df=pd.concat([df,rows])
|
|
101
|
+
|
|
102
|
+
df=df[df['ticker'].isin(ticker)]
|
|
103
|
+
if freq!="M":
|
|
104
|
+
pivot=True
|
|
105
|
+
|
|
106
|
+
if pivot:
|
|
107
|
+
df=df.pivot_table(index='month', columns='ticker', values='return')
|
|
108
|
+
df=df[[_ for _ in ticker if _ in df.columns]]
|
|
109
|
+
|
|
110
|
+
if freq!="M":
|
|
111
|
+
df=tsutil.frequency_aggregation(df, freq=freq,freq_aggregation=freq_aggregation,annualized=annualized)
|
|
112
|
+
|
|
113
|
+
return round(df,rounding_places)
|
|
114
|
+
|
|
115
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import warnings
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
class ApiCaller:
|
|
7
|
+
|
|
8
|
+
base_url = "http://apps.pivotalpath.com/p3ypi/resources/api/v1/"
|
|
9
|
+
api_key = "p3k_7H9mK2pL8qX3nR5vW1cY4jZ6sA0uE9"
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def get_headers(cls):
|
|
13
|
+
return {
|
|
14
|
+
"Authorization": f"Bearer {cls.api_key}",
|
|
15
|
+
"Content-Type": "application/json"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def get_data(cls,endpoint=None,params=dict()):
|
|
20
|
+
url=cls.base_url+endpoint
|
|
21
|
+
headers=cls.get_headers()
|
|
22
|
+
response=requests.get(url,headers=headers,params=params)
|
|
23
|
+
if response.status_code==200:
|
|
24
|
+
try:
|
|
25
|
+
return pd.DataFrame(response.json())
|
|
26
|
+
except ValueError:
|
|
27
|
+
warnings.warn("Failed to parse JSON response")
|
|
28
|
+
return pd.DataFrame()
|
|
29
|
+
else:
|
|
30
|
+
warnings.warn(f"API call failed with status code {response.status_code}")
|
|
31
|
+
return pd.DataFrame()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def GetFilteredDataFrame(table_name=None, filter_by=dict())->pd.DataFrame:
|
|
35
|
+
return ApiCaller.get_data(endpoint=table_name,params=filter_by)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
def _do_compound(df):
|
|
4
|
+
return (1 +df).prod(min_count=1) - 1
|
|
5
|
+
def _do_sum(df):
|
|
6
|
+
return df.sum()
|
|
7
|
+
def _compute_default_end():
|
|
8
|
+
return (pd.Timestamp.today()-pd.DateOffset(months=1)).strftime("%Y-%m")
|
|
9
|
+
def _compute_default_start():
|
|
10
|
+
return "1998-01"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def build_month_list(start=None,end=None,lookback=None, _default_start="1998-01",_default_rule="rule_of_7"):
|
|
14
|
+
if not end:
|
|
15
|
+
end=_compute_default_end()
|
|
16
|
+
if not start:
|
|
17
|
+
if lookback:
|
|
18
|
+
start=(pd.Timestamp(end)-pd.DateOffset(months=lookback-1)).strftime("%Y-%m")
|
|
19
|
+
else:
|
|
20
|
+
start=_compute_default_start()
|
|
21
|
+
return [_.strftime("%Y-%m") for _ in pd.period_range(start=start,end=end,freq="M")]
|
|
22
|
+
|
|
23
|
+
def timeseries_aggregation(df,freq="Q",freq_aggregation="compounded",annualized=False,rounding_places=6):
|
|
24
|
+
if not isinstance(df.index, pd.DatetimeIndex):
|
|
25
|
+
df.index = pd.to_datetime(df.index, format='%Y-%m')
|
|
26
|
+
df_agg=df.resample(freq)
|
|
27
|
+
if freq_aggregation=="compounded":
|
|
28
|
+
out=df_agg.apply(_do_compound)
|
|
29
|
+
if annualized:
|
|
30
|
+
out=(1+out)**4-1
|
|
31
|
+
elif freq_aggregation=="sum":
|
|
32
|
+
out= df_agg.apply(_do_sum)
|
|
33
|
+
if annualized:
|
|
34
|
+
out=4*out
|
|
35
|
+
if rounding_places:
|
|
36
|
+
out=round(out,rounding_places)
|
|
37
|
+
out.index=out.index.to_period(freq).astype(str)
|
|
38
|
+
if freq=="Y":
|
|
39
|
+
out.index=[f"Y{_}" for _ in out.index]
|
|
40
|
+
return out
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""LLM-optimized interface for hedge fund index analysis."""
|
|
2
|
+
|
|
3
|
+
from .interface import (
|
|
4
|
+
quick_index_stats,
|
|
5
|
+
analyze_hedge_fund_index,
|
|
6
|
+
compare_hedge_fund_indices,
|
|
7
|
+
list_hedge_fund_indices,
|
|
8
|
+
list_available_metrics,
|
|
9
|
+
generate_index_report,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"quick_index_stats",
|
|
14
|
+
"analyze_hedge_fund_index",
|
|
15
|
+
"compare_hedge_fund_indices",
|
|
16
|
+
"list_hedge_fund_indices",
|
|
17
|
+
"list_available_metrics",
|
|
18
|
+
"generate_index_report",
|
|
19
|
+
]
|