sqa 0.0.22 → 0.0.31
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/.goose/memory/development.txt +3 -0
- data/.semver +6 -0
- data/ARCHITECTURE.md +648 -0
- data/CHANGELOG.md +86 -0
- data/CLAUDE.md +653 -0
- data/COMMITS.md +196 -0
- data/DATAFRAME_ARCHITECTURE_REVIEW.md +421 -0
- data/NEXT-STEPS.md +154 -0
- data/README.md +833 -213
- data/TASKS.md +358 -0
- data/TEST_RESULTS.md +140 -0
- data/TODO.md +42 -0
- data/_notes.txt +25 -0
- data/bin/sqa-console +11 -0
- data/checksums/sqa-0.0.23.gem.sha512 +1 -0
- data/checksums/sqa-0.0.24.gem.sha512 +1 -0
- data/data/talk_talk.json +103284 -0
- data/develop_summary.md +313 -0
- data/docs/advanced/backtesting.md +206 -0
- data/docs/advanced/ensemble.md +68 -0
- data/docs/advanced/fpop.md +153 -0
- data/docs/advanced/index.md +112 -0
- data/docs/advanced/multi-timeframe.md +67 -0
- data/docs/advanced/pattern-matcher.md +75 -0
- data/docs/advanced/portfolio-optimizer.md +79 -0
- data/docs/advanced/portfolio.md +166 -0
- data/docs/advanced/risk-management.md +210 -0
- data/docs/advanced/strategy-generator.md +158 -0
- data/docs/advanced/streaming.md +209 -0
- data/docs/ai_and_ml.md +80 -0
- data/docs/api/dataframe.md +1115 -0
- data/docs/api/index.md +126 -0
- data/docs/assets/css/custom.css +88 -0
- data/docs/assets/js/mathjax.js +18 -0
- data/docs/concepts/index.md +68 -0
- data/docs/contributing/index.md +60 -0
- data/docs/data-sources/index.md +66 -0
- data/docs/data_frame.md +317 -97
- data/docs/factors_that_impact_price.md +26 -0
- data/docs/finviz.md +11 -0
- data/docs/fx_pro_bit.md +25 -0
- data/docs/genetic_programming.md +104 -0
- data/docs/getting-started/index.md +123 -0
- data/docs/getting-started/installation.md +229 -0
- data/docs/getting-started/quick-start.md +244 -0
- data/docs/i_gotta_an_idea.md +22 -0
- data/docs/index.md +163 -0
- data/docs/indicators/index.md +97 -0
- data/docs/indicators.md +110 -24
- data/docs/options.md +8 -0
- data/docs/strategies/bollinger-bands.md +146 -0
- data/docs/strategies/consensus.md +64 -0
- data/docs/strategies/custom.md +310 -0
- data/docs/strategies/ema.md +53 -0
- data/docs/strategies/index.md +92 -0
- data/docs/strategies/kbs.md +164 -0
- data/docs/strategies/macd.md +96 -0
- data/docs/strategies/market-profile.md +54 -0
- data/docs/strategies/mean-reversion.md +58 -0
- data/docs/strategies/rsi.md +95 -0
- data/docs/strategies/sma.md +55 -0
- data/docs/strategies/stochastic.md +63 -0
- data/docs/strategies/volume-breakout.md +54 -0
- data/docs/ta_lib.md +160 -0
- data/docs/tags.md +7 -0
- data/docs/true_strength_index.md +46 -0
- data/docs/weighted_moving_average.md +48 -0
- data/examples/README.md +354 -0
- data/examples/advanced_features_example.rb +350 -0
- data/examples/fpop_analysis_example.rb +191 -0
- data/examples/genetic_programming_example.rb +148 -0
- data/examples/kbs_strategy_example.rb +208 -0
- data/examples/pattern_context_example.rb +300 -0
- data/examples/rails_app/Gemfile +34 -0
- data/examples/rails_app/README.md +416 -0
- data/examples/rails_app/app/assets/javascripts/application.js +107 -0
- data/examples/rails_app/app/assets/stylesheets/application.css +659 -0
- data/examples/rails_app/app/controllers/analysis_controller.rb +11 -0
- data/examples/rails_app/app/controllers/api/v1/stocks_controller.rb +227 -0
- data/examples/rails_app/app/controllers/application_controller.rb +22 -0
- data/examples/rails_app/app/controllers/backtest_controller.rb +11 -0
- data/examples/rails_app/app/controllers/dashboard_controller.rb +21 -0
- data/examples/rails_app/app/controllers/portfolio_controller.rb +7 -0
- data/examples/rails_app/app/views/analysis/show.html.erb +209 -0
- data/examples/rails_app/app/views/backtest/show.html.erb +171 -0
- data/examples/rails_app/app/views/dashboard/index.html.erb +118 -0
- data/examples/rails_app/app/views/dashboard/show.html.erb +408 -0
- data/examples/rails_app/app/views/errors/show.html.erb +17 -0
- data/examples/rails_app/app/views/layouts/application.html.erb +60 -0
- data/examples/rails_app/app/views/portfolio/index.html.erb +33 -0
- data/examples/rails_app/bin/rails +6 -0
- data/examples/rails_app/config/application.rb +45 -0
- data/examples/rails_app/config/boot.rb +5 -0
- data/examples/rails_app/config/database.yml +18 -0
- data/examples/rails_app/config/environment.rb +11 -0
- data/examples/rails_app/config/routes.rb +26 -0
- data/examples/rails_app/config.ru +8 -0
- data/examples/realtime_stream_example.rb +274 -0
- data/examples/sinatra_app/Gemfile +22 -0
- data/examples/sinatra_app/QUICKSTART.md +159 -0
- data/examples/sinatra_app/README.md +461 -0
- data/examples/sinatra_app/app.rb +344 -0
- data/examples/sinatra_app/config.ru +5 -0
- data/examples/sinatra_app/public/css/style.css +659 -0
- data/examples/sinatra_app/public/js/app.js +107 -0
- data/examples/sinatra_app/views/analyze.erb +306 -0
- data/examples/sinatra_app/views/backtest.erb +325 -0
- data/examples/sinatra_app/views/dashboard.erb +419 -0
- data/examples/sinatra_app/views/error.erb +58 -0
- data/examples/sinatra_app/views/index.erb +118 -0
- data/examples/sinatra_app/views/layout.erb +61 -0
- data/examples/sinatra_app/views/portfolio.erb +43 -0
- data/examples/strategy_generator_example.rb +346 -0
- data/hsa_portfolio.csv +11 -0
- data/justfile +0 -0
- data/lib/api/alpha_vantage_api.rb +462 -0
- data/lib/sqa/backtest.rb +329 -0
- data/lib/sqa/config.rb +22 -9
- data/lib/sqa/data_frame/alpha_vantage.rb +43 -65
- data/lib/sqa/data_frame/data.rb +92 -0
- data/lib/sqa/data_frame/yahoo_finance.rb +34 -41
- data/lib/sqa/data_frame.rb +148 -243
- data/lib/sqa/ensemble.rb +359 -0
- data/lib/sqa/fpop.rb +199 -0
- data/lib/sqa/gp.rb +259 -0
- data/lib/sqa/indicator.rb +5 -8
- data/lib/sqa/init.rb +16 -9
- data/lib/sqa/market_regime.rb +240 -0
- data/lib/sqa/multi_timeframe.rb +379 -0
- data/lib/sqa/pattern_matcher.rb +497 -0
- data/lib/sqa/plugin_manager.rb +20 -0
- data/lib/sqa/portfolio.rb +260 -6
- data/lib/sqa/portfolio_optimizer.rb +377 -0
- data/lib/sqa/risk_manager.rb +442 -0
- data/lib/sqa/seasonal_analyzer.rb +209 -0
- data/lib/sqa/sector_analyzer.rb +300 -0
- data/lib/sqa/stock.rb +67 -96
- data/lib/sqa/strategy/bollinger_bands.rb +42 -0
- data/lib/sqa/strategy/common.rb +0 -2
- data/lib/sqa/strategy/consensus.rb +5 -2
- data/lib/sqa/strategy/kbs_strategy.rb +470 -0
- data/lib/sqa/strategy/macd.rb +46 -0
- data/lib/sqa/strategy/mp.rb +1 -1
- data/lib/sqa/strategy/stochastic.rb +60 -0
- data/lib/sqa/strategy/volume_breakout.rb +57 -0
- data/lib/sqa/strategy.rb +5 -0
- data/lib/sqa/strategy_generator.rb +947 -0
- data/lib/sqa/stream.rb +361 -0
- data/lib/sqa/version.rb +1 -7
- data/lib/sqa.rb +41 -14
- data/main.just +81 -0
- data/mkdocs.yml +288 -0
- data/trace.log +0 -0
- metadata +279 -48
- data/bin/sqa +0 -6
- data/lib/sqa/activity.rb +0 -10
- data/lib/sqa/analysis.rb +0 -306
- data/lib/sqa/cli.rb +0 -173
- data/lib/sqa/constants.rb +0 -23
- data/lib/sqa/indicator/average_true_range.rb +0 -43
- data/lib/sqa/indicator/bollinger_bands.rb +0 -28
- data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +0 -60
- data/lib/sqa/indicator/donchian_channel.rb +0 -29
- data/lib/sqa/indicator/double_top_bottom_pattern.rb +0 -34
- data/lib/sqa/indicator/elliott_wave_theory.rb +0 -57
- data/lib/sqa/indicator/exponential_moving_average.rb +0 -25
- data/lib/sqa/indicator/exponential_moving_average_trend.rb +0 -36
- data/lib/sqa/indicator/fibonacci_retracement.rb +0 -23
- data/lib/sqa/indicator/head_and_shoulders_pattern.rb +0 -26
- data/lib/sqa/indicator/market_profile.rb +0 -32
- data/lib/sqa/indicator/mean_reversion.rb +0 -37
- data/lib/sqa/indicator/momentum.rb +0 -28
- data/lib/sqa/indicator/moving_average_convergence_divergence.rb +0 -29
- data/lib/sqa/indicator/peaks_and_valleys.rb +0 -29
- data/lib/sqa/indicator/predict_next_value.rb +0 -202
- data/lib/sqa/indicator/relative_strength_index.rb +0 -47
- data/lib/sqa/indicator/simple_moving_average.rb +0 -24
- data/lib/sqa/indicator/simple_moving_average_trend.rb +0 -32
- data/lib/sqa/indicator/stochastic_oscillator.rb +0 -68
- data/lib/sqa/indicator/true_range.rb +0 -39
- data/lib/sqa/trade.rb +0 -26
- data/lib/sqa/web.rb +0 -159
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# lib/sqa/indicator/stochastic_oscillator.rb
|
|
2
|
-
|
|
3
|
-
class SQA::Indicator; class << self
|
|
4
|
-
|
|
5
|
-
# @param high_prices [Array]
|
|
6
|
-
# @param low_prices [Array]
|
|
7
|
-
# @param close_prices [Array]
|
|
8
|
-
# @param period [Integer]
|
|
9
|
-
# @param smoothing_period [Integer]
|
|
10
|
-
#
|
|
11
|
-
# @return [Array] An array of %K and %D values.
|
|
12
|
-
#
|
|
13
|
-
def stochastic_oscillator(
|
|
14
|
-
high_prices, # Array of high prices
|
|
15
|
-
low_prices, # Array of low prices
|
|
16
|
-
closing_prices, # Array of closing prices
|
|
17
|
-
period, # Integer The period for calculating the Stochastic Oscillator
|
|
18
|
-
smoothing_period # Integer The smoothing period for %K line
|
|
19
|
-
)
|
|
20
|
-
k_values = []
|
|
21
|
-
d_values = []
|
|
22
|
-
|
|
23
|
-
closing_prices.each_cons(period) do |window|
|
|
24
|
-
highest_high = high_prices.max(period)
|
|
25
|
-
lowest_low = low_prices.min(period)
|
|
26
|
-
current_close = window.last
|
|
27
|
-
k_values << (current_close - lowest_low) / (highest_high - lowest_low) * 100 # Calculate the k_value
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
k_values.each_cons(smoothing_period) do |k_values_subset|
|
|
31
|
-
d_values << k_values_subset.sum / smoothing_period.to_f # Calculate the d_value
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
[k_values, d_values]
|
|
35
|
-
end
|
|
36
|
-
alias_method :so, :stochastic_oscillator
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def stochastic_oscillator2(
|
|
40
|
-
prices, # Array of prices
|
|
41
|
-
period # Integer number of events to consider
|
|
42
|
-
)
|
|
43
|
-
k_values = []
|
|
44
|
-
d_values = []
|
|
45
|
-
|
|
46
|
-
prices.each_cons(period) do |window|
|
|
47
|
-
low = window.min # Lowest price in the period
|
|
48
|
-
high = window.max # Highest price in the period
|
|
49
|
-
current_price = window.last # Current closing price
|
|
50
|
-
|
|
51
|
-
k_values << (current_price - low) * 100 / (high - low)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
k_values.each_cons(period) do |window|
|
|
55
|
-
d_values << window.mean
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
k: k_values,
|
|
60
|
-
d: d_values
|
|
61
|
-
}
|
|
62
|
-
end
|
|
63
|
-
alias_method :so2, :stochastic_oscillator2
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
end; end
|
|
68
|
-
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# lib/sqa/indicator/true_range.rb
|
|
2
|
-
|
|
3
|
-
# See Also: average_true_range
|
|
4
|
-
|
|
5
|
-
class SQA::Indicator; class << self
|
|
6
|
-
|
|
7
|
-
# @param high_prices [Array]
|
|
8
|
-
# @param low_prices [Array]
|
|
9
|
-
# @param previous_closes [Array]
|
|
10
|
-
#
|
|
11
|
-
# @return [Array]
|
|
12
|
-
#
|
|
13
|
-
def true_range(
|
|
14
|
-
high_prices, # Array of high prices
|
|
15
|
-
low_prices, # Array of low prices
|
|
16
|
-
closing_prices # Array of closing prices
|
|
17
|
-
)
|
|
18
|
-
true_ranges = []
|
|
19
|
-
|
|
20
|
-
high_prices.each_with_index do |high, index|
|
|
21
|
-
if index > 0
|
|
22
|
-
low = low_prices[index]
|
|
23
|
-
previous_close = closing_prices[index - 1]
|
|
24
|
-
|
|
25
|
-
true_range = [
|
|
26
|
-
high - low,
|
|
27
|
-
(high - previous_close).abs,
|
|
28
|
-
(low - previous_close).abs
|
|
29
|
-
].max
|
|
30
|
-
|
|
31
|
-
true_ranges << true_range
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
true_ranges # Array of True Range values
|
|
36
|
-
end
|
|
37
|
-
alias_method :tr, :true_range
|
|
38
|
-
|
|
39
|
-
end; end
|
data/lib/sqa/trade.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# lib/sqa/trade.rb
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class SQA::Trade
|
|
5
|
-
attr_accessor :df
|
|
6
|
-
|
|
7
|
-
def initialize(
|
|
8
|
-
filename = SQA::Config.trades_filename
|
|
9
|
-
)
|
|
10
|
-
@df = SQA::DataFrame.load(filename)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def place(signal, ticker, shares, price=nil)
|
|
14
|
-
# TODO: insert row into @df
|
|
15
|
-
|
|
16
|
-
uuid = rand(100000) # FIXME: place holder
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def confirm(uuid, shares, price)
|
|
20
|
-
# TODO: update the row in the data frame
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def save
|
|
24
|
-
# TODO: save the data frame
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/sqa/web.rb
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
# lib/sqa/command/web.rb
|
|
2
|
-
|
|
3
|
-
# require 'tty-option'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
module SQA
|
|
7
|
-
class Web < CLI
|
|
8
|
-
include TTY::Option
|
|
9
|
-
|
|
10
|
-
command "web"
|
|
11
|
-
|
|
12
|
-
desc "Run a web server"
|
|
13
|
-
|
|
14
|
-
example "Set working directory (-w)",
|
|
15
|
-
" sqa web --port 4567 --data-dir /path/to/dir/ ubuntu pwd"
|
|
16
|
-
|
|
17
|
-
example <<~EOS
|
|
18
|
-
Do Something
|
|
19
|
-
sqa web
|
|
20
|
-
EOS
|
|
21
|
-
|
|
22
|
-
argument :image do
|
|
23
|
-
required
|
|
24
|
-
desc "The name of the image to use"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
keyword :restart do
|
|
28
|
-
default "no"
|
|
29
|
-
permit %w[no on-failure always unless-stopped]
|
|
30
|
-
desc "Restart policy to apply when a container exits"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
flag :detach do
|
|
34
|
-
long "--detach"
|
|
35
|
-
desc "Run container in background and print container ID"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
option :name do
|
|
39
|
-
required
|
|
40
|
-
long "--name string"
|
|
41
|
-
desc "Assign a name to the container"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
option :port do
|
|
45
|
-
arity one_or_more
|
|
46
|
-
long "--port integer"
|
|
47
|
-
default 4567
|
|
48
|
-
desc "The port where the web app will run"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def initialize
|
|
53
|
-
# TODO: make it happen
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
__END__
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
#!/usr/bin/env ruby
|
|
62
|
-
# experiments/sinatra_examples/svg_viewer.rb
|
|
63
|
-
# builds on md_viewer.rb
|
|
64
|
-
|
|
65
|
-
require 'sinatra'
|
|
66
|
-
require 'kramdown'
|
|
67
|
-
require 'nenv'
|
|
68
|
-
|
|
69
|
-
# class MdViewer < Sinatra::Application
|
|
70
|
-
|
|
71
|
-
# Set the directory location
|
|
72
|
-
set :markdown_directory, Nenv.home + '/Downloads'
|
|
73
|
-
|
|
74
|
-
# Sinatra route to show a markdown file as html
|
|
75
|
-
get '/md/:filename' do
|
|
76
|
-
# Get the file name from the URL parameter
|
|
77
|
-
filename = params[:filename]
|
|
78
|
-
|
|
79
|
-
# Check if the file exists in the specified directory
|
|
80
|
-
if File.file?(File.join(settings.markdown_directory, filename))
|
|
81
|
-
# Read the markdown file
|
|
82
|
-
markdown_content = File.read(File.join(settings.markdown_directory, filename))
|
|
83
|
-
|
|
84
|
-
# Convert the markdown to HTML using kramdown
|
|
85
|
-
converted_html = Kramdown::Document.new(markdown_content).to_html
|
|
86
|
-
|
|
87
|
-
# Display the generated HTML
|
|
88
|
-
content_type :html
|
|
89
|
-
converted_html
|
|
90
|
-
else
|
|
91
|
-
# File not found error
|
|
92
|
-
status 404
|
|
93
|
-
"File not found: #{filename} in #{markdown_directory}"
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# Sinatra route to show a markdown file as html
|
|
99
|
-
get '/svg/:filename' do
|
|
100
|
-
# Get the file name from the URL parameter
|
|
101
|
-
filename = params[:filename]
|
|
102
|
-
|
|
103
|
-
# Check if the file exists in the specified directory
|
|
104
|
-
if File.file?(File.join(settings.markdown_directory, filename))
|
|
105
|
-
# Read the svg file
|
|
106
|
-
svg_content = File.read(File.join(settings.markdown_directory, filename))
|
|
107
|
-
|
|
108
|
-
# Convert the svg to HTML
|
|
109
|
-
converted_html = <<~HTML
|
|
110
|
-
<!DOCTYPE html>
|
|
111
|
-
<html>
|
|
112
|
-
<head>
|
|
113
|
-
<meta charset="utf-8">
|
|
114
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
115
|
-
<title>#{filename}</title>
|
|
116
|
-
</head>
|
|
117
|
-
<body>
|
|
118
|
-
#{svg_content}
|
|
119
|
-
</body>
|
|
120
|
-
</html>
|
|
121
|
-
HTML
|
|
122
|
-
|
|
123
|
-
# Display the generated HTML
|
|
124
|
-
content_type :html
|
|
125
|
-
converted_html
|
|
126
|
-
else
|
|
127
|
-
# File not found error
|
|
128
|
-
status 404
|
|
129
|
-
"File not found: #{filename} in #{markdown_directory}"
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# end
|
|
137
|
-
|
|
138
|
-
# Start the Sinatra app
|
|
139
|
-
# run MdViewer
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
__END__
|
|
143
|
-
|
|
144
|
-
ruby myapp.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
|
145
|
-
|
|
146
|
-
Options are:
|
|
147
|
-
|
|
148
|
-
-h # help
|
|
149
|
-
-p # set the port (default is 4567)
|
|
150
|
-
-o # set the host (default is 0.0.0.0)
|
|
151
|
-
-e # set the environment (default is development)
|
|
152
|
-
-s # specify rack server/handler (default is puma)
|
|
153
|
-
-q # turn on quiet mode for server (default is off)
|
|
154
|
-
-x # turn on the mutex lock (default is off)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|