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.
@@ -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