quantmod 0.0.1__tar.gz → 0.0.2__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.
- {quantmod-0.0.1 → quantmod-0.0.2}/PKG-INFO +2 -3
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/__init__.py +6 -2
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/datasets/__init__.py +2 -2
- {quantmod-0.0.1/quantmod/indicators → quantmod-0.0.2/quantmod/datasets/data}/__init__.py +1 -7
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/datasets/dataloader.py +11 -7
- quantmod-0.0.2/quantmod/indicators/__init__.py +28 -0
- quantmod-0.0.2/quantmod/indicators/indicators.py +167 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/timeseries/performance.py +52 -42
- quantmod-0.0.2/quantmod/version.py +1 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/PKG-INFO +2 -3
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/SOURCES.txt +2 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/setup.py +9 -3
- quantmod-0.0.1/quantmod/indicators/indicators.py +0 -51
- {quantmod-0.0.1 → quantmod-0.0.2}/LICENSE.txt +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/README.md +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/_version.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/derivatives/__init__.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/derivatives/options.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/main.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/markets/__init__.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/markets/bb.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/markets/yahoo.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/models/__init__.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/models/blackscholes.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/models/montecarlo.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/models/optioninputs.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/risk/__init__.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/risk/riskinputs.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/risk/var.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/risk/varbacktester.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/timeseries/__init__.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/timeseries/timeseries.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod/utils.py +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/dependency_links.txt +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/entry_points.txt +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/not-zip-safe +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/requires.txt +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/quantmod.egg-info/top_level.txt +0 -0
- {quantmod-0.0.1 → quantmod-0.0.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: quantmod
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Quantmod Python Package
|
|
5
5
|
Home-page: https://kannansingaravelu.com/
|
|
6
6
|
Author: Kannan Singaravelu
|
|
@@ -10,7 +10,6 @@ Keywords: python,quant,quantmod,quantmod-python
|
|
|
10
10
|
Platform: any
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Operating System :: OS Independent
|
|
16
15
|
Classifier: Intended Audience :: Developers
|
|
@@ -18,7 +17,7 @@ Classifier: Topic :: Office/Business :: Financial
|
|
|
18
17
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
19
18
|
Classifier: Topic :: Software Development :: Libraries
|
|
20
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.10
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
23
22
|
License-File: LICENSE.txt
|
|
24
23
|
Requires-Dist: numpy>=2.0.2
|
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
# updated by Kannan Singaravelu on 2024-08-26
|
|
19
19
|
|
|
20
|
-
from . import _version
|
|
21
|
-
__version__ = _version.get_versions()['version']
|
|
20
|
+
# from . import _version
|
|
21
|
+
# __version__ = _version.get_versions()['version']
|
|
22
22
|
|
|
23
|
+
from . import version
|
|
23
24
|
from .main import hello
|
|
24
25
|
|
|
25
26
|
from quantmod import (
|
|
@@ -41,3 +42,6 @@ __all__ = [
|
|
|
41
42
|
"timeseries",
|
|
42
43
|
"datasets"
|
|
43
44
|
]
|
|
45
|
+
|
|
46
|
+
__version__ = version.version
|
|
47
|
+
__author__ = "Kannan Singaravelu"
|
|
@@ -14,10 +14,4 @@
|
|
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
from .indicators import ATR
|
|
20
|
-
|
|
21
|
-
__all__ = [
|
|
22
|
-
"ATR",
|
|
23
|
-
]
|
|
17
|
+
#
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
from quantmod.utils import convert_date_format
|
|
3
|
+
import importlib.resources as pkg_resources
|
|
4
|
+
from . import data
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
def fetch_historical_data(symbol: str, start_date: str=None, end_date: str=None) -> pd.DataFrame:
|
|
5
8
|
"""
|
|
@@ -27,10 +30,16 @@ def fetch_historical_data(symbol: str, start_date: str=None, end_date: str=None)
|
|
|
27
30
|
If the start date is greater than the last date in the dataset or the end date is less than the first date in the dataset
|
|
28
31
|
"""
|
|
29
32
|
|
|
33
|
+
def read_csv_file(filename):
|
|
34
|
+
with pkg_resources.path(data, filename) as file_path:
|
|
35
|
+
return pd.read_csv(file_path)
|
|
36
|
+
|
|
30
37
|
if symbol.lower() == "spx":
|
|
31
|
-
df =
|
|
38
|
+
df = read_csv_file("spx.csv")
|
|
39
|
+
# df = pd.read_csv("./data/spx.csv")
|
|
32
40
|
elif symbol.lower() == "nifty":
|
|
33
|
-
df =
|
|
41
|
+
df = read_csv_file("nifty50.csv")
|
|
42
|
+
# df = pd.read_csv("./data/nifty50.csv")
|
|
34
43
|
else:
|
|
35
44
|
raise ValueError("Invalid symbol. Only SPX & NIFTY is supported")
|
|
36
45
|
|
|
@@ -54,8 +63,3 @@ def fetch_historical_data(symbol: str, start_date: str=None, end_date: str=None)
|
|
|
54
63
|
query_str = f"date >= '{start_date}' and date <= '{end_date}'"
|
|
55
64
|
return df.query(query_str)
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
# if __name__ == "__main__":
|
|
59
|
-
# df = fetch_historical_data("nifty")
|
|
60
|
-
# print(df.head())
|
|
61
|
-
# print(df.tail())
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Quantmod Python Package
|
|
2
|
+
# https://kannansingaravelu.com/
|
|
3
|
+
|
|
4
|
+
# Copyright 2024 Kannan Singaravelu
|
|
5
|
+
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
from .indicators import ATR, BBands, SMA, EMA, MACD, RSI
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ATR",
|
|
23
|
+
"BBands",
|
|
24
|
+
"SMA",
|
|
25
|
+
"EMA",
|
|
26
|
+
"MACD",
|
|
27
|
+
"RSI"
|
|
28
|
+
]
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
def ATR(df: pd.DataFrame, lookback: int = 14) -> pd.Series:
|
|
4
|
+
"""
|
|
5
|
+
Calculate the Average True Range (ATR).
|
|
6
|
+
|
|
7
|
+
ATR is a volatility indicator that measures the average of the true range values
|
|
8
|
+
over a specified period. An expanding ATR indicates increased volatility, while
|
|
9
|
+
a low ATR value indicates a series of periods with small price ranges.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
df : pd.DataFrame
|
|
14
|
+
dataFrame with OHLC (Open, High, Low, Close) price data
|
|
15
|
+
lookback : int, optional
|
|
16
|
+
number of periods to use for ATR calculation, by default 14
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
pd.Series
|
|
21
|
+
series containing the ATR values for each period
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
df = df.copy()
|
|
25
|
+
df.rename(columns=str.lower, inplace=True)
|
|
26
|
+
|
|
27
|
+
df['H-L']=abs(df['high']-df['low'])
|
|
28
|
+
df['H-PC']=abs(df['high']-df['close'].shift(1))
|
|
29
|
+
df['L-PC']=abs(df['low']-df['close'].shift(1))
|
|
30
|
+
|
|
31
|
+
df['TR']=df[['H-L','H-PC','L-PC']].max(axis=1,skipna=False)
|
|
32
|
+
df['ATR']=df['TR'].rolling(lookback).mean()
|
|
33
|
+
|
|
34
|
+
data = df.drop(['H-L','H-PC','L-PC'],axis=1) # drop columns
|
|
35
|
+
|
|
36
|
+
return data['ATR']
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def BBands(series: pd.Series, lookback: int, multiplier: float = 2) -> pd.Series:
|
|
40
|
+
"""
|
|
41
|
+
Calculate Bollinger Bands for a given DataFrame
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
series : pd.Series
|
|
46
|
+
price series
|
|
47
|
+
lookback : int
|
|
48
|
+
lookback period for the bollinger bands
|
|
49
|
+
multiplier : float, optional
|
|
50
|
+
multiplier for the standard deviation, by default 2
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
pd.Series
|
|
55
|
+
series containing the Bollinger Bands
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
# Calculate rolling mean and standard deviation
|
|
59
|
+
rolling_mean = series.rolling(window=lookback).mean()
|
|
60
|
+
rolling_std = series.rolling(window=lookback).std()
|
|
61
|
+
|
|
62
|
+
# Calculate upper and lower bands
|
|
63
|
+
upper = rolling_mean + (rolling_std * multiplier)
|
|
64
|
+
middle = rolling_mean
|
|
65
|
+
lower = rolling_mean - (rolling_std * multiplier)
|
|
66
|
+
|
|
67
|
+
return lower, middle, upper
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def SMA(series: pd.Series, lookback: int) -> pd.Series:
|
|
71
|
+
"""
|
|
72
|
+
Moving Average
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
series : pd.Series
|
|
77
|
+
time series to calculate the Moving Average for
|
|
78
|
+
lookback : int
|
|
79
|
+
lookback period for the Moving Average
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
pd.Series
|
|
84
|
+
series containing the Moving Average
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
return series.rolling(lookback).mean()
|
|
88
|
+
|
|
89
|
+
def EMA(series: pd.Series, lookback: int) -> pd.Series:
|
|
90
|
+
"""
|
|
91
|
+
Exponential Moving Average
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
series : pd.Series
|
|
96
|
+
time series to calculate the Exponential Moving Average for
|
|
97
|
+
lookback : int
|
|
98
|
+
lookback period for the Exponential Moving Average
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
pd.Series
|
|
103
|
+
series containing the Exponential Moving Average
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
return series.ewm(span=lookback, adjust=False).mean()
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def MACD(series: pd.Series, lookback: int, fast: int, slow: int) -> pd.Series:
|
|
110
|
+
"""
|
|
111
|
+
Moving Average Convergence Divergence
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
series : pd.Series
|
|
116
|
+
time series to calculate the MACD for
|
|
117
|
+
lookback : int
|
|
118
|
+
lookback period for the MACD
|
|
119
|
+
fast : int
|
|
120
|
+
fast period for the MACD
|
|
121
|
+
slow : int
|
|
122
|
+
slow period for the MACD
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
pd.Series
|
|
127
|
+
series containing the MACD
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# Calculate MACD line
|
|
131
|
+
macd = series.ewm(span=fast, adjust=False).mean() - series.ewm(span=slow, adjust=False).mean()
|
|
132
|
+
|
|
133
|
+
# Calculate Signal line from the MACD line
|
|
134
|
+
signal = macd.ewm(span=lookback, adjust=False).mean()
|
|
135
|
+
|
|
136
|
+
return macd, signal
|
|
137
|
+
|
|
138
|
+
def RSI(series: pd.Series, lookback: int) -> pd.Series:
|
|
139
|
+
"""
|
|
140
|
+
Relative Strength Index
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
series : pd.Series
|
|
145
|
+
time series to calculate the RSI for
|
|
146
|
+
lookback : int
|
|
147
|
+
lookback period for the RSI
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
pd.Series
|
|
152
|
+
series containing the RSI
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
# Calculate price changes
|
|
156
|
+
delta = series.diff()
|
|
157
|
+
delta.where(delta > 0, 0)
|
|
158
|
+
# Separate gains and losses
|
|
159
|
+
gain = (delta.where(delta > 0, 0)).rolling(window=lookback).mean()
|
|
160
|
+
loss = (-delta.where(delta < 0, 0)).rolling(window=lookback).mean()
|
|
161
|
+
|
|
162
|
+
# Calculate the Relative Strength (RS)
|
|
163
|
+
rs = gain / loss
|
|
164
|
+
|
|
165
|
+
# Calculate RSI
|
|
166
|
+
return 100 - (100 / (1 + rs))
|
|
167
|
+
|
|
@@ -2,84 +2,94 @@
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import pandas as pd
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
def periodReturn(series: pd.Series, period: str = None) -> pd.DataFrame:
|
|
5
|
+
def periodReturn(data: pd.DataFrame | pd.Series, period: str = None) -> pd.DataFrame | pd.Series:
|
|
7
6
|
"""
|
|
8
7
|
Calculates periodic returns for the specified inputs
|
|
9
8
|
|
|
10
9
|
Parameters
|
|
11
10
|
----------
|
|
12
|
-
|
|
13
|
-
price
|
|
11
|
+
data : pd.DataFrame | pd.Series
|
|
12
|
+
price data
|
|
14
13
|
period : str, optional
|
|
15
14
|
None, defaults to daily frequency
|
|
16
|
-
Sepcifiy W, M, Q and
|
|
17
|
-
|
|
15
|
+
Sepcifiy W, M, Q and Y for weekly, monthly, quarterly and annual frequency
|
|
16
|
+
|
|
18
17
|
Returns
|
|
19
18
|
-------
|
|
20
|
-
pd.DataFrame
|
|
19
|
+
pd.DataFrame | pd.Series
|
|
21
20
|
resampled dataframe series of log returns
|
|
22
21
|
"""
|
|
23
|
-
|
|
22
|
+
|
|
23
|
+
# Check if the input is a Series or DataFrame
|
|
24
|
+
if not isinstance(data, (pd.DataFrame, pd.Series)):
|
|
25
|
+
raise ValueError("Input must be a pandas DataFrame or Series")
|
|
26
|
+
|
|
27
|
+
# Initialize variable to hold log returns
|
|
28
|
+
temp = pd.Series(dtype=float)
|
|
29
|
+
|
|
24
30
|
if period is None:
|
|
25
|
-
temp = np.log(
|
|
31
|
+
temp = np.log(data).diff()
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
temp = np.log(
|
|
33
|
+
elif period == 'W':
|
|
34
|
+
data = data.resample('W').last()
|
|
35
|
+
temp = np.log(data).diff()
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
temp = np.log(
|
|
37
|
+
elif period == 'M':
|
|
38
|
+
data = data.resample('ME').last()
|
|
39
|
+
temp = np.log(data).diff()
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
temp = np.log(
|
|
41
|
+
elif period == 'Q':
|
|
42
|
+
data = data.resample('QE').last()
|
|
43
|
+
temp = np.log(data).diff()
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
temp = np.log(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
elif period == 'A':
|
|
46
|
+
data = data.resample('YE').last()
|
|
47
|
+
temp = np.log(data).diff()
|
|
48
|
+
|
|
49
|
+
elif period == 'all':
|
|
50
|
+
if isinstance(data, pd.Series):
|
|
51
|
+
temp = pd.DataFrame({
|
|
52
|
+
'daily': dailyReturn(data).iloc[-1],
|
|
53
|
+
'weekly': weeklyReturn(data).iloc[-1],
|
|
54
|
+
'monthly': monthlyReturn(data).iloc[-1],
|
|
55
|
+
'quarterly': quarterlyReturn(data).iloc[-1],
|
|
56
|
+
'annual': annualReturn(data).iloc[-1]
|
|
57
|
+
}, index=[data.index[-1]])
|
|
58
|
+
return temp.dropna()
|
|
59
|
+
else:
|
|
60
|
+
raise ValueError("Please pass a Series for period 'all'")
|
|
51
61
|
|
|
52
62
|
return temp.dropna()
|
|
53
63
|
|
|
54
64
|
|
|
55
|
-
def dailyReturn(
|
|
65
|
+
def dailyReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
56
66
|
"""Calculates daily returns for the specified inputs."""
|
|
57
|
-
return periodReturn(
|
|
67
|
+
return periodReturn(data)
|
|
58
68
|
|
|
59
69
|
|
|
60
|
-
def weeklyReturn(
|
|
70
|
+
def weeklyReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
61
71
|
"""Calculates weekly returns for the specified inputs."""
|
|
62
|
-
return periodReturn(
|
|
72
|
+
return periodReturn(data, period='W')
|
|
63
73
|
|
|
64
74
|
|
|
65
|
-
def monthlyReturn(
|
|
75
|
+
def monthlyReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
66
76
|
"""Calculates monthly returns for the specified inputs."""
|
|
67
|
-
return periodReturn(
|
|
77
|
+
return periodReturn(data, period='M')
|
|
68
78
|
|
|
69
79
|
|
|
70
|
-
def quarterlyReturn(
|
|
80
|
+
def quarterlyReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
71
81
|
"""Calculates quarterly returns for the specified inputs."""
|
|
72
|
-
return periodReturn(
|
|
82
|
+
return periodReturn(data, period='Q')
|
|
73
83
|
|
|
74
84
|
|
|
75
|
-
def annualReturn(
|
|
85
|
+
def annualReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
76
86
|
"""Calculates annual returns for the specified inputs."""
|
|
77
|
-
return periodReturn(
|
|
87
|
+
return periodReturn(data, period='A')
|
|
78
88
|
|
|
79
89
|
|
|
80
|
-
def allReturn(
|
|
90
|
+
def allReturn(data: pd.DataFrame | pd.Series) -> pd.DataFrame | pd.Series:
|
|
81
91
|
"""Calculates annual returns for the specified inputs."""
|
|
82
|
-
return periodReturn(
|
|
92
|
+
return periodReturn(data, period='all')
|
|
83
93
|
|
|
84
94
|
|
|
85
95
|
def cagr(returns: pd.Series, intra_period: int = 1, is_log: bool = False) -> float:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.0.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: quantmod
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Quantmod Python Package
|
|
5
5
|
Home-page: https://kannansingaravelu.com/
|
|
6
6
|
Author: Kannan Singaravelu
|
|
@@ -10,7 +10,6 @@ Keywords: python,quant,quantmod,quantmod-python
|
|
|
10
10
|
Platform: any
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Operating System :: OS Independent
|
|
16
15
|
Classifier: Intended Audience :: Developers
|
|
@@ -18,7 +17,7 @@ Classifier: Topic :: Office/Business :: Financial
|
|
|
18
17
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
19
18
|
Classifier: Topic :: Software Development :: Libraries
|
|
20
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.10
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
23
22
|
License-File: LICENSE.txt
|
|
24
23
|
Requires-Dist: numpy>=2.0.2
|
|
@@ -6,6 +6,7 @@ quantmod/__init__.py
|
|
|
6
6
|
quantmod/_version.py
|
|
7
7
|
quantmod/main.py
|
|
8
8
|
quantmod/utils.py
|
|
9
|
+
quantmod/version.py
|
|
9
10
|
quantmod.egg-info/PKG-INFO
|
|
10
11
|
quantmod.egg-info/SOURCES.txt
|
|
11
12
|
quantmod.egg-info/dependency_links.txt
|
|
@@ -15,6 +16,7 @@ quantmod.egg-info/requires.txt
|
|
|
15
16
|
quantmod.egg-info/top_level.txt
|
|
16
17
|
quantmod/datasets/__init__.py
|
|
17
18
|
quantmod/datasets/dataloader.py
|
|
19
|
+
quantmod/datasets/data/__init__.py
|
|
18
20
|
quantmod/derivatives/__init__.py
|
|
19
21
|
quantmod/derivatives/options.py
|
|
20
22
|
quantmod/indicators/__init__.py
|
|
@@ -11,9 +11,16 @@ README = (HERE / "README.md").read_text(encoding="utf-8")
|
|
|
11
11
|
with open('requirements.txt', 'r', encoding="utf-8") as f:
|
|
12
12
|
requirements = f.read().splitlines()
|
|
13
13
|
|
|
14
|
+
# --- get version ---
|
|
15
|
+
version = "unknown"
|
|
16
|
+
with open("quantmod/version.py") as f:
|
|
17
|
+
line = f.read().strip()
|
|
18
|
+
version = line.replace("version = ", "").replace('"', '')
|
|
19
|
+
# --- /get version ---
|
|
20
|
+
|
|
14
21
|
setup(
|
|
15
22
|
name="quantmod",
|
|
16
|
-
version=
|
|
23
|
+
version=version,
|
|
17
24
|
# version=versioneer.get_version(),
|
|
18
25
|
# cmdclass=versioneer.get_cmdclass(),
|
|
19
26
|
description="Quantmod Python Package",
|
|
@@ -29,7 +36,6 @@ setup(
|
|
|
29
36
|
classifiers=[
|
|
30
37
|
"License :: OSI Approved :: Apache Software License",
|
|
31
38
|
"Programming Language :: Python :: 3",
|
|
32
|
-
"Programming Language :: Python :: 3.9",
|
|
33
39
|
"Programming Language :: Python :: 3.10",
|
|
34
40
|
"Operating System :: OS Independent",
|
|
35
41
|
"Intended Audience :: Developers",
|
|
@@ -39,7 +45,7 @@ setup(
|
|
|
39
45
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
40
46
|
],
|
|
41
47
|
platforms=['any'],
|
|
42
|
-
python_requires=">=3.
|
|
48
|
+
python_requires=">=3.10",
|
|
43
49
|
zip_safe=False,
|
|
44
50
|
entry_points={
|
|
45
51
|
'console_scripts': [
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import pandas as pd
|
|
2
|
-
|
|
3
|
-
def ATR(df: pd.DataFrame, lookback: int = 14) -> pd.Series:
|
|
4
|
-
"""
|
|
5
|
-
Calculate the Average True Range (ATR).
|
|
6
|
-
|
|
7
|
-
ATR is a volatility indicator that measures the average of the true range values
|
|
8
|
-
over a specified period. An expanding ATR indicates increased volatility, while
|
|
9
|
-
a low ATR value indicates a series of periods with small price ranges.
|
|
10
|
-
|
|
11
|
-
Parameters
|
|
12
|
-
----------
|
|
13
|
-
df : pd.DataFrame
|
|
14
|
-
DataFrame with OHLC (Open, High, Low, Close) price data.
|
|
15
|
-
lookback : int, optional
|
|
16
|
-
Number of periods to use for ATR calculation, by default 14.
|
|
17
|
-
|
|
18
|
-
Returns
|
|
19
|
-
-------
|
|
20
|
-
pd.Series
|
|
21
|
-
A pandas Series containing the ATR values for each period.
|
|
22
|
-
|
|
23
|
-
Examples
|
|
24
|
-
--------
|
|
25
|
-
>>> import pandas as pd
|
|
26
|
-
>>> df = pd.DataFrame({
|
|
27
|
-
... 'Open': [10, 11, 12],
|
|
28
|
-
... 'High': [12, 13, 14],
|
|
29
|
-
... 'Low': [9, 10, 11],
|
|
30
|
-
... 'Close': [11, 12, 13]
|
|
31
|
-
... })
|
|
32
|
-
>>> atr = ATR(df, lookback=2)
|
|
33
|
-
>>> print(atr)
|
|
34
|
-
0 NaN
|
|
35
|
-
1 3.000000
|
|
36
|
-
2 2.750000
|
|
37
|
-
dtype: float64
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
df = df.copy()
|
|
41
|
-
|
|
42
|
-
df['H-L']=abs(df['High']-df['Low'])
|
|
43
|
-
df['H-PC']=abs(df['High']-df['Close'].shift(1))
|
|
44
|
-
df['L-PC']=abs(df['Low']-df['Close'].shift(1))
|
|
45
|
-
|
|
46
|
-
df['TR']=df[['H-L','H-PC','L-PC']].max(axis=1,skipna=False)
|
|
47
|
-
df['ATR']=df['TR'].rolling(lookback).mean()
|
|
48
|
-
|
|
49
|
-
data = df.drop(['H-L','H-PC','L-PC'],axis=1) # drop columns
|
|
50
|
-
|
|
51
|
-
return data['ATR']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|