sqa-tai 0.1.0 → 0.1.2
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/CHANGELOG.md +39 -0
- data/Gemfile.lock +1 -1
- data/README.md +30 -2
- data/Rakefile +69 -0
- data/lib/sqa/tai/cycle_indicators.rb +72 -0
- data/lib/sqa/tai/help/data.json +697 -0
- data/lib/sqa/tai/help/resource.rb +66 -0
- data/lib/sqa/tai/help.rb +41 -0
- data/lib/sqa/tai/momentum_indicators.rb +517 -0
- data/lib/sqa/tai/overlap_studies.rb +144 -0
- data/lib/sqa/tai/pattern_recognition.rb +684 -0
- data/lib/sqa/tai/price_transform.rb +64 -0
- data/lib/sqa/tai/statistical_functions.rb +122 -0
- data/lib/sqa/tai/version.rb +1 -1
- data/lib/sqa/tai/volatility_indicators.rb +179 -0
- data/lib/sqa/tai/volume_indicators.rb +54 -0
- data/lib/sqa/tai.rb +73 -1792
- data/mkdocs.yml +8 -10
- metadata +12 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb0c8beef02e005aa23c29fd805d7d68067f816286ccf41f747f9cdcf3dc7918
|
|
4
|
+
data.tar.gz: 485f49c5d3636dd5d4814f6c011fcd2b50848697ba1193faa3d0958ed155208f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f833ff859431d01643f78e7748ae6ff865886bc05f1ba29dedd498285698a191bf5101bc4abc20894adcfdd5cb245157bd5b9ca3a224bbca52be58470565d6f8
|
|
7
|
+
data.tar.gz: f3103d7e14e368cfbc134c93873bcae59144229a484459858460d89cec2cd058e5deaa127a7bb73fecfee2fcd73001383cffd070cde8386b367117ea1057378a
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
- Help system for accessing indicator documentation (`SQA::TAI.help`)
|
|
12
|
+
- Returns URLs to online documentation for any indicator
|
|
13
|
+
- Supports searching by name, filtering by category, and listing all indicators
|
|
14
|
+
- Auto-generated from mkdocs documentation files via `rake help:generate`
|
|
15
|
+
- Flexible API returns HelpResource objects with URL, name, and category
|
|
16
|
+
- Optional browser integration to open documentation directly
|
|
17
|
+
- Zeitwerk-compatible file structure with `help.rb` and `help_resource.rb`
|
|
18
|
+
|
|
19
|
+
## [0.1.1] 2025-11-13
|
|
20
|
+
### Added
|
|
21
|
+
- Intraday Momentum Index (IMI) indicator
|
|
22
|
+
- GitHub Actions workflow to automatically deploy documentation to GitHub Pages
|
|
23
|
+
- Indicator template markdown file for documentation
|
|
24
|
+
- Chronological ordering note to indicator documentation
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- Hash return format handling from newer ta_lib_ffi versions
|
|
28
|
+
- Image alignment and naming in README
|
|
29
|
+
- API reference documentation formatting and index links
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Refactored library code into modular structure with 8 focused modules organized by indicator category
|
|
33
|
+
- `lib/sqa/tai/overlap_studies.rb` - Moving averages and bands
|
|
34
|
+
- `lib/sqa/tai/momentum_indicators.rb` - Momentum and oscillator indicators
|
|
35
|
+
- `lib/sqa/tai/volatility_indicators.rb` - Volatility and range indicators
|
|
36
|
+
- `lib/sqa/tai/volume_indicators.rb` - Volume-based indicators
|
|
37
|
+
- `lib/sqa/tai/price_transform.rb` - Price transformation functions
|
|
38
|
+
- `lib/sqa/tai/cycle_indicators.rb` - Hilbert Transform cycle indicators
|
|
39
|
+
- `lib/sqa/tai/statistical_functions.rb` - Statistical analysis functions
|
|
40
|
+
- `lib/sqa/tai/pattern_recognition.rb` - Candlestick pattern recognition
|
|
41
|
+
- Refactored test suite to mirror lib directory organization with 8 modular test files
|
|
42
|
+
- Reduced main `lib/sqa/tai.rb` from 1,851 lines to 67 lines (96% reduction)
|
|
43
|
+
- Reduced main `test/sqa/tai_test.rb` to core tests only, extracted 72 tests into category-specific files
|
|
44
|
+
- Updated indicator count to 132
|
|
45
|
+
- Reorganized README sections
|
|
46
|
+
- Improved SQA name from "Stock Qualitative Analysis" to "Simple Qualitative Analysis"
|
|
47
|
+
- Updated gemspec description
|
|
48
|
+
|
|
10
49
|
## [0.1.0] - 2025-11-06
|
|
11
50
|
|
|
12
51
|
### Added
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
<table>
|
|
9
9
|
<tr>
|
|
10
|
-
<td width="30%" valign="
|
|
11
|
-
<img src="docs/assets/images/sqa
|
|
10
|
+
<td width="30%" valign="middle" align="center">
|
|
11
|
+
<img src="docs/assets/images/sqa.jpg" alt="Ruby Turns Information into Knowledge" width="80%">
|
|
12
12
|
<br/>
|
|
13
13
|
</td>
|
|
14
14
|
<td width="70%" valign="top">
|
|
@@ -86,6 +86,34 @@ if SQA::TAI.available?
|
|
|
86
86
|
end
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
## Getting Help on Indicators
|
|
90
|
+
|
|
91
|
+
Access comprehensive documentation for any indicator directly from your code:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
# Get documentation URL for an indicator
|
|
95
|
+
help = SQA::TAI.help(:sma)
|
|
96
|
+
puts help.url
|
|
97
|
+
# => https://madbomber.github.io/sqa-tai/indicators/overlap/sma/
|
|
98
|
+
|
|
99
|
+
# Open documentation in browser
|
|
100
|
+
SQA::TAI.help(:rsi, open: true)
|
|
101
|
+
|
|
102
|
+
# Search for indicators
|
|
103
|
+
SQA::TAI.help(search: "momentum")
|
|
104
|
+
# => {mom: "https://...", cmo: "https://...", ...}
|
|
105
|
+
|
|
106
|
+
# List all indicators in a category
|
|
107
|
+
SQA::TAI.help(category: :momentum_indicators)
|
|
108
|
+
# => {rsi: "https://...", macd: "https://...", ...}
|
|
109
|
+
|
|
110
|
+
# Get all available indicators
|
|
111
|
+
SQA::TAI.help(:all)
|
|
112
|
+
# => {sma: "https://...", ema: "https://...", ...}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
See the [Help System Guide](https://madbomber.github.io/sqa-tai/getting-started/help/) for more details.
|
|
116
|
+
|
|
89
117
|
## Available Indicators (136 Total)
|
|
90
118
|
|
|
91
119
|
### Overlap Studies (15)
|
data/Rakefile
CHANGED
|
@@ -11,3 +11,72 @@ Rake::TestTask.new(:test) do |t|
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
task default: :test
|
|
14
|
+
|
|
15
|
+
namespace :help do
|
|
16
|
+
desc "Generate help mappings from documentation files"
|
|
17
|
+
task :generate do
|
|
18
|
+
require "fileutils"
|
|
19
|
+
|
|
20
|
+
indicators = {}
|
|
21
|
+
category_mapping = {
|
|
22
|
+
"overlap" => :overlap_studies,
|
|
23
|
+
"momentum" => :momentum_indicators,
|
|
24
|
+
"volatility" => :volatility_indicators,
|
|
25
|
+
"volume" => :volume_indicators,
|
|
26
|
+
"price_transform" => :price_transform,
|
|
27
|
+
"statistical" => :statistical_functions,
|
|
28
|
+
"cycle" => :cycle_indicators,
|
|
29
|
+
"patterns" => :pattern_recognition
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Scan docs directory
|
|
33
|
+
Dir.glob("docs/indicators/**/*.md").sort.each do |file|
|
|
34
|
+
next if file.include?("index.md")
|
|
35
|
+
|
|
36
|
+
# Extract indicator name from filename
|
|
37
|
+
indicator = File.basename(file, ".md").to_sym
|
|
38
|
+
|
|
39
|
+
# Extract category from path
|
|
40
|
+
path_category = File.dirname(file).split("/").last
|
|
41
|
+
category = category_mapping[path_category] || path_category.to_sym
|
|
42
|
+
|
|
43
|
+
# Read first heading for name
|
|
44
|
+
name = nil
|
|
45
|
+
File.open(file, "r") do |f|
|
|
46
|
+
f.each_line do |line|
|
|
47
|
+
if line.start_with?("# ")
|
|
48
|
+
name = line.gsub(/^#\s*/, "").strip
|
|
49
|
+
# Remove content after parentheses if present
|
|
50
|
+
name = name.split("(").first.strip if name.include?("(")
|
|
51
|
+
break
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Build path relative to docs/
|
|
57
|
+
path = file.gsub("docs/", "").gsub(".md", "")
|
|
58
|
+
|
|
59
|
+
indicators[indicator] = {
|
|
60
|
+
name: name || indicator.to_s.upcase,
|
|
61
|
+
category: category,
|
|
62
|
+
path: path
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Convert to JSON-friendly format (strings instead of symbols)
|
|
67
|
+
json_data = indicators.transform_keys(&:to_s).transform_values do |meta|
|
|
68
|
+
{
|
|
69
|
+
"name" => meta[:name],
|
|
70
|
+
"category" => meta[:category].to_s,
|
|
71
|
+
"path" => meta[:path]
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Write to JSON file
|
|
76
|
+
require "json"
|
|
77
|
+
json_output = JSON.pretty_generate(json_data)
|
|
78
|
+
File.write("lib/sqa/tai/help/data.json", json_output)
|
|
79
|
+
puts "✓ Generated help data for #{indicators.size} indicators"
|
|
80
|
+
puts " File: lib/sqa/tai/help/data.json"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SQA
|
|
4
|
+
module TAI
|
|
5
|
+
# Cycle Indicators
|
|
6
|
+
module CycleIndicators
|
|
7
|
+
# Hilbert Transform - Dominant Cycle Period
|
|
8
|
+
# @param prices [Array<Float>] Array of prices
|
|
9
|
+
# @return [Array<Float>] Dominant cycle period values
|
|
10
|
+
def ht_dcperiod(prices)
|
|
11
|
+
check_available!
|
|
12
|
+
validate_prices!(prices)
|
|
13
|
+
|
|
14
|
+
TALibFFI.ht_dcperiod(prices)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Hilbert Transform - Trend vs Cycle Mode
|
|
18
|
+
# @param prices [Array<Float>] Array of prices
|
|
19
|
+
# @return [Array<Integer>] Trend mode (1) or cycle mode (0)
|
|
20
|
+
def ht_trendmode(prices)
|
|
21
|
+
check_available!
|
|
22
|
+
validate_prices!(prices)
|
|
23
|
+
|
|
24
|
+
TALibFFI.ht_trendmode(prices)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Hilbert Transform - Dominant Cycle Phase
|
|
28
|
+
# @param prices [Array<Float>] Array of prices
|
|
29
|
+
# @return [Array<Float>] Dominant cycle phase values
|
|
30
|
+
def ht_dcphase(prices)
|
|
31
|
+
check_available!
|
|
32
|
+
validate_prices!(prices)
|
|
33
|
+
|
|
34
|
+
TALibFFI.ht_dcphase(prices)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Hilbert Transform - Phasor Components
|
|
38
|
+
# @param prices [Array<Float>] Array of prices
|
|
39
|
+
# @return [Array<Array<Float>>] [inphase, quadrature]
|
|
40
|
+
def ht_phasor(prices)
|
|
41
|
+
check_available!
|
|
42
|
+
validate_prices!(prices)
|
|
43
|
+
|
|
44
|
+
result = TALibFFI.ht_phasor(prices)
|
|
45
|
+
|
|
46
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
47
|
+
if result.is_a?(Hash)
|
|
48
|
+
[result[:in_phase], result[:quadrature]]
|
|
49
|
+
else
|
|
50
|
+
result
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Hilbert Transform - SineWave
|
|
55
|
+
# @param prices [Array<Float>] Array of prices
|
|
56
|
+
# @return [Array<Array<Float>>] [sine, lead_sine]
|
|
57
|
+
def ht_sine(prices)
|
|
58
|
+
check_available!
|
|
59
|
+
validate_prices!(prices)
|
|
60
|
+
|
|
61
|
+
result = TALibFFI.ht_sine(prices)
|
|
62
|
+
|
|
63
|
+
# Handle hash return format from newer ta_lib_ffi versions
|
|
64
|
+
if result.is_a?(Hash)
|
|
65
|
+
[result[:sine], result[:lead_sine]]
|
|
66
|
+
else
|
|
67
|
+
result
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|