sqa-tai 0.1.2 → 0.4.0
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 +4 -4
- data/.claude/settings.local.json +33 -0
- data/.envrc +6 -1
- data/.loki +10 -0
- data/.quality/reek_baseline.txt +0 -0
- data/.rubocop.yml +221 -0
- data/CHANGELOG.md +30 -2
- data/Gemfile +0 -8
- data/Gemfile.local +19 -0
- data/README.md +9 -10
- data/Rakefile +163 -7
- data/lib/sqa/tai/cycle_indicators.rb +7 -19
- data/lib/sqa/tai/help/resource.rb +4 -3
- data/lib/sqa/tai/help.rb +16 -11
- data/lib/sqa/tai/momentum_indicators.rb +51 -110
- data/lib/sqa/tai/native.rb +497 -0
- data/lib/sqa/tai/overlap_studies.rb +13 -22
- data/lib/sqa/tai/pattern_recognition.rb +67 -61
- data/lib/sqa/tai/price_transform.rb +10 -4
- data/lib/sqa/tai/statistical_functions.rb +21 -21
- data/lib/sqa/tai/version.rb +1 -1
- data/lib/sqa/tai/volatility_indicators.rb +27 -31
- data/lib/sqa/tai/volume_indicators.rb +9 -3
- data/lib/sqa/tai.rb +38 -29
- data/mkdocs.yml +153 -15
- data/sqa-tai.gemspec +54 -0
- metadata +131 -13
- data/Gemfile.lock +0 -71
- data/lib/extensions/ta_lib_ffi.rb +0 -154
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sqa-tai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -10,19 +10,33 @@ cert_chain: []
|
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
-
name:
|
|
13
|
+
name: fiddle
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0
|
|
18
|
+
version: '0'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: myway_config
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
24
38
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0
|
|
39
|
+
version: '0'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: bundler
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -93,6 +107,20 @@ dependencies:
|
|
|
93
107
|
- - ">="
|
|
94
108
|
- !ruby/object:Gem::Version
|
|
95
109
|
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: debug
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
96
124
|
- !ruby/object:Gem::Dependency
|
|
97
125
|
name: debug_me
|
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,30 +135,118 @@ dependencies:
|
|
|
107
135
|
- - ">="
|
|
108
136
|
- !ruby/object:Gem::Version
|
|
109
137
|
version: '0'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: flog
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
type: :development
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
152
|
+
- !ruby/object:Gem::Dependency
|
|
153
|
+
name: flay
|
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0'
|
|
159
|
+
type: :development
|
|
160
|
+
prerelease: false
|
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: '0'
|
|
166
|
+
- !ruby/object:Gem::Dependency
|
|
167
|
+
name: racc
|
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: '0'
|
|
173
|
+
type: :development
|
|
174
|
+
prerelease: false
|
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: reek
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '0'
|
|
194
|
+
- !ruby/object:Gem::Dependency
|
|
195
|
+
name: rubocop
|
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
|
197
|
+
requirements:
|
|
198
|
+
- - ">="
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '0'
|
|
201
|
+
type: :development
|
|
202
|
+
prerelease: false
|
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - ">="
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '0'
|
|
208
|
+
- !ruby/object:Gem::Dependency
|
|
209
|
+
name: fasterer
|
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0'
|
|
215
|
+
type: :development
|
|
216
|
+
prerelease: false
|
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
222
|
+
description: An SQA-specific Fiddle binding directly against the installed TA-Lib
|
|
223
|
+
C library, providing many technical analysis indicators for stock analysis. Part
|
|
224
|
+
of the SQA (Simple Qualitative Analysis) ecosystem.
|
|
113
225
|
email:
|
|
114
226
|
- dvanhoozer@gmail.com
|
|
115
227
|
executables: []
|
|
116
228
|
extensions: []
|
|
117
229
|
extra_rdoc_files: []
|
|
118
230
|
files:
|
|
231
|
+
- ".claude/settings.local.json"
|
|
119
232
|
- ".envrc"
|
|
233
|
+
- ".loki"
|
|
234
|
+
- ".quality/reek_baseline.txt"
|
|
235
|
+
- ".rubocop.yml"
|
|
120
236
|
- CHANGELOG.md
|
|
121
237
|
- COMMITS.md
|
|
122
238
|
- Gemfile
|
|
123
|
-
- Gemfile.
|
|
239
|
+
- Gemfile.local
|
|
124
240
|
- LICENSE
|
|
125
241
|
- README.md
|
|
126
242
|
- Rakefile
|
|
127
|
-
- lib/extensions/ta_lib_ffi.rb
|
|
128
243
|
- lib/sqa/tai.rb
|
|
129
244
|
- lib/sqa/tai/cycle_indicators.rb
|
|
130
245
|
- lib/sqa/tai/help.rb
|
|
131
246
|
- lib/sqa/tai/help/data.json
|
|
132
247
|
- lib/sqa/tai/help/resource.rb
|
|
133
248
|
- lib/sqa/tai/momentum_indicators.rb
|
|
249
|
+
- lib/sqa/tai/native.rb
|
|
134
250
|
- lib/sqa/tai/overlap_studies.rb
|
|
135
251
|
- lib/sqa/tai/pattern_recognition.rb
|
|
136
252
|
- lib/sqa/tai/price_transform.rb
|
|
@@ -139,6 +255,7 @@ files:
|
|
|
139
255
|
- lib/sqa/tai/volatility_indicators.rb
|
|
140
256
|
- lib/sqa/tai/volume_indicators.rb
|
|
141
257
|
- mkdocs.yml
|
|
258
|
+
- sqa-tai.gemspec
|
|
142
259
|
- ta-lib-license.md
|
|
143
260
|
homepage: https://github.com/MadBomber/sqa-tai
|
|
144
261
|
licenses:
|
|
@@ -149,6 +266,7 @@ metadata:
|
|
|
149
266
|
source_code_uri: https://github.com/MadBomber/sqa-tai
|
|
150
267
|
changelog_uri: https://github.com/MadBomber/sqa-tai/blob/main/CHANGELOG.md
|
|
151
268
|
documentation_uri: https://madbomber.github.io/sqa-tai
|
|
269
|
+
rubygems_mfa_required: 'true'
|
|
152
270
|
rdoc_options: []
|
|
153
271
|
require_paths:
|
|
154
272
|
- lib
|
|
@@ -156,14 +274,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
156
274
|
requirements:
|
|
157
275
|
- - ">="
|
|
158
276
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: 3.
|
|
277
|
+
version: 3.4.0
|
|
160
278
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
279
|
requirements:
|
|
162
280
|
- - ">="
|
|
163
281
|
- !ruby/object:Gem::Version
|
|
164
282
|
version: '0'
|
|
165
283
|
requirements: []
|
|
166
|
-
rubygems_version:
|
|
284
|
+
rubygems_version: 4.0.21
|
|
167
285
|
specification_version: 4
|
|
168
286
|
summary: SQA::TAI - Technical Analysis Indicators
|
|
169
287
|
test_files: []
|
data/Gemfile.lock
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
sqa-tai (0.1.2)
|
|
5
|
-
ta_lib_ffi (~> 0.3)
|
|
6
|
-
|
|
7
|
-
GEM
|
|
8
|
-
remote: https://rubygems.org/
|
|
9
|
-
specs:
|
|
10
|
-
ansi (1.5.0)
|
|
11
|
-
builder (3.3.0)
|
|
12
|
-
date (3.5.0)
|
|
13
|
-
debug (1.11.0)
|
|
14
|
-
irb (~> 1.10)
|
|
15
|
-
reline (>= 0.3.8)
|
|
16
|
-
debug_me (1.1.1)
|
|
17
|
-
docile (1.4.1)
|
|
18
|
-
erb (5.1.3)
|
|
19
|
-
fiddle (1.1.8)
|
|
20
|
-
io-console (0.8.1)
|
|
21
|
-
irb (1.15.3)
|
|
22
|
-
pp (>= 0.6.0)
|
|
23
|
-
rdoc (>= 4.0.0)
|
|
24
|
-
reline (>= 0.4.2)
|
|
25
|
-
minitest (5.26.0)
|
|
26
|
-
minitest-reporters (1.7.1)
|
|
27
|
-
ansi
|
|
28
|
-
builder
|
|
29
|
-
minitest (>= 5.0)
|
|
30
|
-
ruby-progressbar
|
|
31
|
-
pp (0.6.3)
|
|
32
|
-
prettyprint
|
|
33
|
-
prettyprint (0.2.0)
|
|
34
|
-
psych (5.2.6)
|
|
35
|
-
date
|
|
36
|
-
stringio
|
|
37
|
-
rake (13.3.1)
|
|
38
|
-
rdoc (6.15.1)
|
|
39
|
-
erb
|
|
40
|
-
psych (>= 4.0.0)
|
|
41
|
-
tsort
|
|
42
|
-
reline (0.6.2)
|
|
43
|
-
io-console (~> 0.5)
|
|
44
|
-
ruby-progressbar (1.13.0)
|
|
45
|
-
simplecov (0.22.0)
|
|
46
|
-
docile (~> 1.1)
|
|
47
|
-
simplecov-html (~> 0.11)
|
|
48
|
-
simplecov_json_formatter (~> 0.1)
|
|
49
|
-
simplecov-html (0.13.2)
|
|
50
|
-
simplecov_json_formatter (0.1.4)
|
|
51
|
-
stringio (3.1.7)
|
|
52
|
-
ta_lib_ffi (0.3.0)
|
|
53
|
-
fiddle (~> 1.1)
|
|
54
|
-
tsort (0.2.0)
|
|
55
|
-
|
|
56
|
-
PLATFORMS
|
|
57
|
-
arm64-darwin-25
|
|
58
|
-
ruby
|
|
59
|
-
|
|
60
|
-
DEPENDENCIES
|
|
61
|
-
bundler
|
|
62
|
-
debug
|
|
63
|
-
debug_me
|
|
64
|
-
minitest (~> 5.0)
|
|
65
|
-
minitest-reporters
|
|
66
|
-
rake (~> 13.0, >= 0)
|
|
67
|
-
simplecov
|
|
68
|
-
sqa-tai!
|
|
69
|
-
|
|
70
|
-
BUNDLED WITH
|
|
71
|
-
2.7.2
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Monkey patch for ta_lib_ffi 0.3.0 to fix multi-array parameter bug
|
|
4
|
-
#
|
|
5
|
-
# This patch fixes a critical bug in ta_lib_ffi 0.3.0 where functions requiring
|
|
6
|
-
# multiple array parameters (high, low, close) fail with NoMethodError.
|
|
7
|
-
#
|
|
8
|
-
# Affected functions:
|
|
9
|
-
# - All volatility indicators (ATR, NATR, SAR, TRANGE)
|
|
10
|
-
# - All momentum indicators requiring OHLC (CCI, WILLR, ADX, STOCH)
|
|
11
|
-
# - All volume indicators (OBV, AD, ADOSC)
|
|
12
|
-
# - All candlestick pattern recognition functions (60+ patterns)
|
|
13
|
-
#
|
|
14
|
-
# This patch can be removed once ta_lib_ffi fixes the upstream bug.
|
|
15
|
-
|
|
16
|
-
module TALibFFI
|
|
17
|
-
class << self
|
|
18
|
-
# Store original method to call it for non-price parameters
|
|
19
|
-
alias_method :original_setup_input_parameters, :setup_input_parameters
|
|
20
|
-
|
|
21
|
-
# Fixed version that properly handles multi-array Price inputs
|
|
22
|
-
#
|
|
23
|
-
# The original code assumes a 1-to-1 mapping between input_arrays and function
|
|
24
|
-
# parameters, but TA_Input_Price parameters can consume multiple arrays.
|
|
25
|
-
#
|
|
26
|
-
# This fix:
|
|
27
|
-
# 1. Tracks position in input_arrays with array_index
|
|
28
|
-
# 2. For each function parameter, checks its type
|
|
29
|
-
# 3. For TA_Input_Price, determines how many arrays are needed from flags
|
|
30
|
-
# 4. Bundles those arrays together: [[high], [low], [close]]
|
|
31
|
-
# 5. Passes the bundle to setup_price_inputs
|
|
32
|
-
# 6. Advances array_index by the number of arrays consumed
|
|
33
|
-
def setup_input_parameters(params_ptr, input_arrays, func_name)
|
|
34
|
-
func_info = function_info_map[func_name]
|
|
35
|
-
array_index = 0 # Track position in input_arrays
|
|
36
|
-
|
|
37
|
-
func_info[:inputs].each_with_index do |input_info, param_index|
|
|
38
|
-
case input_info["type"]
|
|
39
|
-
when TA_PARAM_TYPE[:TA_Input_Price]
|
|
40
|
-
# Price inputs consume multiple arrays based on required flags
|
|
41
|
-
required_flags = extract_flags(input_info["flags"], :TA_InputFlags)
|
|
42
|
-
num_arrays = required_flags.length
|
|
43
|
-
|
|
44
|
-
# Collect the next num_arrays from input_arrays
|
|
45
|
-
if array_index + num_arrays > input_arrays.length
|
|
46
|
-
raise ArgumentError, "Function #{func_name} requires #{num_arrays} price arrays " \
|
|
47
|
-
"(#{required_flags.join(', ')}), but only #{input_arrays.length - array_index} " \
|
|
48
|
-
"provided at position #{array_index}"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
price_arrays = input_arrays[array_index, num_arrays]
|
|
52
|
-
|
|
53
|
-
# Pass the bundled arrays to set_input_parameter
|
|
54
|
-
ret_code = set_input_parameter(params_ptr, param_index, price_arrays, input_info)
|
|
55
|
-
check_ta_return_code(ret_code)
|
|
56
|
-
|
|
57
|
-
array_index += num_arrays # Advance by number of arrays consumed
|
|
58
|
-
|
|
59
|
-
when TA_PARAM_TYPE[:TA_Input_Real], TA_PARAM_TYPE[:TA_Input_Integer]
|
|
60
|
-
# Single array inputs
|
|
61
|
-
if array_index >= input_arrays.length
|
|
62
|
-
raise ArgumentError, "Not enough input arrays for function #{func_name} " \
|
|
63
|
-
"(expected array at index #{array_index}, but only #{input_arrays.length} provided)"
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
ret_code = set_input_parameter(params_ptr, param_index, input_arrays[array_index], input_info)
|
|
67
|
-
check_ta_return_code(ret_code)
|
|
68
|
-
|
|
69
|
-
array_index += 1 # Advance by one
|
|
70
|
-
|
|
71
|
-
else
|
|
72
|
-
# Unknown type - should not happen, but handle gracefully
|
|
73
|
-
raise ArgumentError, "Unknown input type #{input_info['type']} for function #{func_name}"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Verify all arrays were consumed
|
|
78
|
-
if array_index != input_arrays.length
|
|
79
|
-
raise ArgumentError, "Function #{func_name} expected #{array_index} input arrays " \
|
|
80
|
-
"but received #{input_arrays.length}"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Store original method
|
|
85
|
-
alias_method :original_setup_price_inputs, :setup_price_inputs
|
|
86
|
-
|
|
87
|
-
# Fixed version that handles bundled price arrays correctly
|
|
88
|
-
#
|
|
89
|
-
# After the setup_input_parameters fix, price_data is now guaranteed to be
|
|
90
|
-
# an array of arrays: [[high_array], [low_array], [close_array]]
|
|
91
|
-
def setup_price_inputs(params_ptr, index, price_data, flags)
|
|
92
|
-
required_flags = extract_flags(flags, :TA_InputFlags)
|
|
93
|
-
data_pointers = Array.new(6) { Fiddle::Pointer.malloc(0) }
|
|
94
|
-
|
|
95
|
-
# price_data is now an array of arrays: [[high], [low], [close]]
|
|
96
|
-
# Each element corresponds to one required flag
|
|
97
|
-
required_flags.each_with_index do |flag, i|
|
|
98
|
-
flag_index = TA_FLAGS[:TA_InputFlags].keys.index(flag)
|
|
99
|
-
|
|
100
|
-
# price_data[i] now correctly returns an array (e.g., high, low, or close)
|
|
101
|
-
if price_data[i].nil?
|
|
102
|
-
raise ArgumentError, "Missing price array for flag #{flag} at index #{i}"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Validate it's an array
|
|
106
|
-
unless price_data[i].is_a?(Array)
|
|
107
|
-
raise ArgumentError, "Expected array for flag #{flag} at index #{i}, " \
|
|
108
|
-
"got #{price_data[i].class}"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
data_pointers[flag_index] = prepare_double_array(price_data[i]) if required_flags.include?(flag)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
TA_SetInputParamPricePtr(params_ptr, index, *data_pointers)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Store original method
|
|
118
|
-
alias_method :original_calculate_results, :calculate_results
|
|
119
|
-
|
|
120
|
-
# Fixed version that correctly determines input_size for Price inputs
|
|
121
|
-
#
|
|
122
|
-
# The original code expects input_arrays[0][0].length for Price inputs,
|
|
123
|
-
# which assumes format [[high], [low], [close]]. Our fix passes [high, low, close],
|
|
124
|
-
# so we need to adjust this check.
|
|
125
|
-
def calculate_results(params_ptr, input_arrays, func_name)
|
|
126
|
-
func_info = function_info_map[func_name]
|
|
127
|
-
|
|
128
|
-
# Determine input size based on input type
|
|
129
|
-
input_size = if func_info[:inputs].first["type"] == TA_PARAM_TYPE[:TA_Input_Price]
|
|
130
|
-
# For Price inputs, input_arrays is [high, low, close]
|
|
131
|
-
# Get length from the first array
|
|
132
|
-
input_arrays[0].length
|
|
133
|
-
else
|
|
134
|
-
# For other inputs, get length normally
|
|
135
|
-
input_arrays[0].length
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
out_begin = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
|
|
139
|
-
out_size = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
|
|
140
|
-
output_arrays = setup_output_buffers(params_ptr, input_size, func_name)
|
|
141
|
-
|
|
142
|
-
begin
|
|
143
|
-
ret_code = TA_CallFunc(params_ptr, 0, input_size - 1, out_begin, out_size)
|
|
144
|
-
check_ta_return_code(ret_code)
|
|
145
|
-
|
|
146
|
-
actual_size = out_size[0, Fiddle::SIZEOF_INT].unpack1("l")
|
|
147
|
-
format_output_results(output_arrays, actual_size, func_name)
|
|
148
|
-
ensure
|
|
149
|
-
out_begin.free
|
|
150
|
-
out_size.free
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|