yf_as_dataframe 0.2.15
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.
- checksums.yaml +7 -0
- data/.rubocop.yml +13 -0
- data/CHANGELOG.rst +0 -0
- data/CODE_OF_CONDUCT.md +15 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +299 -0
- data/Rakefile +8 -0
- data/chart.png +0 -0
- data/lib/yf_as_dataframe/analysis.rb +68 -0
- data/lib/yf_as_dataframe/financials.rb +304 -0
- data/lib/yf_as_dataframe/fundamentals.rb +53 -0
- data/lib/yf_as_dataframe/holders.rb +253 -0
- data/lib/yf_as_dataframe/multi.rb +238 -0
- data/lib/yf_as_dataframe/price_history.rb +2045 -0
- data/lib/yf_as_dataframe/price_technical.rb +579 -0
- data/lib/yf_as_dataframe/quote.rb +343 -0
- data/lib/yf_as_dataframe/ticker.rb +380 -0
- data/lib/yf_as_dataframe/tickers.rb +50 -0
- data/lib/yf_as_dataframe/utils.rb +354 -0
- data/lib/yf_as_dataframe/version.rb +3 -0
- data/lib/yf_as_dataframe/yf_connection.rb +304 -0
- data/lib/yf_as_dataframe/yfinance_exception.rb +15 -0
- data/lib/yf_as_dataframe.rb +24 -0
- metadata +139 -0
@@ -0,0 +1,579 @@
|
|
1
|
+
require 'tulirb'
|
2
|
+
|
3
|
+
class YfAsDataframe
|
4
|
+
module PriceTechnical
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include ActionView::Helpers::NumberHelper
|
7
|
+
|
8
|
+
|
9
|
+
def ad(df)
|
10
|
+
inputs = ['High', 'Low','Adj Close','Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
11
|
+
output = Tulirb.ad(inputs).first
|
12
|
+
Polars::Series.new("Accum-Distrib Ln", [nil]*(df.rows.length - output.length)+output)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def adosc(df, short_window: 2, long_window: 5)
|
17
|
+
inputs = ['High', 'Low','Adj Close','Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
18
|
+
output = Tulirb.adosc(inputs, short_period: short_window, long_period: long_window).first
|
19
|
+
Polars::Series.new("#{short_window}/#{long_window} Accum-Distrib Osc", [nil]*(df.rows.length - output.length)+output)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def adx(df, column: 'Adj Close', window: 5)
|
24
|
+
input = Polars::Series.new(df[column]).to_a
|
25
|
+
output = Tulirb.adx([input], period: window).first
|
26
|
+
Polars::Series.new("#{window}-day Avg Dir Movemt Idx for #{column}", [nil]*(df.rows.length - output.length)+output)
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :avg_dir_index, :adx
|
30
|
+
|
31
|
+
def adxr(df, column: 'Adj Close', window: 5)
|
32
|
+
input = Polars::Series.new(df[column]).to_a
|
33
|
+
output = Tulirb.adxr([input], period: window).first
|
34
|
+
Polars::Series.new("#{window}-day Avg Dir Movemt Rating for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :avg_dir_movement_rating, :adxr
|
38
|
+
|
39
|
+
|
40
|
+
def avg_daily_trading_volume(df, window: 20)
|
41
|
+
df.insert_at_idx(0, Polars::Series.new('idx', (1..df.length).to_a))
|
42
|
+
df = df.set_sorted('idx', descending: false)
|
43
|
+
|
44
|
+
adtv = df.group_by_rolling(index_column: 'idx', period: "#{window}i").
|
45
|
+
agg([Polars.mean('Volume').alias("ADTV(#{window})")]).to_series(1)
|
46
|
+
df = df.drop('idx')
|
47
|
+
adtv
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def ao(df)
|
52
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
53
|
+
output = Tulirb.ao(inputs).first
|
54
|
+
Polars::Series.new("Accum-Distrib Ln", [nil]*(df.rows.length - output.length)+output) #)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def apo(df, column: 'Adj Close', short_window: 12, long_window: 29)
|
59
|
+
input = Polars::Series.new(df[column]).to_a
|
60
|
+
output = Tulirb.ao([input], short_period: short_window, long_period: long_window).first
|
61
|
+
Polars::Series.new("#{short_window}/#{long_window} Abs Price Osc for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def aroon(df, window: 20)
|
66
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
67
|
+
output = Tulirb.aroon(inputs, period: window).first
|
68
|
+
Polars::Series.new("#{window} Aroon Ind", [nil]*(df.rows.length - output.length)+output) #)
|
69
|
+
end
|
70
|
+
|
71
|
+
def aroonosc(df, window: 20)
|
72
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
73
|
+
output = Tulirb.aroonosc(inputs, period: window).first
|
74
|
+
Polars::Series.new("#{window} Aroon Osc Ind", [nil]*(df.rows.length - output.length)+output) #)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def avg_price(df)
|
79
|
+
inputs = ['Open', 'High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
80
|
+
output = Tulirb.avgprice(inputs).first
|
81
|
+
Polars::Series.new("Avg Price", [nil]*(df.rows.length - output.length)+output) #)
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :avgprice, :avg_price
|
85
|
+
|
86
|
+
def atr(df, window: 20)
|
87
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
88
|
+
output = Tulirb.atr(inputs, period: window).first
|
89
|
+
Polars::Series.new("#{window}-day Avg True Range", [nil]*(df.rows.length - output.length)+output)#)
|
90
|
+
end
|
91
|
+
|
92
|
+
alias_method :avg_true_range, :atr
|
93
|
+
|
94
|
+
def bbands(df, column: 'Adj Close', window: 20, stddev: 1 )
|
95
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
96
|
+
output = Tulirb.bbands(inputs, period: window, stddev: stddev).first
|
97
|
+
Polars::Series.new("#{window}-day Boll Band for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def bop(df)
|
102
|
+
inputs = ['Open', 'High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
103
|
+
output = Tulirb.bop(inputs).first
|
104
|
+
Polars::Series.new("Bal of Power", [nil]*(df.rows.length - output.length)+output) #)
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def cci(df, window: 20)
|
109
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
110
|
+
output = Tulirb.cci(inputs, period: window).first
|
111
|
+
Polars::Series.new("#{window}-day Comm Channel Idx", [nil]*(df.rows.length - output.length)+output) #)
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def cmo(df, column: 'Adj Close', window: 20)
|
116
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
117
|
+
output = Tulirb.cmo(inputs, period: window).first
|
118
|
+
Polars::Series.new("#{window}-day Chande Mom Osc for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def cvi(df, window: 20)
|
123
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
124
|
+
output = Tulirb.cvi(inputs, period: window).first
|
125
|
+
Polars::Series.new("#{window}-day Chaikins Volatility", [nil]*(df.rows.length - output.length)+output) #)
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def dema(df, column: 'Adj Close', window: 20)
|
130
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
131
|
+
output = Tulirb.dema(inputs, period: window).first
|
132
|
+
Polars::Series.new("Dbl EMA(#{window})", [nil]*(df.rows.length - output.length)+output) #)
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
def di(df, window: 20)
|
137
|
+
inputs = ['High','Low','Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
138
|
+
output = Tulirb.di(inputs, period: window).first
|
139
|
+
Polars::Series.new("#{window}-day Dir Idx", [nil]*(df.rows.length - output.length)+output) #)
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def dm(df, window: 20)
|
144
|
+
inputs = ['High','Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
145
|
+
output = Tulirb.dm(inputs, period: window).first
|
146
|
+
Polars::Series.new("#{window}-day Dir Movemt", [nil]*(df.rows.length - output.length)+output) #)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def dpo(df, column: 'Adj Close', window: 20)
|
151
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
152
|
+
output = Tulirb.dpo(inputs, period: window).first
|
153
|
+
Polars::Series.new("#{window}-day Detrend Price Osc of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
def dx(df, window: 20)
|
158
|
+
inputs = ['High','Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
159
|
+
output = Tulirb.dx(inputs, period: window).first
|
160
|
+
Polars::Series.new("#{window}-day Dir Movemt Idx", [nil]*(df.rows.length - output.length)+output) #)
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
def ema(df, column: 'Adj Close', window: 5)
|
165
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
166
|
+
output = Tulirb.ema(inputs, period: window).first
|
167
|
+
Polars::Series.new("EMA(#{window}) for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
def emv(df)
|
172
|
+
inputs = ['High', 'Low', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
173
|
+
output = Tulirb.emv(inputs).first
|
174
|
+
Polars::Series.new("Ease of Mvmt", [nil]*(df.rows.length - output.length)+output) #)
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def fisher(df, window: 20)
|
179
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
180
|
+
output = Tulirb.fisher(inputs, period: window).first
|
181
|
+
Polars::Series.new("#{window}-day Fisher Xform", [nil]*(df.rows.length - output.length)+output) #)
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
def fosc(df, window: 20)
|
186
|
+
inputs = ['Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
187
|
+
output = Tulirb.fosc(inputs, period: window).first
|
188
|
+
Polars::Series.new("Fcast Osc", [nil]*(df.rows.length - output.length)+output) #)
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
def hma(df, column: 'Adj Close', window: 5)
|
193
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
194
|
+
output = Tulirb.ema(inputs, period: window).first
|
195
|
+
Polars::Series.new("EMA(#{window}) for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
def kama(df, column: 'Adj Close', window: 5)
|
200
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
201
|
+
output = Tulirb.kama(inputs, period: window).first
|
202
|
+
Polars::Series.new("KAMA(#{window}) for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
def kvo(df, short_window: 5, long_window: 20)
|
207
|
+
inputs = ['High', 'Low', 'Adj Close', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
208
|
+
output = Tulirb.kvo(inputs, short_period: short_window, long_period: long_window).first
|
209
|
+
Polars::Series.new("#{short_window}/#{long_window} Klinger Vol Osc", [nil]*(df.rows.length - output.length)+output) #)
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
def linreg(df, column: 'Adj Close', window: 20)
|
214
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
215
|
+
output = Tulirb.linreg(inputs, period: window).first
|
216
|
+
Polars::Series.new("#{window}-day Lin Reg Est for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
def linregintercept(df, column: 'Adj Close', window: 20)
|
221
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
222
|
+
output = Tulirb.linregintercept(inputs, period: window).first
|
223
|
+
Polars::Series.new("#{window}-day Lin Reg Int for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
def linregslope(df, column: 'Adj Close', window: 20)
|
228
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
229
|
+
output = Tulirb.linregslope(inputs, period: window).first
|
230
|
+
Polars::Series.new("#{window}-day Lin Reg Slope for #{column}", [nil]*(df.rows.length - output.length)+output)
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
def macd(df, column: 'Adj Close', short_window: 12, long_window: 26, signal_window: 9)
|
235
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
236
|
+
output = Tulirb.macd(inputs, short_period: short_window, long_period: long_window, signal_period: signal_window).first
|
237
|
+
Polars::Series.new("#{short_window}/#{long_window}/#{signal_window} MACD for #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def marketfi(df)
|
242
|
+
inputs = ['High', 'Low', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
243
|
+
output = Tulirb.marketfi(inputs).first
|
244
|
+
Polars::Series.new("Mkt Facilitation Idx", [nil]*(df.rows.length - output.length)+output) #)
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
def mass(df, window: 20)
|
249
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
250
|
+
output = Tulirb.mass(inputs, period: window).first
|
251
|
+
Polars::Series.new("#{window}-day Mass Idx", [nil]*(df.rows.length - output.length)+output) #)
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
def max(df, column: 'Adj Close', window: 20)
|
256
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
257
|
+
output = Tulirb.max(inputs, period: window).first
|
258
|
+
Polars::Series.new("Max of #{column} in #{window}-day pd", [nil]*(df.rows.length - output.length)+output) #)
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
def md(df, column: 'Adj Close', window: 20)
|
263
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
264
|
+
output = Tulirb.md(inputs, period: window).first
|
265
|
+
Polars::Series.new("Mean Dev of #{column} in #{window}-day pd", [nil]*(df.rows.length - output.length)+output) #)
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
def median_price(df)
|
270
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
271
|
+
output = Tulirb.medprice(inputs).first
|
272
|
+
Polars::Series.new("Med Price", [nil]*(df.rows.length - output.length)+output) #)
|
273
|
+
end
|
274
|
+
|
275
|
+
alias_method :medprice, :median_price
|
276
|
+
|
277
|
+
def mfi(df, window: 20)
|
278
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
279
|
+
output = Tulirb.mfi(inputs, period: window).first
|
280
|
+
Polars::Series.new("#{window}-day Money Flow Idx", [nil]*(df.rows.length - output.length)+output) #)
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
def min(df, column: 'Adj Close', window: 20)
|
285
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
286
|
+
output = Tulirb.min(inputs, period: window).first
|
287
|
+
Polars::Series.new("Min of #{column} in #{window}-day pd", [nil]*(df.rows.length - output.length)+output) #)
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
def mom(df, column: 'Adj Close', window: 5)
|
292
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
293
|
+
output = Tulirb.mom(inputs, period: window).first
|
294
|
+
Polars::Series.new("#{window}-day Momentum of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
295
|
+
end
|
296
|
+
|
297
|
+
alias_method :momentum, :mom
|
298
|
+
|
299
|
+
def moving_avgs(df, window: 20)
|
300
|
+
df.insert_at_idx(0, Polars::Series.new('idx', (1..df.length).to_a))
|
301
|
+
df = df.set_sorted('idx', descending: false)
|
302
|
+
s = df.group_by_rolling(index_column: 'idx', period: "#{window}i").agg([Polars.mean('Adj Close').alias("MA(#{window})")]).to_series(1) #)
|
303
|
+
df = df.drop('idx')
|
304
|
+
s
|
305
|
+
end
|
306
|
+
|
307
|
+
def natr(df, window: 20)
|
308
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
309
|
+
output = Tulirb.natr(inputs, period: window).firs
|
310
|
+
Polars::Series.new("#{window}-day Norm Avg True Range", [nil]*(df.rows.length - output.length)+output) #)
|
311
|
+
end
|
312
|
+
|
313
|
+
alias_method :normalized_avg_true_range, :natr
|
314
|
+
|
315
|
+
|
316
|
+
# def norm_momentum(period: '1y')
|
317
|
+
# df = history(period: period, interval: "1d")
|
318
|
+
# dat = df['Adj Close'].to_a
|
319
|
+
# mn = dat.sum.to_f / dat.count.to_f
|
320
|
+
# std = dat.map{|d| (d-mn)}.sum.to_f/dat.count.to_f
|
321
|
+
# all_times = df['Timestamps'].to_a
|
322
|
+
# min_time = all_times.min
|
323
|
+
|
324
|
+
# WINDOWS.each_with_index do |n, ndex|
|
325
|
+
# s = [nil] * all_times.length
|
326
|
+
# dat.length.times do |t_ndex|
|
327
|
+
# next if t_ndex < n
|
328
|
+
# later_row = df[t_ndex]
|
329
|
+
# earlier_row = df[t_ndex - n]
|
330
|
+
# s[t_ndex] = (later_row['Adj Close'][0]) - (earlier_row['Adj Close'][0])/std
|
331
|
+
# end
|
332
|
+
# next if s.all?(&:nil?)
|
333
|
+
# s = Polars::Series.new("#{n}-day Price Chg", s)
|
334
|
+
# df.insert_at_idx(df.columns.length, s)
|
335
|
+
# end
|
336
|
+
|
337
|
+
# min_win = WINDOWS.min
|
338
|
+
# df.drop_nulls(subset: ["#{min_win}-day Price Chg"])
|
339
|
+
# end
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
def nvi(df)
|
344
|
+
inputs = ['Adj Close', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
345
|
+
output = Tulirb.nvi(inputs).first
|
346
|
+
Polars::Series.new("Neg Vol Idx", [nil]*(df.rows.length - output.length)+output) #)
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
def obv(df)
|
351
|
+
inputs = ['Adj Close', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
352
|
+
output = Tulirb.obv(inputs).first
|
353
|
+
Polars::Series.new("On Bal Vol", [nil]*(df.rows.length - output.length)+output) #)
|
354
|
+
end
|
355
|
+
|
356
|
+
|
357
|
+
def ppo(df, column: 'Adj Close', short_window: 12, long_window: 26)
|
358
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
359
|
+
output = Tulirb.ppo(inputs, short_period: short_window, long_period: long_window).first
|
360
|
+
Polars::Series.new("#{short_window}/#{long_window} Pctage Price Osc of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
361
|
+
end
|
362
|
+
|
363
|
+
|
364
|
+
def psar(df, acceleration_factor_step: 0.2, acceleration_factor_maximum: 2)
|
365
|
+
inputs = ['High', 'Low'].map{|col| Polars::Series.new(df[col]).to_a}
|
366
|
+
output = Tulirb.psar(inputs, acceleration_factor_step, acceleration_factor_maximum).first
|
367
|
+
Polars::Series.new("Parabolic SAR w step #{acceleration_factor_step} and max #{acceleration_factor_maximum}", [nil]*(df.rows.length - output.length)+output) #)
|
368
|
+
end
|
369
|
+
|
370
|
+
|
371
|
+
def pvi(df)
|
372
|
+
inputs = ['Adj Close', 'Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
373
|
+
output = Tulirb.pvi(inputs).first
|
374
|
+
Polars::Series.new("Pos Vol Idx", [nil]*(df.rows.length - output.length)+output) #)
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
def qstick(df, window: 20)
|
379
|
+
inputs = ['Open', 'Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
380
|
+
output = Tulirb.qstick(inputs, period: window).first
|
381
|
+
Polars::Series.new("#{window}-day Qstick", [nil]*(df.rows.length - output.length)+output) #)
|
382
|
+
end
|
383
|
+
|
384
|
+
|
385
|
+
def roc(df, column: 'Adj Close', window: 20)
|
386
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
387
|
+
output = Tulirb.roc(inputs, period: window).first
|
388
|
+
Polars::Series.new("Rate of Chg of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
389
|
+
end
|
390
|
+
|
391
|
+
|
392
|
+
def rocr(df, column: 'Adj Close', window: 20)
|
393
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
394
|
+
output = Tulirb.rocr(inputs, period: window).first
|
395
|
+
Polars::Series.new("Rate of Chg Ratio of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
396
|
+
end
|
397
|
+
|
398
|
+
def rsi(df, window: 20)
|
399
|
+
return nil if w == 1
|
400
|
+
inputs = ['Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
401
|
+
output = Tulirb.rsi(inputs, period: window).first
|
402
|
+
Polars::Series.new("#{window}-day RSI", [nil]*(df.rows.length - output.length)+output) #)
|
403
|
+
end
|
404
|
+
|
405
|
+
def sma(df, column: 'Adj Close', window: 20)
|
406
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
407
|
+
output = Tulirb.sma(inputs, period: window).first
|
408
|
+
Polars::Series.new("SMA(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
409
|
+
end
|
410
|
+
|
411
|
+
|
412
|
+
def stddev(df, column: 'Adj Close', window: 20)
|
413
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
414
|
+
output = Tulirb.stddev(inputs, period: window).first
|
415
|
+
Polars::Series.new("Rolling Stdev(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
416
|
+
end
|
417
|
+
|
418
|
+
|
419
|
+
def stderr(df, column: 'Adj Close', window: 20)
|
420
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
421
|
+
output = Tulirb.stderr(inputs, period: window).first
|
422
|
+
Polars::Series.new("Rolling Stderr(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
423
|
+
end
|
424
|
+
|
425
|
+
|
426
|
+
def stochrsi(df, column: 'Adj Close', window: 20)
|
427
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
428
|
+
output = Tulirb.stochrsi(inputs, period: window).first
|
429
|
+
Polars::Series.new("Stochastic RSI(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
430
|
+
end
|
431
|
+
|
432
|
+
|
433
|
+
def sum(df, column: 'Adj Close', window: 20)
|
434
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
435
|
+
output = Tulirb.sum(inputs, period: window).first
|
436
|
+
Polars::Series.new("Rolling #{window}-day Sum of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
437
|
+
end
|
438
|
+
|
439
|
+
def tema(df, column: 'Adj Close', window: 20)
|
440
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
441
|
+
output = Tulirb.tema(inputs, period: window).first
|
442
|
+
Polars::Series.new("TEMA(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
443
|
+
end
|
444
|
+
|
445
|
+
|
446
|
+
def tr(df, column: 'Adj Close')
|
447
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
448
|
+
output = Tulirb.tr(inputs).first
|
449
|
+
Polars::Series.new("True Range of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
450
|
+
end
|
451
|
+
|
452
|
+
alias_method :true_range, :tr
|
453
|
+
|
454
|
+
def trima(df, column: 'Adj Close', window: 20)
|
455
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
456
|
+
output = Tulirb.trima(inputs, period: window).first
|
457
|
+
Polars::Series.new("Triang MA(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
458
|
+
end
|
459
|
+
|
460
|
+
|
461
|
+
def trix(df, column: 'Adj Close', window: 20)
|
462
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
463
|
+
output = Tulirb.trix(inputs, period: window).first
|
464
|
+
Polars::Series.new("Trix(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
465
|
+
end
|
466
|
+
|
467
|
+
|
468
|
+
def tsf(df, column: 'Adj Close', window: 20)
|
469
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
470
|
+
output = Tulirb.tsf(inputs, period: window).first
|
471
|
+
Polars::Series.new("Time-series Fcast(#{window}) of #{window}", [nil]*(df.rows.length - output.length)+output) #)
|
472
|
+
end
|
473
|
+
|
474
|
+
|
475
|
+
def typical_price(df)
|
476
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
477
|
+
output = Tulirb.typprice(inputs).first
|
478
|
+
Polars::Series.new("Typical Price", [nil]*(df.rows.length - output.length)+output) #)
|
479
|
+
end
|
480
|
+
|
481
|
+
alias_method :typprice, :typical_price
|
482
|
+
|
483
|
+
def ultosc(df, short_window: 5, medium_window: 12, long_window: 26)
|
484
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
485
|
+
output = Tulirb.ultosc(inputs, short_period: short_window, medium_period: medium_window, long_period: long_window).first
|
486
|
+
Polars::Series.new("Ult Osc(#{short_window}, #{medium_window}, #{long_window})", [nil]*(df.rows.length - output.length)+output) #)
|
487
|
+
end
|
488
|
+
|
489
|
+
def weighted_close_price(df)
|
490
|
+
inputs = ['High', 'Low', 'Adj Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
491
|
+
output = Tulirb.wcprice(inputs).first
|
492
|
+
Polars::Series.new("Wtd Close Price", [nil]*(df.rows.length - output.length)+output) #)
|
493
|
+
end
|
494
|
+
|
495
|
+
|
496
|
+
def var(df, column: 'Adj Close', window: 20)
|
497
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
498
|
+
output = Tulirb.var(inputs, period: window).first
|
499
|
+
Polars::Series.new("Var over Per(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
500
|
+
end
|
501
|
+
|
502
|
+
|
503
|
+
def vhf(df, column: 'Adj Close', window: 20)
|
504
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
505
|
+
output = Tulirb.vhf(inputs, period: window).first
|
506
|
+
Polars::Series.new("VHF(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
507
|
+
end
|
508
|
+
|
509
|
+
|
510
|
+
def vidya(df, column: 'Adj Close', short_window: 5, long_window: 20, alpha: 0.2)
|
511
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
512
|
+
output = Tulirb.vidya(inputs, short_period: short_window, long_period: long_window, alpha: alpha).first
|
513
|
+
Polars::Series.new("vidya(#{short_window},#{long_window},#{alpha}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
514
|
+
end
|
515
|
+
|
516
|
+
|
517
|
+
def volatility(df, column: 'Adj Close', window: 20)
|
518
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
519
|
+
output = Tulirb.volatility(inputs, period: window).first
|
520
|
+
Polars::Series.new("#{window}-day Volatility of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
521
|
+
end
|
522
|
+
|
523
|
+
|
524
|
+
def vosc(df, column: 'Adj Close', short_window: 5, long_window: 20)
|
525
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
526
|
+
output = Tulirb.vosc(inputs, short_period: short_window, long_period: long_window).first
|
527
|
+
Polars::Series.new("#{short_window}/#{long_window} Vol Osc of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
528
|
+
end
|
529
|
+
|
530
|
+
def vol_weighted_moving_avg(df, window: 20)
|
531
|
+
inputs = ['Adj Close','Volume'].map{|col| Polars::Series.new(df[col]).to_a}
|
532
|
+
output = Tulirb.vwma(inputs, period: window).first
|
533
|
+
Polars::Series.new("VWMA(#{window})", [nil]*(df.rows.length - output.length)+output) #)
|
534
|
+
end
|
535
|
+
|
536
|
+
alias_method :vwma, :vol_weighted_moving_avg
|
537
|
+
|
538
|
+
def wad(df)
|
539
|
+
inputs = ['High','Low','Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
540
|
+
output = Tulirb.wad(inputs, period: window).first
|
541
|
+
Polars::Series.new("Wms Accum/Distrib", [nil]*(df.rows.length - output.length)+output) #)
|
542
|
+
end
|
543
|
+
|
544
|
+
|
545
|
+
def wcprice(df)
|
546
|
+
inputs = ['High','Low','Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
547
|
+
output = Tulirb.stderr(inputs).first
|
548
|
+
Polars::Series.new("Wtd Close Price", [nil]*(df.rows.length - output.length)+output) #)
|
549
|
+
end
|
550
|
+
|
551
|
+
|
552
|
+
def wilders(df, column: 'Adj Close', window: 20)
|
553
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
554
|
+
output = Tulirb.wilders(inputs, period: window).first
|
555
|
+
Polars::Series.new("#{window}-day Wilders Smoothing of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
556
|
+
end
|
557
|
+
|
558
|
+
|
559
|
+
def willr(df, window: 20)
|
560
|
+
inputs = ['High','Low','Close'].map{|col| Polars::Series.new(df[col]).to_a}
|
561
|
+
output = Tulirb.willr(inputs, period: window).first
|
562
|
+
Polars::Series.new("#{window}-day Williams %R Ind", [nil]*(df.rows.length - output.length)+output) #)
|
563
|
+
end
|
564
|
+
|
565
|
+
|
566
|
+
def wma(df, column: 'Adj Close', window: 5)
|
567
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
568
|
+
output = Tulirb.wma(inputs, period: window).first
|
569
|
+
Polars::Series.new("WMA(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
570
|
+
end
|
571
|
+
|
572
|
+
|
573
|
+
def zlema(df, column: 'Adj Close', window: 5)
|
574
|
+
inputs = [column].map{|col| Polars::Series.new(df[col]).to_a}
|
575
|
+
output = Tulirb.zlema(inputs, period: window).first
|
576
|
+
Polars::Series.new("ZLEMA(#{window}) of #{column}", [nil]*(df.rows.length - output.length)+output) #)
|
577
|
+
end
|
578
|
+
end
|
579
|
+
end
|