sqa 0.0.32 → 0.0.38
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 +154 -1
- data/README.md +4 -0
- data/Rakefile +52 -10
- data/docs/advanced/index.md +1 -13
- data/docs/api/index.md +547 -61
- data/docs/api-reference/alphavantageapi.md +1057 -0
- data/docs/api-reference/apierror.md +31 -0
- data/docs/api-reference/index.md +221 -0
- data/docs/api-reference/notimplemented.md +27 -0
- data/docs/api-reference/sqa.md +267 -0
- data/docs/api-reference/sqa_backtest.md +171 -0
- data/docs/api-reference/sqa_backtest_results.md +530 -0
- data/docs/api-reference/sqa_badparametererror.md +13 -0
- data/docs/api-reference/sqa_config.md +538 -0
- data/docs/api-reference/sqa_configurationerror.md +13 -0
- data/docs/api-reference/sqa_datafetcherror.md +56 -0
- data/docs/api-reference/sqa_dataframe.md +779 -0
- data/docs/api-reference/sqa_dataframe_alphavantage.md +30 -0
- data/docs/api-reference/sqa_dataframe_data.md +325 -0
- data/docs/api-reference/sqa_dataframe_yahoofinance.md +25 -0
- data/docs/api-reference/sqa_ensemble.md +413 -0
- data/docs/api-reference/sqa_fpop.md +211 -0
- data/docs/api-reference/sqa_geneticprogram.md +325 -0
- data/docs/api-reference/sqa_geneticprogram_individual.md +114 -0
- data/docs/api-reference/sqa_marketregime.md +212 -0
- data/docs/api-reference/sqa_multitimeframe.md +227 -0
- data/docs/api-reference/sqa_patternmatcher.md +195 -0
- data/docs/api-reference/sqa_pluginmanager.md +55 -0
- data/docs/api-reference/sqa_portfolio.md +512 -0
- data/docs/api-reference/sqa_portfolio_position.md +220 -0
- data/docs/api-reference/sqa_portfolio_trade.md +332 -0
- data/docs/api-reference/sqa_portfoliooptimizer.md +248 -0
- data/docs/api-reference/sqa_riskmanager.md +388 -0
- data/docs/api-reference/sqa_seasonalanalyzer.md +121 -0
- data/docs/api-reference/sqa_sectoranalyzer.md +163 -0
- data/docs/api-reference/sqa_stock.md +661 -0
- data/docs/api-reference/sqa_strategy.md +178 -0
- data/docs/api-reference/sqa_strategy_bollingerbands.md +26 -0
- data/docs/api-reference/sqa_strategy_common.md +29 -0
- data/docs/api-reference/sqa_strategy_consensus.md +129 -0
- data/docs/api-reference/sqa_strategy_ema.md +41 -0
- data/docs/api-reference/sqa_strategy_kbs.md +154 -0
- data/docs/api-reference/sqa_strategy_macd.md +26 -0
- data/docs/api-reference/sqa_strategy_mp.md +41 -0
- data/docs/api-reference/sqa_strategy_mr.md +41 -0
- data/docs/api-reference/sqa_strategy_random.md +41 -0
- data/docs/api-reference/sqa_strategy_rsi.md +41 -0
- data/docs/api-reference/sqa_strategy_sma.md +41 -0
- data/docs/api-reference/sqa_strategy_stochastic.md +26 -0
- data/docs/api-reference/sqa_strategy_volumebreakout.md +26 -0
- data/docs/api-reference/sqa_strategygenerator.md +298 -0
- data/docs/api-reference/sqa_strategygenerator_pattern.md +264 -0
- data/docs/api-reference/sqa_strategygenerator_patterncontext.md +326 -0
- data/docs/api-reference/sqa_strategygenerator_profitablepoint.md +424 -0
- data/docs/api-reference/sqa_stream.md +256 -0
- data/docs/api-reference/sqa_ticker.md +175 -0
- data/docs/api-reference/string.md +135 -0
- data/docs/assets/images/advanced-workflow.svg +89 -0
- data/docs/assets/images/architecture.svg +107 -0
- data/docs/assets/images/data-flow.svg +138 -0
- data/docs/assets/images/getting-started-workflow.svg +88 -0
- data/docs/assets/images/strategy-flow.svg +78 -0
- data/docs/assets/images/system-architecture.svg +150 -0
- data/docs/concepts/index.md +292 -19
- data/docs/file_formats.md +250 -0
- data/docs/getting-started/index.md +1 -14
- data/docs/index.md +26 -23
- data/docs/llms.txt +109 -0
- data/docs/strategies/kbs.md +15 -14
- data/docs/strategy.md +381 -3
- data/docs/terms_of_use.md +1 -1
- data/examples/README.md +10 -0
- data/lib/api/alpha_vantage_api.rb +3 -7
- data/lib/sqa/backtest.rb +32 -0
- data/lib/sqa/config.rb +109 -28
- data/lib/sqa/data_frame/data.rb +13 -1
- data/lib/sqa/data_frame.rb +193 -26
- data/lib/sqa/errors.rb +79 -17
- data/lib/sqa/init.rb +70 -15
- data/lib/sqa/pattern_matcher.rb +4 -4
- data/lib/sqa/portfolio.rb +55 -1
- data/lib/sqa/sector_analyzer.rb +3 -11
- data/lib/sqa/stock.rb +180 -15
- data/lib/sqa/strategy.rb +62 -4
- data/lib/sqa/ticker.rb +106 -48
- data/lib/sqa/version.rb +1 -1
- data/lib/sqa.rb +4 -4
- data/mkdocs.yml +69 -81
- metadata +89 -21
- data/docs/README.md +0 -43
- data/examples/sinatra_app/Gemfile +0 -42
- data/examples/sinatra_app/Gemfile.lock +0 -268
- data/examples/sinatra_app/QUICKSTART.md +0 -169
- data/examples/sinatra_app/README.md +0 -471
- data/examples/sinatra_app/RUNNING_WITHOUT_TALIB.md +0 -90
- data/examples/sinatra_app/TROUBLESHOOTING.md +0 -95
- data/examples/sinatra_app/app.rb +0 -404
- data/examples/sinatra_app/config.ru +0 -5
- data/examples/sinatra_app/public/css/style.css +0 -723
- data/examples/sinatra_app/public/debug_macd.html +0 -82
- data/examples/sinatra_app/public/js/app.js +0 -107
- data/examples/sinatra_app/start.sh +0 -53
- data/examples/sinatra_app/views/analyze.erb +0 -306
- data/examples/sinatra_app/views/backtest.erb +0 -325
- data/examples/sinatra_app/views/dashboard.erb +0 -831
- data/examples/sinatra_app/views/error.erb +0 -58
- data/examples/sinatra_app/views/index.erb +0 -118
- data/examples/sinatra_app/views/layout.erb +0 -61
- data/examples/sinatra_app/views/portfolio.erb +0 -43
data/lib/sqa/ticker.rb
CHANGED
|
@@ -1,75 +1,133 @@
|
|
|
1
1
|
# sqa/lib/sqa/ticker.rb
|
|
2
2
|
#
|
|
3
|
-
#
|
|
3
|
+
# Stock ticker symbol validation and lookup using the dumbstockapi.com service.
|
|
4
|
+
# Downloads and caches a CSV file containing ticker symbols, company names, and exchanges.
|
|
4
5
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
6
|
+
# @example Validating a ticker
|
|
7
|
+
# SQA::Ticker.valid?('AAPL') # => true
|
|
8
|
+
# SQA::Ticker.valid?('FAKE') # => false
|
|
7
9
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
10
|
+
# @example Looking up ticker info
|
|
11
|
+
# info = SQA::Ticker.lookup('AAPL')
|
|
12
|
+
# info[:name] # => "Apple Inc"
|
|
13
|
+
# info[:exchange] # => "NASDAQ"
|
|
12
14
|
#
|
|
13
15
|
class SQA::Ticker
|
|
16
|
+
# @return [String] Prefix for downloaded CSV filenames
|
|
14
17
|
FILENAME_PREFIX = "dumbstockapi"
|
|
18
|
+
|
|
19
|
+
# @return [Faraday::Connection] Connection to dumbstockapi.com
|
|
15
20
|
CONNECTION = Faraday.new(url: "https://dumbstockapi.com")
|
|
16
|
-
@@data = {}
|
|
17
21
|
|
|
22
|
+
class << self
|
|
23
|
+
# Downloads ticker data from dumbstockapi.com and saves to data directory.
|
|
24
|
+
#
|
|
25
|
+
# @param country [String] Country code for ticker list (default: "US")
|
|
26
|
+
# @return [Integer] HTTP status code from the download request
|
|
27
|
+
#
|
|
28
|
+
# @example
|
|
29
|
+
# SQA::Ticker.download("US") # => 200
|
|
30
|
+
#
|
|
31
|
+
def download(country="US")
|
|
32
|
+
response = CONNECTION.get("/stock?format=csv&countries=#{country.upcase}").to_hash
|
|
18
33
|
|
|
19
|
-
|
|
20
|
-
|
|
34
|
+
if 200 == response[:status]
|
|
35
|
+
filename = response[:response_headers]["content-disposition"].split('=').last.gsub('"','')
|
|
36
|
+
out_path = Pathname.new(SQA.config.data_dir) + filename
|
|
37
|
+
out_path.write response[:body]
|
|
38
|
+
end
|
|
21
39
|
|
|
22
|
-
|
|
23
|
-
filename = response[:response_headers]["content-disposition"].split('=').last.gsub('"','')
|
|
24
|
-
out_path = Pathname.new(SQA.config.data_dir) + filename
|
|
25
|
-
out_path.write response[:body]
|
|
40
|
+
response[:status]
|
|
26
41
|
end
|
|
27
42
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
# Loads ticker data from cached CSV or downloads if not available.
|
|
44
|
+
# Retries download up to 3 times if no cached file exists.
|
|
45
|
+
#
|
|
46
|
+
# @return [Hash{String => Hash}] Hash mapping ticker symbols to info hashes
|
|
47
|
+
def load
|
|
48
|
+
tries = 0
|
|
49
|
+
found = false
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
51
|
+
until(found || tries >= 3) do
|
|
52
|
+
files = Pathname.new(SQA.config.data_dir).children.select{|c| c.basename.to_s.start_with?(FILENAME_PREFIX)}.sort
|
|
53
|
+
if files.empty?
|
|
54
|
+
begin
|
|
55
|
+
download
|
|
56
|
+
rescue StandardError => e
|
|
57
|
+
warn "Warning: Could not download ticker list: #{e.message}" if $VERBOSE
|
|
58
|
+
end
|
|
59
|
+
tries += 1
|
|
60
|
+
else
|
|
61
|
+
found = true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
35
64
|
|
|
36
|
-
until(found || tries >= 3) do
|
|
37
|
-
files = Pathname.new(SQA.config.data_dir).children.select{|c| c.basename.to_s.start_with?(FILENAME_PREFIX)}.sort
|
|
38
65
|
if files.empty?
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
rescue => e
|
|
42
|
-
warn "Warning: Could not download ticker list: #{e.message}" if $VERBOSE
|
|
43
|
-
end
|
|
44
|
-
tries += 1
|
|
45
|
-
else
|
|
46
|
-
found = true
|
|
66
|
+
warn "Warning: No ticker validation data available. Proceeding without validation." if $VERBOSE
|
|
67
|
+
return {}
|
|
47
68
|
end
|
|
48
|
-
end
|
|
49
69
|
|
|
50
|
-
|
|
51
|
-
warn "Warning: No ticker validation data available. Proceeding without validation." if $VERBOSE
|
|
52
|
-
return {}
|
|
70
|
+
load_from_csv files.last
|
|
53
71
|
end
|
|
54
72
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
# Loads ticker data from a specific CSV file.
|
|
74
|
+
#
|
|
75
|
+
# @param csv_path [Pathname, String] Path to CSV file
|
|
76
|
+
# @return [Hash{String => Hash}] Hash mapping ticker symbols to info hashes
|
|
77
|
+
def load_from_csv(csv_path)
|
|
78
|
+
@data ||= {}
|
|
79
|
+
CSV.foreach(csv_path, headers: true) do |row|
|
|
80
|
+
@data[row["ticker"]] = {
|
|
81
|
+
name: row["name"],
|
|
82
|
+
exchange: row["exchange"]
|
|
83
|
+
}
|
|
84
|
+
end
|
|
58
85
|
|
|
59
|
-
|
|
60
|
-
CSV.foreach(csv_path, headers: true) do |row|
|
|
61
|
-
@@data[row["ticker"]] = {
|
|
62
|
-
name: row["name"],
|
|
63
|
-
exchange: row["exchange"]
|
|
64
|
-
}
|
|
86
|
+
@data
|
|
65
87
|
end
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
# Returns the cached ticker data, loading it if necessary.
|
|
90
|
+
#
|
|
91
|
+
# @return [Hash{String => Hash}] Hash mapping ticker symbols to info hashes
|
|
92
|
+
def data
|
|
93
|
+
@data ||= {}
|
|
94
|
+
@data.empty? ? load : @data
|
|
95
|
+
end
|
|
69
96
|
|
|
97
|
+
# Looks up information for a specific ticker symbol.
|
|
98
|
+
#
|
|
99
|
+
# @param ticker [String, nil] Ticker symbol to look up
|
|
100
|
+
# @return [Hash, nil] Hash with :name and :exchange keys, or nil if not found
|
|
101
|
+
#
|
|
102
|
+
# @example
|
|
103
|
+
# SQA::Ticker.lookup('AAPL') # => { name: "Apple Inc", exchange: "NASDAQ" }
|
|
104
|
+
# SQA::Ticker.lookup('FAKE') # => nil
|
|
105
|
+
#
|
|
106
|
+
def lookup(ticker)
|
|
107
|
+
return nil if ticker.nil? || ticker.to_s.empty?
|
|
108
|
+
data[ticker.to_s.upcase]
|
|
109
|
+
end
|
|
70
110
|
|
|
111
|
+
# Checks if a ticker symbol is valid (exists in the data).
|
|
112
|
+
#
|
|
113
|
+
# @param ticker [String, nil] Ticker symbol to validate
|
|
114
|
+
# @return [Boolean] true if ticker exists, false otherwise
|
|
115
|
+
#
|
|
116
|
+
# @example
|
|
117
|
+
# SQA::Ticker.valid?('AAPL') # => true
|
|
118
|
+
# SQA::Ticker.valid?(nil) # => false
|
|
119
|
+
#
|
|
120
|
+
def valid?(ticker)
|
|
121
|
+
return false if ticker.nil? || ticker.to_s.empty?
|
|
122
|
+
data.key?(ticker.to_s.upcase)
|
|
123
|
+
end
|
|
71
124
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
125
|
+
# Resets the cached ticker data.
|
|
126
|
+
# Useful for testing to force a fresh load.
|
|
127
|
+
#
|
|
128
|
+
# @return [Hash] Empty hash
|
|
129
|
+
def reset!
|
|
130
|
+
@data = {}
|
|
131
|
+
end
|
|
132
|
+
end
|
|
75
133
|
end
|
data/lib/sqa/version.rb
CHANGED
data/lib/sqa.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# lib/sqa.rb
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
#
|
|
4
|
+
# NOTE: The dumbstockapi integration is handled by SQA::Ticker class.
|
|
5
|
+
# A separate gem could be created if more extensive API coverage is needed.
|
|
5
6
|
|
|
6
7
|
#############################################
|
|
7
8
|
## Standard Libraries
|
|
@@ -13,9 +14,8 @@ unless defined?(HOME)
|
|
|
13
14
|
HOME = Pathname.new(ENV['HOME'])
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
17
|
+
# NOTE: debug_me is optional - loaded if available, otherwise a no-op is defined.
|
|
18
|
+
# This keeps it as a development dependency while allowing production use if installed.
|
|
19
19
|
if defined?(DebugMe)
|
|
20
20
|
unless respond_to?(:debug_me)
|
|
21
21
|
include DebugMe
|
data/mkdocs.yml
CHANGED
|
@@ -3,7 +3,7 @@ site_name: SQA - Simple Qualitative Analysis
|
|
|
3
3
|
site_description: A powerful Ruby library for stock market technical analysis and trading strategy development
|
|
4
4
|
site_author: Dewayne VanHoozer
|
|
5
5
|
site_url: https://madbomber.github.io/sqa
|
|
6
|
-
copyright: Copyright ©
|
|
6
|
+
copyright: Copyright © 2025 Dewayne VanHoozer (CAUTION! This documentation was mostly written by a robot so it might be wrong.)
|
|
7
7
|
|
|
8
8
|
# Repository information
|
|
9
9
|
repo_name: madbomber/sqa
|
|
@@ -56,7 +56,6 @@ theme:
|
|
|
56
56
|
|
|
57
57
|
# Table of contents
|
|
58
58
|
- toc.follow
|
|
59
|
-
- toc.integrate
|
|
60
59
|
|
|
61
60
|
# Search
|
|
62
61
|
- search.suggest
|
|
@@ -74,15 +73,11 @@ theme:
|
|
|
74
73
|
- content.action.edit
|
|
75
74
|
- content.action.view
|
|
76
75
|
|
|
77
|
-
# Announce
|
|
78
|
-
- announce.dismiss
|
|
79
|
-
|
|
80
76
|
# Plugins
|
|
81
77
|
plugins:
|
|
82
78
|
- search:
|
|
83
79
|
separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
|
|
84
|
-
- tags
|
|
85
|
-
tags_file: tags.md
|
|
80
|
+
- tags
|
|
86
81
|
|
|
87
82
|
# Extensions
|
|
88
83
|
markdown_extensions:
|
|
@@ -97,7 +92,6 @@ markdown_extensions:
|
|
|
97
92
|
- toc:
|
|
98
93
|
permalink: true
|
|
99
94
|
title: On this page
|
|
100
|
-
toc_depth: 3
|
|
101
95
|
|
|
102
96
|
# Python Markdown Extensions
|
|
103
97
|
- pymdownx.arithmatex:
|
|
@@ -154,9 +148,6 @@ extra:
|
|
|
154
148
|
link: https://rubygems.org/gems/sqa
|
|
155
149
|
name: SQA on RubyGems
|
|
156
150
|
|
|
157
|
-
version:
|
|
158
|
-
provider: mike
|
|
159
|
-
|
|
160
151
|
analytics:
|
|
161
152
|
feedback:
|
|
162
153
|
title: Was this page helpful?
|
|
@@ -175,78 +166,75 @@ extra:
|
|
|
175
166
|
# Navigation
|
|
176
167
|
nav:
|
|
177
168
|
- Home: index.md
|
|
169
|
+
|
|
178
170
|
- Getting Started:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
171
|
+
- Overview: getting-started/index.md
|
|
172
|
+
- Installation: getting-started/installation.md
|
|
173
|
+
- Quick Start: getting-started/quick-start.md
|
|
174
|
+
|
|
175
|
+
- User Guide:
|
|
176
|
+
- Core Concepts:
|
|
177
|
+
- Overview: concepts/index.md
|
|
178
|
+
- DataFrames: data_frame.md
|
|
179
|
+
- Trading Strategies: strategy.md
|
|
180
|
+
- File Formats: file_formats.md
|
|
181
|
+
- Technical Indicators:
|
|
182
|
+
- Overview: indicators/index.md
|
|
183
|
+
- Indicator Details: indicators.md
|
|
184
|
+
- sqa-tai Gem: https://github.com/MadBomber/sqa-tai
|
|
185
|
+
- TA-Lib Documentation: https://ta-lib.org/
|
|
186
|
+
- Trading Strategies:
|
|
187
|
+
- Overview: strategies/index.md
|
|
188
|
+
- Built-in Strategies:
|
|
189
|
+
- Bollinger Bands: strategies/bollinger-bands.md
|
|
190
|
+
- RSI Strategy: strategies/rsi.md
|
|
191
|
+
- MACD Strategy: strategies/macd.md
|
|
192
|
+
- SMA Strategy: strategies/sma.md
|
|
193
|
+
- EMA Strategy: strategies/ema.md
|
|
194
|
+
- Stochastic: strategies/stochastic.md
|
|
195
|
+
- Volume Breakout: strategies/volume-breakout.md
|
|
196
|
+
- Mean Reversion: strategies/mean-reversion.md
|
|
197
|
+
- Market Profile: strategies/market-profile.md
|
|
198
|
+
- Consensus: strategies/consensus.md
|
|
199
|
+
- Advanced Strategies:
|
|
200
|
+
- KBS Strategy: strategies/kbs.md
|
|
201
|
+
- Custom Strategies: strategies/custom.md
|
|
202
|
+
- Data Sources:
|
|
203
|
+
- Overview: data-sources/index.md
|
|
204
|
+
|
|
205
|
+
- Advanced:
|
|
206
|
+
- Overview: advanced/index.md
|
|
207
|
+
- Portfolio Management: advanced/portfolio.md
|
|
208
|
+
- Backtesting: advanced/backtesting.md
|
|
209
|
+
- Strategy Generator: advanced/strategy-generator.md
|
|
210
|
+
- Genetic Programming: genetic_programming.md
|
|
211
|
+
- Real-Time Streaming: advanced/streaming.md
|
|
212
|
+
- FPOP Analysis: advanced/fpop.md
|
|
213
|
+
- Risk Management: advanced/risk-management.md
|
|
214
|
+
- Portfolio Optimizer: advanced/portfolio-optimizer.md
|
|
215
|
+
- Ensemble Strategies: advanced/ensemble.md
|
|
216
|
+
- Multi-Timeframe: advanced/multi-timeframe.md
|
|
217
|
+
- Pattern Matcher: advanced/pattern-matcher.md
|
|
218
|
+
- AI & Machine Learning:
|
|
219
|
+
- Overview: ai_and_ml.md
|
|
220
|
+
- Mean Reversion: mean_reversion.md
|
|
221
|
+
- Predict Next Value: predict_next_value.md
|
|
222
|
+
- Wave Condition: identify_wave_condition.md
|
|
223
|
+
- LIBSVM Format: libsvm_file_format.md
|
|
232
224
|
|
|
233
225
|
- API Reference:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- Data Sources:
|
|
238
|
-
- data-sources/index.md
|
|
226
|
+
- Overview: api/index.md
|
|
227
|
+
- DataFrame Class: api/dataframe.md
|
|
228
|
+
- Complete API Reference: api-reference/index.md
|
|
239
229
|
|
|
240
230
|
- Resources:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
- Contributing:
|
|
252
|
-
- contributing/index.md
|
|
231
|
+
- Tags: tags.md
|
|
232
|
+
- Requirements: requirements.md
|
|
233
|
+
- Terms of Use: terms_of_use.md
|
|
234
|
+
- Trading Ideas: i_gotta_an_idea.md
|
|
235
|
+
- Factor Analysis: factors_that_impact_price.md
|
|
236
|
+
- External Tools:
|
|
237
|
+
- FinViz: finviz.md
|
|
238
|
+
- FX Pro Bit: fx_pro_bit.md
|
|
239
|
+
- Options Trading: options.md
|
|
240
|
+
- Contributing: contributing/index.md
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sqa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.38
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -345,6 +345,34 @@ dependencies:
|
|
|
345
345
|
- - ">="
|
|
346
346
|
- !ruby/object:Gem::Version
|
|
347
347
|
version: '0'
|
|
348
|
+
- !ruby/object:Gem::Dependency
|
|
349
|
+
name: yard
|
|
350
|
+
requirement: !ruby/object:Gem::Requirement
|
|
351
|
+
requirements:
|
|
352
|
+
- - ">="
|
|
353
|
+
- !ruby/object:Gem::Version
|
|
354
|
+
version: '0'
|
|
355
|
+
type: :development
|
|
356
|
+
prerelease: false
|
|
357
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
358
|
+
requirements:
|
|
359
|
+
- - ">="
|
|
360
|
+
- !ruby/object:Gem::Version
|
|
361
|
+
version: '0'
|
|
362
|
+
- !ruby/object:Gem::Dependency
|
|
363
|
+
name: yard-markdown
|
|
364
|
+
requirement: !ruby/object:Gem::Requirement
|
|
365
|
+
requirements:
|
|
366
|
+
- - ">="
|
|
367
|
+
- !ruby/object:Gem::Version
|
|
368
|
+
version: '0'
|
|
369
|
+
type: :development
|
|
370
|
+
prerelease: false
|
|
371
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
372
|
+
requirements:
|
|
373
|
+
- - ">="
|
|
374
|
+
- !ruby/object:Gem::Version
|
|
375
|
+
version: '0'
|
|
348
376
|
description: |
|
|
349
377
|
Simplistic playpen (e.g. not for serious use) for doing
|
|
350
378
|
technical analysis of stock prices. Under Construction.
|
|
@@ -398,7 +426,6 @@ files:
|
|
|
398
426
|
- data/talk_talk.json
|
|
399
427
|
- develop_summary.md
|
|
400
428
|
- docs/.gitignore
|
|
401
|
-
- docs/README.md
|
|
402
429
|
- docs/advanced/backtesting.md
|
|
403
430
|
- docs/advanced/ensemble.md
|
|
404
431
|
- docs/advanced/fpop.md
|
|
@@ -411,16 +438,75 @@ files:
|
|
|
411
438
|
- docs/advanced/strategy-generator.md
|
|
412
439
|
- docs/advanced/streaming.md
|
|
413
440
|
- docs/ai_and_ml.md
|
|
441
|
+
- docs/api-reference/alphavantageapi.md
|
|
442
|
+
- docs/api-reference/apierror.md
|
|
443
|
+
- docs/api-reference/index.md
|
|
444
|
+
- docs/api-reference/notimplemented.md
|
|
445
|
+
- docs/api-reference/sqa.md
|
|
446
|
+
- docs/api-reference/sqa_backtest.md
|
|
447
|
+
- docs/api-reference/sqa_backtest_results.md
|
|
448
|
+
- docs/api-reference/sqa_badparametererror.md
|
|
449
|
+
- docs/api-reference/sqa_config.md
|
|
450
|
+
- docs/api-reference/sqa_configurationerror.md
|
|
451
|
+
- docs/api-reference/sqa_datafetcherror.md
|
|
452
|
+
- docs/api-reference/sqa_dataframe.md
|
|
453
|
+
- docs/api-reference/sqa_dataframe_alphavantage.md
|
|
454
|
+
- docs/api-reference/sqa_dataframe_data.md
|
|
455
|
+
- docs/api-reference/sqa_dataframe_yahoofinance.md
|
|
456
|
+
- docs/api-reference/sqa_ensemble.md
|
|
457
|
+
- docs/api-reference/sqa_fpop.md
|
|
458
|
+
- docs/api-reference/sqa_geneticprogram.md
|
|
459
|
+
- docs/api-reference/sqa_geneticprogram_individual.md
|
|
460
|
+
- docs/api-reference/sqa_marketregime.md
|
|
461
|
+
- docs/api-reference/sqa_multitimeframe.md
|
|
462
|
+
- docs/api-reference/sqa_patternmatcher.md
|
|
463
|
+
- docs/api-reference/sqa_pluginmanager.md
|
|
464
|
+
- docs/api-reference/sqa_portfolio.md
|
|
465
|
+
- docs/api-reference/sqa_portfolio_position.md
|
|
466
|
+
- docs/api-reference/sqa_portfolio_trade.md
|
|
467
|
+
- docs/api-reference/sqa_portfoliooptimizer.md
|
|
468
|
+
- docs/api-reference/sqa_riskmanager.md
|
|
469
|
+
- docs/api-reference/sqa_seasonalanalyzer.md
|
|
470
|
+
- docs/api-reference/sqa_sectoranalyzer.md
|
|
471
|
+
- docs/api-reference/sqa_stock.md
|
|
472
|
+
- docs/api-reference/sqa_strategy.md
|
|
473
|
+
- docs/api-reference/sqa_strategy_bollingerbands.md
|
|
474
|
+
- docs/api-reference/sqa_strategy_common.md
|
|
475
|
+
- docs/api-reference/sqa_strategy_consensus.md
|
|
476
|
+
- docs/api-reference/sqa_strategy_ema.md
|
|
477
|
+
- docs/api-reference/sqa_strategy_kbs.md
|
|
478
|
+
- docs/api-reference/sqa_strategy_macd.md
|
|
479
|
+
- docs/api-reference/sqa_strategy_mp.md
|
|
480
|
+
- docs/api-reference/sqa_strategy_mr.md
|
|
481
|
+
- docs/api-reference/sqa_strategy_random.md
|
|
482
|
+
- docs/api-reference/sqa_strategy_rsi.md
|
|
483
|
+
- docs/api-reference/sqa_strategy_sma.md
|
|
484
|
+
- docs/api-reference/sqa_strategy_stochastic.md
|
|
485
|
+
- docs/api-reference/sqa_strategy_volumebreakout.md
|
|
486
|
+
- docs/api-reference/sqa_strategygenerator.md
|
|
487
|
+
- docs/api-reference/sqa_strategygenerator_pattern.md
|
|
488
|
+
- docs/api-reference/sqa_strategygenerator_patterncontext.md
|
|
489
|
+
- docs/api-reference/sqa_strategygenerator_profitablepoint.md
|
|
490
|
+
- docs/api-reference/sqa_stream.md
|
|
491
|
+
- docs/api-reference/sqa_ticker.md
|
|
492
|
+
- docs/api-reference/string.md
|
|
414
493
|
- docs/api/dataframe.md
|
|
415
494
|
- docs/api/index.md
|
|
416
495
|
- docs/assets/css/custom.css
|
|
496
|
+
- docs/assets/images/advanced-workflow.svg
|
|
497
|
+
- docs/assets/images/architecture.svg
|
|
498
|
+
- docs/assets/images/data-flow.svg
|
|
499
|
+
- docs/assets/images/getting-started-workflow.svg
|
|
417
500
|
- docs/assets/images/sqa.jpg
|
|
501
|
+
- docs/assets/images/strategy-flow.svg
|
|
502
|
+
- docs/assets/images/system-architecture.svg
|
|
418
503
|
- docs/assets/js/mathjax.js
|
|
419
504
|
- docs/concepts/index.md
|
|
420
505
|
- docs/contributing/index.md
|
|
421
506
|
- docs/data-sources/index.md
|
|
422
507
|
- docs/data_frame.md
|
|
423
508
|
- docs/factors_that_impact_price.md
|
|
509
|
+
- docs/file_formats.md
|
|
424
510
|
- docs/finviz.md
|
|
425
511
|
- docs/fx_pro_bit.md
|
|
426
512
|
- docs/genetic_programming.md
|
|
@@ -433,6 +519,7 @@ files:
|
|
|
433
519
|
- docs/indicators.md
|
|
434
520
|
- docs/indicators/index.md
|
|
435
521
|
- docs/libsvm_file_format.md
|
|
522
|
+
- docs/llms.txt
|
|
436
523
|
- docs/mean_reversion.md
|
|
437
524
|
- docs/options.md
|
|
438
525
|
- docs/predict_next_value.md
|
|
@@ -484,25 +571,6 @@ files:
|
|
|
484
571
|
- examples/rails_app/config/environment.rb
|
|
485
572
|
- examples/rails_app/config/routes.rb
|
|
486
573
|
- examples/realtime_stream_example.rb
|
|
487
|
-
- examples/sinatra_app/Gemfile
|
|
488
|
-
- examples/sinatra_app/Gemfile.lock
|
|
489
|
-
- examples/sinatra_app/QUICKSTART.md
|
|
490
|
-
- examples/sinatra_app/README.md
|
|
491
|
-
- examples/sinatra_app/RUNNING_WITHOUT_TALIB.md
|
|
492
|
-
- examples/sinatra_app/TROUBLESHOOTING.md
|
|
493
|
-
- examples/sinatra_app/app.rb
|
|
494
|
-
- examples/sinatra_app/config.ru
|
|
495
|
-
- examples/sinatra_app/public/css/style.css
|
|
496
|
-
- examples/sinatra_app/public/debug_macd.html
|
|
497
|
-
- examples/sinatra_app/public/js/app.js
|
|
498
|
-
- examples/sinatra_app/start.sh
|
|
499
|
-
- examples/sinatra_app/views/analyze.erb
|
|
500
|
-
- examples/sinatra_app/views/backtest.erb
|
|
501
|
-
- examples/sinatra_app/views/dashboard.erb
|
|
502
|
-
- examples/sinatra_app/views/error.erb
|
|
503
|
-
- examples/sinatra_app/views/index.erb
|
|
504
|
-
- examples/sinatra_app/views/layout.erb
|
|
505
|
-
- examples/sinatra_app/views/portfolio.erb
|
|
506
574
|
- examples/strategy_generator_example.rb
|
|
507
575
|
- hsa_portfolio.csv
|
|
508
576
|
- justfile
|
data/docs/README.md
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# README.md
|
|
2
|
-
|
|
3
|
-
"Playing the market" has always felt like "playing roulette" at the casino - "you pays your money and you takes your chances". Some players are winners. Some are losers. But **the House Always Wins.**
|
|
4
|
-
|
|
5
|
-
Before computers, swings in the market were caused by people. These days I believe that computers have more to do with it than public trader sentiment. One computer program can start a cascade of other computer programs selling or buying in a digital frenzy of trading chaos.
|
|
6
|
-
|
|
7
|
-
There are supposed to be tripwires in the system that protect against such things.
|
|
8
|
-
|
|
9
|
-
## Recent Computer-caused Chaos
|
|
10
|
-
|
|
11
|
-
I asked my AI assistant "do you know of any times when computer programs caused trading chaos in the stock market?"
|
|
12
|
-
|
|
13
|
-
Yes, there have been several instances in history when computer programs have contributed to chaos in the stock market. Here are a few notable examples:
|
|
14
|
-
|
|
15
|
-
1. **Flash Crash, 2010:** On May 6, 2010, U.S. financial markets experienced a brief, severe, and rapidly-reversed drop in stock prices. The Dow Jones Industrial Average plunged by over 1,000 points in a matter of minutes, only to recover just as quickly. This event is known as the "Flash Crash". The crash was primarily blamed on high-frequency trading algorithms - computer programs that execute trades at incredibly high speeds.
|
|
16
|
-
|
|
17
|
-
2. **Knight Capital Group Incident, 2012:** On August 1, 2012, the company Knight Capital Group experienced a major malfunction in its automated trading software. The software executed trades worth $7 billion in about half an hour, causing Knight Capital's stock price to collapse and leading to a $440 million loss for the company.
|
|
18
|
-
|
|
19
|
-
3. **Facebook's IPO, 2012:** During the initial public offering of Facebook on May 18, 2012, the stock exchange NASDAQ experienced significant technical problems. The defective technology running NASDAQ’s trading software resulted in a delay of the start of trading and confusion over individual share orders, leading to a chaotic and disorderly start to Facebook's life as a public company.
|
|
20
|
-
|
|
21
|
-
4. **Swiss Franc Surge, 2015:** On January 15, 2015, the Swiss franc surged nearly 30% in a matter of minutes after the Swiss National Bank unexpectedly abolished a cap on the franc's value against the euro. Many automated trading systems were not equipped to handle this abrupt change, resulting in massive losses for many traders and companies.
|
|
22
|
-
|
|
23
|
-
These events highlight the importance of careful design and rigorous testing for trading algorithms and software systems. They also demonstrate the potential for extreme market volatility in the face of unforeseen software failures or unexpected economic events.
|
|
24
|
-
|
|
25
|
-
## How to be a Winner
|
|
26
|
-
|
|
27
|
-
**Knowledge is King** at the casino when playing blackjack, if you can count the cards without getting caught and killed, you can gain a very small advantage over the house. I was once given the advice to never trade a company that I did not know inside and out or in an industry in which I had no expertise. Basically the more you know about a company the better your chances of making a beneficial trade. I guess the extreme of that is being an insider; but there are laws against that right? Or is it like blackjack and you should just not get caught?
|
|
28
|
-
|
|
29
|
-
Is it possible to "beat the system?" Lots of people have become wealthy selling books or services that purport to teach you how. They all contain the same or similar disclaimers:
|
|
30
|
-
|
|
31
|
-
> Decisions to buy, sell, hold or trade in securities, commodities and other investments involve risk and are best made based on the advice of qualified financial professionals. Any trading in securities or other investments involves a risk of substantial losses.
|
|
32
|
-
>
|
|
33
|
-
> Before undertaking any trading program, you should consult a qualified financial professional. Please consider carefully whether such trading is suitable for you in light of your financial condition and ability to bear financial risks. **Under no circumstances shall we be liable** for any loss or damage you or anyone else incurs as a result of any trading or investment activity that you or anyone else engages in based on any information or material you receive through us or our services.
|
|
34
|
-
|
|
35
|
-
Here's my favorite:
|
|
36
|
-
|
|
37
|
-
> Hypothetical performance results have many inherent limitations. No representation is being made that any account will or is likely to achieve profits or losses similar to those shown. In fact, there are frequently sharp differences between hypothetical performance results and actual results subsequently achieved by any particular trading program.
|
|
38
|
-
>
|
|
39
|
-
> One of the limitations of hypothetical performance results is that they are generally prepared with the benefit of hindsight. In addition, hypothetical trading does not involve financial risk and no hypothetical trading record can completely account for the impact of financial risk in actual trading. For example the ability to withstand losses or to adhere to a particular trading program in spite of the trading losses are material points, which can also adversely affect trading results. There are numerous other factors related to the market in general or to the implementation of any specific trading program which cannot be fully accounted for in the preparation of hypothetical performance results and all of which can adversely affect actual trading results.
|
|
40
|
-
|
|
41
|
-
So it other words "you pays your money and you takes your chances."
|
|
42
|
-
|
|
43
|
-
**The House Always Wins**
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
source 'https://rubygems.org'
|
|
4
|
-
|
|
5
|
-
ruby '>= 3.2.0'
|
|
6
|
-
|
|
7
|
-
# Web framework
|
|
8
|
-
gem 'rackup'
|
|
9
|
-
gem 'sinatra', '~> 4.0'
|
|
10
|
-
gem 'sinatra-contrib', '~> 4.0'
|
|
11
|
-
gem 'puma', '~> 6.0'
|
|
12
|
-
|
|
13
|
-
# JSON handling
|
|
14
|
-
gem 'json', '~> 2.7'
|
|
15
|
-
|
|
16
|
-
# SQA library dependencies (required when loading SQA from local path)
|
|
17
|
-
gem 'alphavantage'
|
|
18
|
-
gem 'csv'
|
|
19
|
-
gem 'faraday'
|
|
20
|
-
gem 'hashie'
|
|
21
|
-
gem 'kbs'
|
|
22
|
-
gem 'lite-statistics'
|
|
23
|
-
gem 'nenv'
|
|
24
|
-
gem 'redis'
|
|
25
|
-
gem 'ruby_llm'
|
|
26
|
-
gem 'ruby_llm-mcp'
|
|
27
|
-
gem 'shared_tools'
|
|
28
|
-
gem 'sqa-tai'
|
|
29
|
-
gem 'tty-table'
|
|
30
|
-
gem 'eps'
|
|
31
|
-
gem 'polars-df'
|
|
32
|
-
gem 'toml-rb'
|
|
33
|
-
gem 'regent'
|
|
34
|
-
|
|
35
|
-
# SQA library (assumes it's in parent directory)
|
|
36
|
-
# In production, this would be:
|
|
37
|
-
# gem 'sqa'
|
|
38
|
-
# For development, we'll load from local path via require in app.rb
|
|
39
|
-
|
|
40
|
-
group :development do
|
|
41
|
-
gem 'rerun' # Auto-reload on file changes
|
|
42
|
-
end
|