tafunc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +113 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/examples/tafunc_adx.rb +30 -0
- data/examples/tafunc_hints.rb +13 -0
- data/examples/tafunc_ma.rb +25 -0
- data/examples/tafunc_macd.rb +40 -0
- data/lib/tafunc.rb +770 -0
- data/lib/tafunc_array.rb +50 -0
- data/tafunc.gemspec +64 -0
- data/test/helper.rb +18 -0
- data/test/test_tafunc.rb +505 -0
- data/test/test_tafunc_more.rb +53 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a16c9b54df3d232237180720227c7eaf76d4bf3
|
4
|
+
data.tar.gz: 0e43e95d6331b02987609f857b904428f9af528e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3b3b56efb395dbce0b9b5eef73733063ca71b6bafc7a5b9c8d4925f7c56fc8b9e63fb8578026e8b4a318301dacb123eb48c5cdbe703404d4654b0efbeccc3e0
|
7
|
+
data.tar.gz: c77ba939c0afe776b67e030b0be892089c0111be7ef5144cb37ee752253402650530a0d44a9868350e903929f4cc5dd9f8859084feba9042b6b288582ba946fe
|
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "bundler", "~> 1.0"
|
12
|
+
gem "jeweler", "~> 1.8.7"
|
13
|
+
gem "talib_ruby", ">= 1.0.5"
|
14
|
+
gem "activesupport", ">= 4.0.0"
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 YAMAMOTO, Masayuki
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# TAFunc - another talib_ruby wrapper and extension README.
|
2
|
+
|
3
|
+
TAFunc provides utility extensions for talib_ruby.
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
* [TA-Lib library](http://ta-lib.org) itself. On Mac, just do ``[sudo] brew install ta-lib``
|
7
|
+
* activesupport/core_ext (just for underscore method)
|
8
|
+
* ``talib_ruby`` gem which is modified ver. of 1.0.5 for TaLib::Function.{groups, functions} (see my github repository: https://github.com/mephistobooks/talib-ruby/tree/patch-1217a)
|
9
|
+
* Ruby 2.0 (I tested in this environment)
|
10
|
+
*
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
|
15
|
+
## Description
|
16
|
+
|
17
|
+
According to ``ta_abstract.h`` of TA-Lib, there are some ways of wrapping library. Mlamby-san's [indicator](https://github.com/mlamby/indicator), which contains useful extension, takes static code generation approach using [XML at SourceForge]() to get TA method information.
|
18
|
+
|
19
|
+
On the contrary, the approach of TAFunc is more dynamic and meta-programming. No xml is needed. No static code generation.
|
20
|
+
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
```
|
25
|
+
ma = TaLib::TAFunc.new( :MA ) do |taf|
|
26
|
+
taf.param_in_real = ARRAY_OF_HISTORICAL_DATA
|
27
|
+
taf.param_opt_in_period = 2
|
28
|
+
end
|
29
|
+
|
30
|
+
ma.call
|
31
|
+
|
32
|
+
```
|
33
|
+
|
34
|
+
```
|
35
|
+
result = [1.0, 2.0, 3.0, 4.0].tafunc( :MA ) do |taf|
|
36
|
+
taf.param_in_real = ARRAY_OF_HISTORICAL_DATA
|
37
|
+
taf.param_opt_in_time_period = 2
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
|
42
|
+
```
|
43
|
+
TaLib::TAFunc.new( :MACDEXT ).hints
|
44
|
+
==== Momentum Indicators ====
|
45
|
+
<MACDEXT>
|
46
|
+
inputs:
|
47
|
+
param_in_real
|
48
|
+
|
49
|
+
options:
|
50
|
+
param_opt_in_fast_period
|
51
|
+
param_opt_in_fast_ma_type
|
52
|
+
param_opt_in_slow_period
|
53
|
+
param_opt_in_slow_ma_type
|
54
|
+
param_opt_in_signal_period
|
55
|
+
param_opt_in_signal_ma_type
|
56
|
+
|
57
|
+
outputs:
|
58
|
+
param_out_macd
|
59
|
+
param_out_macd_signal
|
60
|
+
param_out_macd_hist
|
61
|
+
|
62
|
+
|
63
|
+
=> ["Momentum Indicators"]
|
64
|
+
```
|
65
|
+
|
66
|
+
```
|
67
|
+
>> TaLib::TAFunc.groups
|
68
|
+
=> ["Math Operators", "Math Transform", "Overlap Studies", "Volatility Indicators", "Momentum Indicators", "Cycle Indicators", "Volume Indicators", "Pattern Recognition", "Statistic Functions", "Price Transform"]
|
69
|
+
>> TaLib::TAFunc.function
|
70
|
+
TaLib::TAFunc.function_exists? TaLib::TAFunc.functions
|
71
|
+
TaLib::TAFunc.function_find
|
72
|
+
|
73
|
+
>> TaLib::TAFunc.group_of_function( :MA )
|
74
|
+
=> "Overlap Studies"
|
75
|
+
>> TaLib::TAFunc.new( :MA ).hints
|
76
|
+
==== Overlap Studies ====
|
77
|
+
<MA>
|
78
|
+
inputs:
|
79
|
+
param_in_real
|
80
|
+
|
81
|
+
options:
|
82
|
+
param_opt_in_time_period
|
83
|
+
param_opt_in_ma_type
|
84
|
+
|
85
|
+
outputs:
|
86
|
+
param_out_real
|
87
|
+
|
88
|
+
|
89
|
+
=> ["Overlap Studies"]
|
90
|
+
```
|
91
|
+
|
92
|
+
See in ``examples`` directory and test code for details.
|
93
|
+
|
94
|
+
## References
|
95
|
+
* TA-Lib
|
96
|
+
* TACODE.org is also nice documentation which discribes many of TA methods.
|
97
|
+
*
|
98
|
+
|
99
|
+
## Contributing to TAFunc
|
100
|
+
|
101
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
102
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
103
|
+
* Fork the project.
|
104
|
+
* Start a feature/bugfix branch.
|
105
|
+
* Commit and push until you are happy with your contribution.
|
106
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
107
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
108
|
+
|
109
|
+
## Copyright
|
110
|
+
|
111
|
+
Copyright (c) 2013 YAMAMOTO, Masayuki. License is MIT. See LICENSE.txt for
|
112
|
+
further details.
|
113
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "tafunc"
|
18
|
+
gem.homepage = "http://github.com/mephistobooks/tafunc"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{TAFunc: another talib_ruby wrapper and extensions}
|
21
|
+
gem.description = %Q{Useful methods are added to TaLib, TaLib::Function, and TaLib::TAFunc.}
|
22
|
+
gem.email = "martin.route66.blues+github@gmail.com"
|
23
|
+
gem.authors = ["YAMAMOTO, Masayuki"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
#require 'rcov/rcovtask'
|
36
|
+
#Rcov::RcovTask.new do |test|
|
37
|
+
# test.libs << 'test'
|
38
|
+
# test.pattern = 'test/**/test_*.rb'
|
39
|
+
# test.verbose = true
|
40
|
+
# test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
#end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rdoc/task'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "tafunc #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#require 'rubygems'
|
2
|
+
require 'tafunc'
|
3
|
+
|
4
|
+
# init input data
|
5
|
+
a = Array.new
|
6
|
+
10.times { |i| a.push i.to_f }
|
7
|
+
|
8
|
+
hi = (7..17).inject([]) { |list, i| list << i }
|
9
|
+
lo = (3..15).inject([]) { |list, i| list << i }
|
10
|
+
cl = (6..16).inject([]) { |list, i| list << i }
|
11
|
+
|
12
|
+
5.times do |k|
|
13
|
+
|
14
|
+
b = Array.new(10)
|
15
|
+
l = TaLib::TAFunc.new("ADX")
|
16
|
+
#l = TaLib::Function.new("ADX")
|
17
|
+
# setup input price
|
18
|
+
# open = nil, volume = nil, open_interest = nil
|
19
|
+
l.param_in_price_hlc = [nil, hi, lo, cl, nil, nil]
|
20
|
+
|
21
|
+
# setup optional parameter
|
22
|
+
l.opt_int(0,k+2);
|
23
|
+
|
24
|
+
# setup output parameter
|
25
|
+
l.out_real(0,b);
|
26
|
+
l.call(0,9)
|
27
|
+
|
28
|
+
p "k=#{k+2}"
|
29
|
+
p b
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "tafunc.rb"
|
2
|
+
|
3
|
+
|
4
|
+
# sample input data.
|
5
|
+
a = Array.new
|
6
|
+
10.times { |i| a.push i.to_f }
|
7
|
+
|
8
|
+
#
|
9
|
+
10.times do |k|
|
10
|
+
b = Array.new(10)
|
11
|
+
|
12
|
+
l = TaLib::TAFunc.new("MA") do |ma|
|
13
|
+
ma.param_in_real = a # setup input parameter
|
14
|
+
ma.param_opt_in_time_period = k+2 # setup optional parameter
|
15
|
+
ma.param_out_real = b # setup output parameter
|
16
|
+
end
|
17
|
+
|
18
|
+
#l.call( 0, 9 )
|
19
|
+
l.call( 0..9 )
|
20
|
+
|
21
|
+
#
|
22
|
+
p "k=#{k+2}"
|
23
|
+
p b
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "tafunc.rb"
|
2
|
+
|
3
|
+
|
4
|
+
# sample input data.
|
5
|
+
#a = Array.new
|
6
|
+
#10.times { |i| a.push i.to_f }
|
7
|
+
a = [ 1.0, 2.0, 3.0, 4.0, 5.0, 0.0, 0.0, 3.0, 4.0, ]
|
8
|
+
#a = [ 1.0, 1.0, 2.0, 3.0, 5.0, 1.0, 1.0, 2.0, 3.0, 5.0, ]
|
9
|
+
|
10
|
+
#
|
11
|
+
5.times do |k|
|
12
|
+
b = Array.new(10)
|
13
|
+
b_1 = Array.new(10)
|
14
|
+
b_2 = Array.new(10)
|
15
|
+
|
16
|
+
l = TaLib::TAFunc.new("MACDEXT") do |macd|
|
17
|
+
macd.param_in_real = a # setup input parameter
|
18
|
+
macd.param_opt_in_fast_period = k+2 # setup optional parameter
|
19
|
+
macd.param_opt_in_fast_ma_type= TaLib::TA_MAType_EMA
|
20
|
+
macd.param_opt_in_slow_period = k+3 # setup optional parameter
|
21
|
+
macd.param_opt_in_slow_ma_type= TaLib::TA_MAType_EMA
|
22
|
+
macd.param_opt_in_signal_period = k+1 # setup optional parameter
|
23
|
+
macd.param_opt_in_signal_ma_type= TaLib::TA_MAType_EMA
|
24
|
+
macd.param_out_macd = b # setup output parameter
|
25
|
+
macd.param_out_macd_signal = b_1 # setup output parameter
|
26
|
+
macd.param_out_macd_hist = b_2 # setup output parameter
|
27
|
+
end
|
28
|
+
|
29
|
+
ret = l.call
|
30
|
+
|
31
|
+
#
|
32
|
+
p "k=#{k+2}"
|
33
|
+
#p " BegIdx:#{ret[:start_idx].to_s}, #oE:#{ret[:num_elements].to_s}"
|
34
|
+
p ret
|
35
|
+
puts "MACD #{b.map{|e| (e.nil?)? nil : sprintf("%.2f",e.to_s.to_f) }}"
|
36
|
+
puts "sign #{b_1.map{|e| (e.nil?)? nil : sprintf("%.2f",e.to_s.to_f) }}"
|
37
|
+
puts "hist #{b_2.map{|e| (e.nil?)? nil : sprintf("%.2f",e.to_s.to_f) }}"
|
38
|
+
|
39
|
+
end
|
40
|
+
|
data/lib/tafunc.rb
ADDED
@@ -0,0 +1,770 @@
|
|
1
|
+
#
|
2
|
+
# filename: tafunc.rb
|
3
|
+
#
|
4
|
+
#
|
5
|
+
require "talib_ruby"
|
6
|
+
require 'active_support/core_ext'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
#require "tafunc_array"
|
10
|
+
|
11
|
+
|
12
|
+
# extension for taLib_ruby structures.
|
13
|
+
#
|
14
|
+
#
|
15
|
+
class Struct
|
16
|
+
|
17
|
+
# get structs of TA_*.
|
18
|
+
# ==== Returns
|
19
|
+
# array of TA_* structs.
|
20
|
+
def self.ta_types; self.constants.grep( /TA_.*/ ); end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# talib_ruby main module.
|
26
|
+
# class Function is defined in this module.
|
27
|
+
#
|
28
|
+
module TaLib
|
29
|
+
|
30
|
+
# get value-table for TA_Input_* of TA-Lib.
|
31
|
+
# ==== Return
|
32
|
+
# Table of Input types: { val => :sym }.
|
33
|
+
# TA_Input_{Integer,Real,Price}
|
34
|
+
#
|
35
|
+
def self.input_types
|
36
|
+
ret = {}
|
37
|
+
self.constants.grep( /^TA_Input/ ).each{|c| ret[const_get(c)] = c }
|
38
|
+
return ret
|
39
|
+
end
|
40
|
+
|
41
|
+
# get value-type table for TA_OptInput_* of TA-Lib.
|
42
|
+
# ==== Return
|
43
|
+
# Table of optinput types: { val => :sym }.
|
44
|
+
# TA_OptInput_{Real,Integer}{Range,List}
|
45
|
+
#
|
46
|
+
def self.optinput_types
|
47
|
+
ret = {}
|
48
|
+
self.constants.grep( /^TA_OptInput/ ).each{|c| ret[const_get(c)] = c }
|
49
|
+
return ret
|
50
|
+
end
|
51
|
+
|
52
|
+
# get value-type table for TA_Output_* of TA-Lib.
|
53
|
+
# ==== Return
|
54
|
+
# Table of output types: { val => :sym }.
|
55
|
+
# TA_Output_{Integer,Real}
|
56
|
+
#
|
57
|
+
def self.output_types
|
58
|
+
ret = {}
|
59
|
+
self.constants.grep( /^TA_Output/ ).each{|c| ret[const_get(c)] = c }
|
60
|
+
return ret
|
61
|
+
end
|
62
|
+
|
63
|
+
# get value-type table for TA_MAType_* of TA-Lib
|
64
|
+
# ==== Return
|
65
|
+
# Table of MA types: { val => :sym }.
|
66
|
+
#
|
67
|
+
def self.ma_types
|
68
|
+
ret = {}
|
69
|
+
self.constants.grep( /^TA_MAType_/ ).each{|c| ret[const_get(c)] = c }
|
70
|
+
return ret
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Util extension for default TaLib::Function by open-class.
|
77
|
+
#
|
78
|
+
#
|
79
|
+
class TaLib::Function
|
80
|
+
|
81
|
+
# class methods Function.groups and Function.functions are defined
|
82
|
+
# in talib.c of talib_ruby.
|
83
|
+
|
84
|
+
# :nodoc:
|
85
|
+
# ==== Return
|
86
|
+
# { :group => group_in_which_function_exists,
|
87
|
+
# :function => name_of_function }
|
88
|
+
private
|
89
|
+
def self.__group_of_function( func )
|
90
|
+
func = func.to_s if func.class != String
|
91
|
+
ret = { :group => nil, :function => nil, }
|
92
|
+
|
93
|
+
self.functions.each do |k,v|
|
94
|
+
if tmp = v.grep(/^#{func}$/i).first
|
95
|
+
then ret[:group] = k; ret[:function] = tmp; break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
return ret
|
99
|
+
end
|
100
|
+
|
101
|
+
public
|
102
|
+
# find func from hash.
|
103
|
+
# ==== Args
|
104
|
+
# func :: name of function which you want to search from the table.
|
105
|
+
# (Symbol can match with String. So you can use also Symbol)
|
106
|
+
# ==== Return
|
107
|
+
# String :: function name found.
|
108
|
+
# nil :: no such function.
|
109
|
+
def self.function_find( func )
|
110
|
+
return __group_of_function( func )[:function]
|
111
|
+
end
|
112
|
+
|
113
|
+
# check if a function is existed.
|
114
|
+
# ==== Args
|
115
|
+
# func :: name of function which you want to search from the table.
|
116
|
+
# ==== Return
|
117
|
+
# true :: there exists
|
118
|
+
# false :: no such function.
|
119
|
+
def self.function_exists?( func )
|
120
|
+
return not(self.function_find(func).nil?)
|
121
|
+
end
|
122
|
+
|
123
|
+
public
|
124
|
+
# get the group of specified function.
|
125
|
+
#
|
126
|
+
def self.group_of_function( func )
|
127
|
+
return __group_of_function( func )[:group]
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
####
|
132
|
+
|
133
|
+
# TA Function name.
|
134
|
+
attr_reader :name if defined?( name ).nil? # @name
|
135
|
+
|
136
|
+
####
|
137
|
+
|
138
|
+
# the interfaces of each TA function.
|
139
|
+
# Define ifs_ins, ifs_outs, and ifs_opts with
|
140
|
+
# TaLib::Function#{in[s],out[s],opt[s]}.
|
141
|
+
#
|
142
|
+
ifs = ["in","out","opt"]
|
143
|
+
ifs.each do |funcif|
|
144
|
+
|
145
|
+
##
|
146
|
+
# :method: ifs_ins
|
147
|
+
# Helper method of Function#{in,ins}.
|
148
|
+
# ==== Args
|
149
|
+
# none.
|
150
|
+
# ==== Return
|
151
|
+
# input interface (parameters) of current Function object.
|
152
|
+
# ex. [#<struct Struct::TA_InputParameterInfo type=1,
|
153
|
+
# param_name="inReal", flags=0>]
|
154
|
+
# type corresponds to TaLib.input_type[type].
|
155
|
+
#
|
156
|
+
|
157
|
+
##
|
158
|
+
# :method: ifs_opts
|
159
|
+
# Helper method of Function#{opt,opts}
|
160
|
+
# ==== Args
|
161
|
+
# none.
|
162
|
+
# ==== Return
|
163
|
+
# option interface (parameters) of current Function object.
|
164
|
+
|
165
|
+
##
|
166
|
+
# :method: ifs_outs
|
167
|
+
# Helper method of Function#{out,outs}
|
168
|
+
# ==== Args
|
169
|
+
# none.
|
170
|
+
# ==== Return
|
171
|
+
# output interface (parameters) of current Function object.
|
172
|
+
#
|
173
|
+
|
174
|
+
##
|
175
|
+
|
176
|
+
define_method("ifs_#{funcif}s") {
|
177
|
+
eval("self.#{funcif}s.times.map {|i| self.#{funcif}(i) }")
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# :method: ifs_all
|
183
|
+
# list all of ifs_ins, ifs_outs, ifs_opts.
|
184
|
+
# ==== Args
|
185
|
+
# none.
|
186
|
+
# ==== Return
|
187
|
+
# Array of current object (an instance of Function) interfaces.
|
188
|
+
|
189
|
+
##
|
190
|
+
|
191
|
+
define_method("ifs_all") {
|
192
|
+
ifs.map{|ifname|
|
193
|
+
eval("ifs_#{ifname}s")
|
194
|
+
}.flatten
|
195
|
+
}
|
196
|
+
|
197
|
+
####
|
198
|
+
|
199
|
+
# Function#call(idx1,idx2) is defined.
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
# more Util extensions for TaLib::Function.
|
205
|
+
#
|
206
|
+
#
|
207
|
+
class TaLib::TAFunc < TaLib::Function
|
208
|
+
|
209
|
+
# :nodoc:
|
210
|
+
PPREFIX = "param_"
|
211
|
+
table_for_param = {
|
212
|
+
"in" => ["int","real","price"],
|
213
|
+
"opt" => ["int","real"],
|
214
|
+
"out" => ["int","real"],
|
215
|
+
}
|
216
|
+
table_for_param_regex = {
|
217
|
+
"in" => ["Price","Integer","Real"],
|
218
|
+
"opt" => ["Integer","Real"],
|
219
|
+
"out" => ["Integer","Real"],
|
220
|
+
}
|
221
|
+
def etype_attr
|
222
|
+
{
|
223
|
+
"in" => { 0 => "price",
|
224
|
+
1 => "real",
|
225
|
+
2 => "int", },
|
226
|
+
"opt" => { 0 => "real",
|
227
|
+
1 => "real",
|
228
|
+
2 => "int",
|
229
|
+
3 => "int", },
|
230
|
+
"out" => { 0 => "real",
|
231
|
+
1 => "int", },
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
# generate interface methods (parameters) of each Function, dynamically.
|
237
|
+
# (used only by #initialize)
|
238
|
+
#
|
239
|
+
# generated methods are param_in_*, param_opt_*, param_out_*. These are
|
240
|
+
# due to each Function's specification.
|
241
|
+
#
|
242
|
+
# ex. for MACDEXT, param_in_real (getter), and param_in_real= (setter)
|
243
|
+
# are generated as input parameter. This is singleton methods.
|
244
|
+
#
|
245
|
+
# To see the generated methods, use #param_methods, #param_attr or
|
246
|
+
# something.
|
247
|
+
# ==== Args
|
248
|
+
# none.
|
249
|
+
# ==== Return
|
250
|
+
# none.
|
251
|
+
# ==== TODO
|
252
|
+
# * hove to change ( wh = :val ) interface for getter?
|
253
|
+
# (maybe confused to setter.)
|
254
|
+
def __define_ifmethods
|
255
|
+
|
256
|
+
#
|
257
|
+
types = {
|
258
|
+
:ifs_ins => :input_types,
|
259
|
+
:ifs_opts => :optinput_types,
|
260
|
+
:ifs_outs => :output_types,
|
261
|
+
}
|
262
|
+
types_dir = {
|
263
|
+
:ifs_ins => 'in',
|
264
|
+
:ifs_opts => 'opt',
|
265
|
+
:ifs_outs => 'out',
|
266
|
+
}
|
267
|
+
|
268
|
+
# param_accessors generator.
|
269
|
+
#
|
270
|
+
#
|
271
|
+
types.each do |ifs_method, type_method|
|
272
|
+
send(ifs_method).each do |e|
|
273
|
+
case
|
274
|
+
when TaLib.send(type_method)[e.type].to_s =~ /(Price)|(Integer)|(Real)/
|
275
|
+
idx = send(ifs_method).index(e)
|
276
|
+
typ = etype_attr[types_dir[ifs_method]][e.type]
|
277
|
+
|
278
|
+
define_singleton_method( PPREFIX+
|
279
|
+
e.param_name.underscore ) {|wh=:val|
|
280
|
+
unless wh =~ /^(val)|(type)$/ # :sym matches "sym".
|
281
|
+
raise "#{__method__} is getter and cannot recognaize"+
|
282
|
+
" the argument: #{wh}"
|
283
|
+
end
|
284
|
+
|
285
|
+
#
|
286
|
+
(send("param_"+types_dir[ifs_method])[idx].nil?)? nil : \
|
287
|
+
send("param_"+types_dir[ifs_method])[idx][wh]
|
288
|
+
}
|
289
|
+
if typ =~ /Price/i
|
290
|
+
then
|
291
|
+
# define param_in_price_hlc= , etc.
|
292
|
+
#
|
293
|
+
#
|
294
|
+
#define_singleton_method( PPREFIX+
|
295
|
+
# e.param_name.underscore+'=') {|vo,vh,vl,vc,vv,voi|
|
296
|
+
define_singleton_method( PPREFIX+
|
297
|
+
e.param_name.underscore+'=') {|vv|
|
298
|
+
#pp vv
|
299
|
+
|
300
|
+
#
|
301
|
+
vv.each do |v_e|
|
302
|
+
if v_e.nil? or v_e==[]
|
303
|
+
next
|
304
|
+
elsif v_e.class != Array
|
305
|
+
then raise "#{__method__} error!"+
|
306
|
+
" #{v_e.to_s}(#{v_e.class.to_s}) must be array."
|
307
|
+
end
|
308
|
+
end if vv.class == Array
|
309
|
+
|
310
|
+
# in_price,
|
311
|
+
send( types_dir[ifs_method]+"_"+typ,
|
312
|
+
idx,
|
313
|
+
{ :open => vv[0],
|
314
|
+
:high => vv[1],
|
315
|
+
:low => vv[2],
|
316
|
+
:close => vv[3],
|
317
|
+
:volume => vv[4],
|
318
|
+
:oi => vv[5], } )
|
319
|
+
}
|
320
|
+
|
321
|
+
else
|
322
|
+
define_singleton_method( PPREFIX+
|
323
|
+
e.param_name.underscore+'=') {|v|
|
324
|
+
send( types_dir[ifs_method]+"_"+typ, idx, v )
|
325
|
+
}
|
326
|
+
|
327
|
+
end
|
328
|
+
|
329
|
+
else
|
330
|
+
raise "Initialization error #{TaLib.input_types[e.type]} #{e}!"
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
# # accessor generator
|
337
|
+
# # for input parameter of the current TA function.
|
338
|
+
# self.ifs_ins.each {|e|
|
339
|
+
# case
|
340
|
+
# when TaLib.input_types[e.type].to_s =~ /(Price)|(Integer)|(Real)/
|
341
|
+
# #
|
342
|
+
# # This is NG: self.class.class_eval { ... }.
|
343
|
+
# # Because same instance methods are re-difined on TAFunc when
|
344
|
+
# # we do TAFunc.new multiple times.
|
345
|
+
# #
|
346
|
+
# # So, we have to create singleton-methods on each object of
|
347
|
+
# # TAFunc by ~~``self.singleton_class.instance_eval``~~.
|
348
|
+
# #
|
349
|
+
# #
|
350
|
+
# idx = ifs_ins.index(e)
|
351
|
+
# typ = etype_attr['in'][e.type]
|
352
|
+
#
|
353
|
+
# define_singleton_method( PPREFIX+
|
354
|
+
# e.param_name.underscore ) {|wh=:val|
|
355
|
+
# #idx = ifs_ins.index(e)
|
356
|
+
# unless wh =~ /^(val)|(type)$/ # :sym matches "sym".
|
357
|
+
# raise "#{__method__} is getter and cannot recognaize"+
|
358
|
+
# " the argument: #{wh}"
|
359
|
+
# end
|
360
|
+
#
|
361
|
+
# (@param_in[idx].nil?)? nil : @param_in[idx][wh]
|
362
|
+
# }
|
363
|
+
# define_singleton_method( PPREFIX+
|
364
|
+
# e.param_name.underscore+'=') {|v|
|
365
|
+
# #eval("in_price( ifs_ins.index(e), v )")
|
366
|
+
# #eval("in_#{etype_attr['in'][e.type]}( ifs_ins.index(e), v )")
|
367
|
+
# #puts "#{__method__}: #{idx}, #{v}"
|
368
|
+
# #puts "raw method: in_#{etype_attr['in'][e.type]}"
|
369
|
+
#
|
370
|
+
# send("in_"+typ, idx, v )
|
371
|
+
# }
|
372
|
+
# else
|
373
|
+
# raise "Initialization error #{TaLib.input_types[e.type]} #{e}!"
|
374
|
+
# end
|
375
|
+
# }
|
376
|
+
#
|
377
|
+
# # accessor generator
|
378
|
+
# # for option parameter of current TA function.
|
379
|
+
# self.ifs_opts.each {|e|
|
380
|
+
# case
|
381
|
+
# when TaLib.optinput_types[e.type].to_s =~ /(Integer)|(Real)/
|
382
|
+
# idx = ifs_opts.index(e)
|
383
|
+
# typ = etype_attr['opt'][e.type]
|
384
|
+
#
|
385
|
+
# define_singleton_method( PPREFIX+
|
386
|
+
# e.param_name.underscore ) {|wh=:val|
|
387
|
+
# unless wh =~ /^(val)|(type)$/ # :sym matches "sym".
|
388
|
+
# raise "#{__method__} is getter and cannot recognaize"+
|
389
|
+
# " the argument: #{wh}"
|
390
|
+
# end
|
391
|
+
#
|
392
|
+
# (@param_opt[idx].nil?)? nil : @param_opt[idx][wh]
|
393
|
+
# }
|
394
|
+
# define_singleton_method( PPREFIX+
|
395
|
+
# e.param_name.underscore + '=' ) {|v|
|
396
|
+
# #eval("opt_int( ifs_opts.index(e), v )")
|
397
|
+
# send( "opt_"+typ, idx, v )
|
398
|
+
# }
|
399
|
+
# else
|
400
|
+
# raise "Initialization error #{TaLib.optinput_types[e.type]} #{e}!"
|
401
|
+
# end
|
402
|
+
# }
|
403
|
+
#
|
404
|
+
# # accessor generator
|
405
|
+
# # for output parameter of current TA function.
|
406
|
+
# self.ifs_outs.each {|e|
|
407
|
+
# case
|
408
|
+
# when TaLib.output_types[e.type].to_s =~ /(Integer)|(Real)/
|
409
|
+
# idx = ifs_outs.index(e)
|
410
|
+
# typ = etype_attr['out'][e.type]
|
411
|
+
#
|
412
|
+
# define_singleton_method( PPREFIX+
|
413
|
+
# e.param_name.underscore ) {|wh=:val|
|
414
|
+
# unless wh =~ /^(val)|(type)$/ # :sym matches "sym".
|
415
|
+
# raise "#{__method__} is getter and cannot recognaize"+
|
416
|
+
# " the argument: #{wh}"
|
417
|
+
# end
|
418
|
+
#
|
419
|
+
# (@param_out[idx].nil?)? nil : @param_out[idx][wh]
|
420
|
+
# }
|
421
|
+
# define_singleton_method( PPREFIX+
|
422
|
+
# e.param_name.underscore + '=' ) {|v|
|
423
|
+
# #eval("out_int( ifs_outs.index(e), v )")
|
424
|
+
# send( "out_"+typ, idx, v )
|
425
|
+
# }
|
426
|
+
# else
|
427
|
+
# raise "Initialization error #{TaLib.output_types[e.type]} #{e}!"
|
428
|
+
# end
|
429
|
+
# }
|
430
|
+
end
|
431
|
+
|
432
|
+
public
|
433
|
+
# get defined singleton methods of param_{in,opt,out}_*.
|
434
|
+
#
|
435
|
+
#
|
436
|
+
def param_methods( kind = "(in|opt|out)" )
|
437
|
+
kind = kind.to_s if kind.class == Symbol
|
438
|
+
self.singleton_methods.grep(/^param_#{kind}_.+$/)
|
439
|
+
end
|
440
|
+
def param_attr( kind = "(in|opt|out)" )
|
441
|
+
self.param_methods( kind ).grep(/[^=]$/)
|
442
|
+
end
|
443
|
+
|
444
|
+
|
445
|
+
public
|
446
|
+
#
|
447
|
+
# ==== Args
|
448
|
+
# func :: The function name.
|
449
|
+
#
|
450
|
+
def initialize( func, arr_in: [], arr_out: [] )
|
451
|
+
func = func.to_s if func.class == Symbol
|
452
|
+
func_renamed = self.class.function_find( func )
|
453
|
+
case
|
454
|
+
when func.class != String
|
455
|
+
raise "Type error for the function name: #{func.class}(#{func})!"+
|
456
|
+
" This should be in String."
|
457
|
+
when TaLib::Function.function_exists?( func ) == false
|
458
|
+
raise "No such function: #{func}!"+
|
459
|
+
" Choose one of"+
|
460
|
+
" #{TaLib::Function.functions.values.flatten.join(' ')}."
|
461
|
+
end
|
462
|
+
|
463
|
+
#
|
464
|
+
super( func_renamed )
|
465
|
+
|
466
|
+
# for recording parameter setting.
|
467
|
+
# { idx => { :val => some_val,
|
468
|
+
# :type => type_name, }
|
469
|
+
#
|
470
|
+
@param_in = {}
|
471
|
+
@param_opt = {}
|
472
|
+
@param_out = {}
|
473
|
+
|
474
|
+
# define method for the function: func.
|
475
|
+
# for example, param_in_real, param_opt_in_fast_period methods, etc.
|
476
|
+
#
|
477
|
+
__define_ifmethods
|
478
|
+
|
479
|
+
# this must be after __define_ifmethods because we want to use
|
480
|
+
# generated interface methods in yield block.
|
481
|
+
#
|
482
|
+
yield self if block_given?
|
483
|
+
|
484
|
+
end
|
485
|
+
|
486
|
+
public
|
487
|
+
# current parameter values of each object of Function.
|
488
|
+
# for @param_in, @param_opt, @param_out.
|
489
|
+
# ==== See Also
|
490
|
+
# * TaLib::Function#ifs_all/ifs_ins/ifs_opts/ifs_outs.
|
491
|
+
# * TaLib::TAFunc.#hints
|
492
|
+
attr_reader :param_in, :param_opt, :param_out
|
493
|
+
|
494
|
+
private
|
495
|
+
#alias :in_int_orig :in_int
|
496
|
+
#alias :in_real_orig :in_real
|
497
|
+
#alias :in_price_orig :in_price
|
498
|
+
|
499
|
+
#alias :opt_int_orig :opt_int
|
500
|
+
#alias :opt_real_orig :opt_real
|
501
|
+
|
502
|
+
#alias :out_int_orig :out_int
|
503
|
+
#alias :out_real_orig :out_real
|
504
|
+
|
505
|
+
table_for_param.keys.each{|k|
|
506
|
+
table_for_param[k].each{|v|
|
507
|
+
unless self.method_defined?( "#{k}_#{v}_orig".to_sym )
|
508
|
+
then alias_method( "#{k}_#{v}_orig".to_sym, "#{k}_#{v}".to_sym )
|
509
|
+
else raise "Error in re-defining at #{self.to_s}:"+
|
510
|
+
" #{k}_#{v}_orig already exists!"
|
511
|
+
end
|
512
|
+
}
|
513
|
+
}
|
514
|
+
|
515
|
+
private
|
516
|
+
def __param_in_record( idx, val )
|
517
|
+
@param_in[idx] = {
|
518
|
+
val: val,
|
519
|
+
type: TaLib.input_types[ifs_ins[idx].type], }
|
520
|
+
end
|
521
|
+
def __param_opt_record( idx, val )
|
522
|
+
@param_opt[idx] = { val: val,
|
523
|
+
type: TaLib.optinput_types[ifs_opts[idx].type], }
|
524
|
+
end
|
525
|
+
def __param_out_record( idx, val )
|
526
|
+
@param_out[idx] = { val: val,
|
527
|
+
type: TaLib.output_types[ifs_outs[idx].type], }
|
528
|
+
end
|
529
|
+
|
530
|
+
public
|
531
|
+
##
|
532
|
+
# wrap the original {in,opt,out}_{int,real,price} to record values.
|
533
|
+
# For example,
|
534
|
+
# def in_real( idx, val )
|
535
|
+
# __in_param_record( idx, val )
|
536
|
+
# in_real_orig(idx, val)
|
537
|
+
# end
|
538
|
+
#
|
539
|
+
#
|
540
|
+
##
|
541
|
+
table_for_param.keys.each{|k|
|
542
|
+
table_for_param[k].each{|v|
|
543
|
+
if v == 'price'
|
544
|
+
then define_method( k+"_"+v ) {|idx,val|
|
545
|
+
# attention: val must be lvalue when out_*.
|
546
|
+
eval("__param_#{k}_record( idx, val )")
|
547
|
+
eval("#{k}_#{v}_orig(idx,"+
|
548
|
+
" val[:open], val[:high], val[:low], val[:close],"+
|
549
|
+
" val[:volume], val[:oi] )")
|
550
|
+
}
|
551
|
+
|
552
|
+
# real or int
|
553
|
+
else define_method( k+"_"+v ) {|idx,val|
|
554
|
+
# attention: val must be lvalue when out_*.
|
555
|
+
eval("__param_#{k}_record( idx, val )")
|
556
|
+
eval("#{k}_#{v}_orig(idx, val)")
|
557
|
+
}
|
558
|
+
end
|
559
|
+
}
|
560
|
+
}
|
561
|
+
|
562
|
+
####
|
563
|
+
public
|
564
|
+
# wrap Function#call to accept various kinds of args.
|
565
|
+
# ==== Args
|
566
|
+
# *r :: range of input array in several ways:
|
567
|
+
# no args: from pram_in_*
|
568
|
+
# m, n: direct indexes
|
569
|
+
# m..n: range object
|
570
|
+
# array: array
|
571
|
+
# ==== Return
|
572
|
+
# due to the function.
|
573
|
+
def call( *r )
|
574
|
+
m, n = nil, nil
|
575
|
+
|
576
|
+
# specifies m and n, simulation range in input data.
|
577
|
+
case
|
578
|
+
when r.size == 0 # no args.
|
579
|
+
raise "No setting of param_in_* for #{name}!" if @param_in[0].nil?
|
580
|
+
m, n = 0, @param_in[0][:val].size-1
|
581
|
+
when r.first.class == Range # Range is given.
|
582
|
+
m, n = r.first.first, r.first.last
|
583
|
+
when r.size == 2 # 2 indexes are given.
|
584
|
+
#puts "couple of index."
|
585
|
+
m, n = r.first, r.last
|
586
|
+
when r.first.class == Array # Array is given.
|
587
|
+
#puts "array."
|
588
|
+
self.param_in_real = r.first if @param_in[0].nil?
|
589
|
+
m, n = 0, r.first.size-1
|
590
|
+
else
|
591
|
+
raise "Strange args: #{r}! Should be in one of Nothing,"+
|
592
|
+
" two indexes, Array or Range."
|
593
|
+
end
|
594
|
+
|
595
|
+
#puts "idx: #{m}, #{n}"
|
596
|
+
param_size = case @param_in[0][:type]
|
597
|
+
when :TA_Input_Price
|
598
|
+
[ @param_in[0][:val][:open],
|
599
|
+
@param_in[0][:val][:high],
|
600
|
+
@param_in[0][:val][:low],
|
601
|
+
@param_in[0][:val][:close],
|
602
|
+
].map{|e| (e.nil?)? 0 : e.size }.max
|
603
|
+
when :TA_Input_Real
|
604
|
+
self.param_in_real.size
|
605
|
+
when :TA_Input_Integer
|
606
|
+
raise "Not yet implemented."
|
607
|
+
else
|
608
|
+
raise "Strange type for input parameter:"+
|
609
|
+
" #{@param_in[0][:type]}."
|
610
|
+
end
|
611
|
+
|
612
|
+
case
|
613
|
+
when m > n
|
614
|
+
raise "calculation range(#{m},#{n}) is currently not supported!"
|
615
|
+
when n >= param_size
|
616
|
+
raise "#{n} is too big!"+
|
617
|
+
" less than or equal to #{self.param_in_real.size-1}"
|
618
|
+
end
|
619
|
+
|
620
|
+
#
|
621
|
+
tmp = super( m, n )
|
622
|
+
ret = param_out_setting
|
623
|
+
ret.merge!( { :start_idx => tmp[0], :num_elements => tmp[1], } )
|
624
|
+
|
625
|
+
#
|
626
|
+
return ret
|
627
|
+
|
628
|
+
end
|
629
|
+
|
630
|
+
# auto prepare output arrays.
|
631
|
+
# ==== Requirements
|
632
|
+
# all in-parameters have already been set.
|
633
|
+
# ==== Args
|
634
|
+
# h :: output hash to be set.
|
635
|
+
# force_mode: :: force to create new array for output (default: false)
|
636
|
+
# ==== Return
|
637
|
+
# h :: { :output_parameter1 => [ nil, nil, ... ],
|
638
|
+
# :output_parameter2 => [ nil, nil, ... ], }
|
639
|
+
# ==== TODO
|
640
|
+
# * currently tested only MA, MACDEXT.
|
641
|
+
#
|
642
|
+
def param_out_setting( h = {}, force_mode: false )
|
643
|
+
|
644
|
+
|
645
|
+
# get output attributes (arrays to prepare).
|
646
|
+
tmp = self.param_attr( :out )
|
647
|
+
|
648
|
+
# prepare arrays and set them.
|
649
|
+
tmp.each{|a|
|
650
|
+
#
|
651
|
+
if force_mode or self.send( a ).nil?
|
652
|
+
then h[a] = Array.new( self.param_in_real.size )
|
653
|
+
self.send( (a.to_s+'=').to_sym, h[a] )
|
654
|
+
else h[a] = self.send( a ) # call getter.
|
655
|
+
end
|
656
|
+
}
|
657
|
+
|
658
|
+
return h
|
659
|
+
end
|
660
|
+
|
661
|
+
####
|
662
|
+
|
663
|
+
# Wrapper of the class method: hints.
|
664
|
+
# ==== See Also
|
665
|
+
# * self.hints
|
666
|
+
def hints( verbose: false, group: "all", function: name )
|
667
|
+
self.class.hints( verbose: verbose, group: group, function: function )
|
668
|
+
end
|
669
|
+
|
670
|
+
# self.hints provides the information about TA-Lib function.
|
671
|
+
# The information of them are extracted from talib library itself.
|
672
|
+
# ==== ATTENTION
|
673
|
+
# library (talib_ruby) must support TaLib::Function.{groups,functions}.
|
674
|
+
# ==== Args
|
675
|
+
# verbose: :: parameter name only when false, or entire structs when true.
|
676
|
+
# group: :: group name of functions.
|
677
|
+
# function: :: name of function.
|
678
|
+
# ==== Description
|
679
|
+
# * one of group or function should be specified.
|
680
|
+
# * these args can be String, Array of String, or "all"
|
681
|
+
# *
|
682
|
+
# ==== Return
|
683
|
+
#
|
684
|
+
def self.hints( verbose: false, group: "all", function: "all" )
|
685
|
+
group_list = nil
|
686
|
+
case
|
687
|
+
when group == "all"
|
688
|
+
group_list = self.groups
|
689
|
+
when group.class == String
|
690
|
+
group_list = [group]
|
691
|
+
when group.class == Array
|
692
|
+
group_list = group
|
693
|
+
else
|
694
|
+
raise "Type error #{group.class} for group!"+
|
695
|
+
" Please specify group in String or Array of String."
|
696
|
+
end
|
697
|
+
|
698
|
+
func_list = nil
|
699
|
+
tmp = self.functions
|
700
|
+
case
|
701
|
+
when function == "all"
|
702
|
+
func_list = tmp.values.flatten
|
703
|
+
when function.class == Array
|
704
|
+
func_list = function
|
705
|
+
group_list = []
|
706
|
+
func_list.each{|f|
|
707
|
+
group_list.push( tmp.keys.map{|e|
|
708
|
+
(tmp[e].grep(f).size>0)? e : nil }.compact )
|
709
|
+
}
|
710
|
+
group_list.flatten!
|
711
|
+
when function.class == String
|
712
|
+
func_list = [function]
|
713
|
+
group_list = tmp.keys.map{|e|
|
714
|
+
(tmp[e].grep(function).size>0)? e : nil
|
715
|
+
}.compact
|
716
|
+
else
|
717
|
+
end
|
718
|
+
|
719
|
+
#
|
720
|
+
group_list = group_list.sort.uniq
|
721
|
+
func_list = func_list.sort.uniq
|
722
|
+
#pp group_list
|
723
|
+
#pp func_list
|
724
|
+
|
725
|
+
#
|
726
|
+
group_list.each{|grp|
|
727
|
+
puts "==== #{grp} ===="
|
728
|
+
self.functions[grp].each{|func|
|
729
|
+
#puts func
|
730
|
+
if func_list.grep(func).size > 0
|
731
|
+
tmp = self.new(func)
|
732
|
+
|
733
|
+
puts "<#{func}>"
|
734
|
+
puts "inputs:"
|
735
|
+
if verbose
|
736
|
+
then pp tmp.ifs_ins
|
737
|
+
else tmp.ifs_ins.each{|e|
|
738
|
+
puts PPREFIX+e.param_name.underscore }
|
739
|
+
end
|
740
|
+
puts ""
|
741
|
+
|
742
|
+
puts "options:"
|
743
|
+
if verbose
|
744
|
+
then pp tmp.ifs_opts
|
745
|
+
else tmp.ifs_opts.each{|e|
|
746
|
+
puts PPREFIX+e.param_name.underscore }
|
747
|
+
end
|
748
|
+
puts ""
|
749
|
+
|
750
|
+
puts "outputs:"
|
751
|
+
if verbose
|
752
|
+
then pp tmp.ifs_outs
|
753
|
+
else tmp.ifs_outs.each{|e|
|
754
|
+
puts PPREFIX+e.param_name.underscore }
|
755
|
+
end
|
756
|
+
puts ""
|
757
|
+
|
758
|
+
puts ""
|
759
|
+
end
|
760
|
+
}
|
761
|
+
}
|
762
|
+
|
763
|
+
end
|
764
|
+
|
765
|
+
|
766
|
+
end
|
767
|
+
|
768
|
+
|
769
|
+
|
770
|
+
#### endof filename: tafunc.rb
|