66from fmp_py .fmp_historical_data import FmpHistoricalData
77from ta .trend import SMAIndicator , EMAIndicator , WMAIndicator , ADXIndicator
88from ta .momentum import RSIIndicator
9- from ta .volume import VolumeWeightedAveragePrice , MFIIndicator , AccDistIndexIndicator
9+ from ta .volume import (
10+ VolumeWeightedAveragePrice ,
11+ MFIIndicator ,
12+ AccDistIndexIndicator ,
13+ OnBalanceVolumeIndicator ,
14+ ChaikinMoneyFlowIndicator ,
15+ ForceIndexIndicator ,
16+ EaseOfMovementIndicator ,
17+ VolumePriceTrendIndicator ,
18+ NegativeVolumeIndexIndicator ,
19+ )
1020from ta .volatility import AverageTrueRange , BollingerBands
1121
1222load_dotenv ()
1323
1424
15- class FmpCharts (FmpBase ):
25+ class FmpChartData (FmpBase ):
1626 def __init__ (
1727 self ,
1828 symbol : str ,
@@ -30,6 +40,234 @@ def __init__(
3040 ########################### VOLUME INDICATORS ############################
3141 ##########################################################################
3242
43+ ####################################
44+ # Negative Volume Index Indicator
45+ ####################################
46+ def nvi (self ) -> None :
47+ """
48+ Calculates the Negative Volume Index (NVI) for the chart data.
49+
50+ The Negative Volume Index (NVI) is a technical indicator that uses volume to predict
51+ changes in stock prices. It is calculated by summing the percentage changes in price
52+ on days with declining volume and subtracting the sum of the percentage changes on
53+ days with increasing volume.
54+
55+ This method modifies the `chart` attribute of the object by adding a new column
56+ called "nvi" that contains the NVI values.
57+
58+ Returns:
59+ None
60+
61+ Example:
62+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
63+ >>> fmp.nvi()
64+ >>> print(fmp.return_chart())
65+ """
66+ chart = self .chart .copy ()
67+ chart ["nvi" ] = (
68+ NegativeVolumeIndexIndicator (
69+ close = chart ["close" ], volume = chart ["volume" ], fillna = True
70+ )
71+ .negative_volume_index ()
72+ .round (2 )
73+ .astype (float )
74+ )
75+ self .chart = chart
76+
77+ ####################################
78+ # Volume Price Trend Indicator
79+ ####################################
80+ def vpt (self ) -> None :
81+ """
82+ Calculates the Volume Price Trend (VPT) indicator for the chart data.
83+
84+ The Volume Price Trend (VPT) indicator measures the strength of a price trend by
85+ analyzing the relationship between volume and price. It is used to identify
86+ potential reversals or confirm the strength of a trend.
87+
88+ This method modifies the `chart` attribute of the object by adding a new column
89+ called "vpt" that contains the calculated VPT values.
90+
91+ Returns:
92+ None
93+
94+ Example:
95+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
96+ >>> fmp.vpt()
97+ >>> print(fmp.return_chart())
98+ """
99+ chart = self .chart .copy ()
100+ chart ["vpt" ] = (
101+ VolumePriceTrendIndicator (
102+ close = chart ["close" ],
103+ volume = chart ["volume" ],
104+ fillna = True ,
105+ ).volume_price_trend ()
106+ ).astype (int )
107+ self .chart = chart
108+
109+ ####################################
110+ # SMA Ease of Movement Indicator
111+ ####################################
112+ def sma_eom (self , period : int = 14 ) -> None :
113+ """
114+ Calculates the Simple Moving Average (SMA) of the Ease of Movement (EOM) indicator.
115+
116+ Args:
117+ period (int): The number of periods to consider for calculating the SMA. Default is 14.
118+
119+ Returns:
120+ None
121+
122+ """
123+ chart = self .chart .copy ()
124+ chart [f"sma_eom{ period } " ] = (
125+ EaseOfMovementIndicator (
126+ high = chart ["high" ],
127+ low = chart ["low" ],
128+ volume = chart ["volume" ],
129+ window = period ,
130+ fillna = True ,
131+ )
132+ .sma_ease_of_movement ()
133+ .round (2 )
134+ .astype (float )
135+ )
136+
137+ self .chart = chart
138+
139+ ##################################
140+ # Ease of Movement Indicator
141+ ##################################
142+ def eom (self , period : int = 14 ) -> None :
143+ """
144+ Calculates the Ease of Movement (EOM) indicator for the given chart data.
145+
146+ Parameters:
147+ period (int): The number of periods to consider for the EOM calculation. Default is 14.
148+
149+ Returns:
150+ None
151+
152+ Notes:
153+ - The EOM indicator measures the relationship between price change and volume.
154+ - It helps identify potential price reversals and divergences.
155+
156+ Example:
157+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
158+ >>> fmp.eom(14)
159+ >>> print(fmp.return_chart())
160+ """
161+ chart = self .chart .copy ()
162+ chart [f"eom{ period } " ] = (
163+ EaseOfMovementIndicator (
164+ high = chart ["high" ],
165+ low = chart ["low" ],
166+ volume = chart ["volume" ],
167+ window = period ,
168+ fillna = True ,
169+ )
170+ .ease_of_movement ()
171+ .round (2 )
172+ .astype (float )
173+ )
174+
175+ self .chart = chart
176+
177+ ##################################
178+ # Force Index Indicator
179+ ##################################
180+ def fi (self , period : int = 13 ) -> None :
181+ """
182+ Calculates and adds the Force Index (FI) to the chart data.
183+
184+ The Force Index is a technical indicator that measures the force behind price movements based on the combination of
185+ price change and trading volume. It helps identify strong trends and potential reversals.
186+
187+ Args:
188+ period (int, optional): The period used to calculate the Force Index. Defaults to 13.
189+
190+ Returns:
191+ None
192+
193+ Example:
194+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
195+ >>> fmp.fi(13)
196+ >>> print(fmp.return_chart())
197+ """
198+ chart = self .chart .copy ()
199+ chart [f"fi{ period } " ] = (
200+ ForceIndexIndicator (
201+ close = chart ["close" ], volume = chart ["volume" ], window = period
202+ )
203+ .force_index ()
204+ .round (2 )
205+ ).astype (float )
206+ self .chart = chart
207+
208+ #################################
209+ # Chaikin Money Flow Indicator
210+ #################################
211+ def cmf (self , period : int = 20 ) -> None :
212+ """
213+ Calculates the Chaikin Money Flow (CMF) indicator for the chart data.
214+
215+ Args:
216+ period (int): The number of periods to consider for the CMF calculation. Default is 20.
217+
218+ Returns:
219+ None. The CMF values are added as a new column 'cmf' to the chart data.
220+
221+ Example:
222+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
223+ >>> fmp.cmf()
224+ >>> print(fmp.return_chart())
225+ """
226+ chart = self .chart .copy ()
227+ chart ["cmf" ] = (
228+ ChaikinMoneyFlowIndicator (
229+ high = chart ["high" ],
230+ low = chart ["low" ],
231+ close = chart ["close" ],
232+ volume = chart ["volume" ],
233+ window = period ,
234+ fillna = True ,
235+ )
236+ .chaikin_money_flow ()
237+ .round (2 )
238+ ).astype (float )
239+
240+ self .chart = chart
241+
242+ #################################
243+ # On Balance Volume Indicator
244+ #################################
245+ def obv (self ) -> None :
246+ """
247+ Calculates the On-Balance Volume (OBV) indicator for the chart data.
248+
249+ The On-Balance Volume (OBV) indicator measures the cumulative buying and selling pressure based on the volume of trades.
250+ It is used to identify the strength of a trend and potential reversals.
251+
252+ Returns:
253+ None
254+
255+ Example:
256+ >>> fmp = FmpCharts(symbol="AAPL", from_date="2021-01-01", to_date="2021-01-10")
257+ >>> fmp.obv()
258+ >>> print(fmp.return_chart())
259+ """
260+ chart = self .chart .copy ()
261+ chart ["obv" ] = (
262+ OnBalanceVolumeIndicator (
263+ close = chart ["close" ],
264+ volume = chart ["volume" ],
265+ fillna = True ,
266+ ).on_balance_volume ()
267+ ).astype (int )
268+
269+ self .chart = chart
270+
33271 #################################
34272 # Accumulated Distribution Index
35273 #################################
@@ -389,7 +627,8 @@ def adx(self, period: int = 14) -> None:
389627 )
390628 .adx_neg ()
391629 .round (2 )
392- ).astype (float )
630+ .astype (float )
631+ )
393632
394633 chart [f"adx{ period } _pos" ] = (
395634 ADXIndicator (
0 commit comments