sqa 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ # lib/sqa/indicator/predict_next_values.rb
2
+
3
+ module SQA
4
+ end
5
+
6
+ class SQA::Indicator; class << self
7
+
8
+ def predict_next_values(array, predictions)
9
+ result = []
10
+
11
+ array.each_cons(2) do |a, b|
12
+ # TODO: take 3 at a time. compare 3rd
13
+ # prediction. Generate an average delta
14
+ # between predicted and actual. Return
15
+ # the prediction as a range???
16
+ result << b + (b - a)
17
+ end
18
+
19
+ if predictions > 0
20
+ (1..predictions).each do |_|
21
+ last_two_values = result.last(2)
22
+ delta = last_two_values.last - last_two_values.first
23
+ next_value = last_two_values.last + delta
24
+ result << next_value
25
+ end
26
+ end
27
+
28
+ result.last(predictions)
29
+ end
30
+ alias_method :pnv, :predict_next_values
31
+
32
+
33
+ # Returns a forecast for future values based on the near past
34
+ #
35
+ # When I wrote this I was thinking of hurricane forecasting and how
36
+ # the cone of probability gets larger the further into the future
37
+ # the forecast goes. This does not produce that kind of probability
38
+ # cone; but, that was hwat I was thinking about
39
+ #
40
+ # array is an Array - for example historical price data
41
+ # predictions is an Integer for how many predictions into the future
42
+ #
43
+ def pnv2(array, predictions)
44
+ result = []
45
+ last_inx = array.size - 1 # indexes are zero based
46
+
47
+ predictions.times do |x|
48
+ x += 1 # forecasting 1 day into the future needs 2 days of near past data
49
+
50
+ # window is the near past values
51
+ window = array[last_inx-x..]
52
+
53
+ high = window.max
54
+ low = window.min
55
+ midpoint = (high + low) / 2.0
56
+
57
+ result << [high, midpoint, low]
58
+ end
59
+
60
+ result
61
+ end
62
+
63
+ end; end
data/lib/sqa/portfolio.rb CHANGED
@@ -3,7 +3,9 @@
3
3
  class SQA::Portfolio
4
4
  attr_accessor :df
5
5
 
6
- def initialize(filename="portfolio.csv")
6
+ def initialize(
7
+ filename = SQA::Config.portfolio_filename
8
+ )
7
9
  @df = SQA::DataFrame.load(filename)
8
10
  end
9
11
  end
data/lib/sqa/stock.rb CHANGED
@@ -6,10 +6,12 @@ class SQA::Stock
6
6
  attr_accessor :ticker
7
7
 
8
8
  def initialize(ticker:, source: :yahoo_finance, type: :csv)
9
- @ticker = ticker
9
+ @ticker = ticker.downcase
10
10
  @company_name = "Company Name"
11
11
  klass = "SQA::DataFrame::#{source.to_s.camelize}".constantize
12
- @df = klass.send("from_#{type.downcase}", ticker)
12
+ filename = "#{@ticker}.#{type}"
13
+ @df = klass.send(:load, filename)
14
+ @df[:ticker] = ticker
13
15
  end
14
16
 
15
17
  def to_s
data/lib/sqa/trade.rb CHANGED
@@ -4,7 +4,9 @@
4
4
  class SQA::Trade
5
5
  attr_accessor :df
6
6
 
7
- def initialize(filename="trades.csv")
7
+ def initialize(
8
+ filename = SQA::Config.trades_filename
9
+ )
8
10
  @df = SQA::DataFrame.load(filename)
9
11
  end
10
12
 
data/lib/sqa/version.rb CHANGED
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sem_version'
4
+ require 'sem_version/core_ext'
5
+
3
6
  module SQA
4
- module Version
5
- VERSION = "0.0.6"
7
+ VERSION = "0.0.8"
8
+
9
+ class << self
10
+ def version
11
+ @@version ||= VERSION.to_version
12
+ end
6
13
  end
7
14
  end
data/lib/sqa/web.rb ADDED
@@ -0,0 +1,159 @@
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
+
data/lib/sqa.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # lib/sqa.rb
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'active_support'
@@ -5,10 +6,11 @@ require 'active_support/core_ext/string'
5
6
  require 'daru'
6
7
  require 'date'
7
8
  require 'descriptive_statistics'
8
- require 'mixlib/config'
9
9
  require 'nenv'
10
10
  require 'pathname'
11
- require "version_gem"
11
+
12
+ require_relative "sqa/version"
13
+
12
14
 
13
15
  unless defined?(HOME)
14
16
  HOME = Pathname.new(Nenv.home)
@@ -16,39 +18,58 @@ end
16
18
 
17
19
 
18
20
  module SQA
19
- Signal = {
20
- hold: 0,
21
- buy: 1,
22
- sell: 2
23
- }.freeze
24
-
25
- Trend = {
26
- up: 0,
27
- down: 1
28
- }.freeze
29
-
30
- Swing = {
31
- valley: 0,
32
- peak: 1,
33
- }.freeze
34
-
35
- module Config
36
- extend Mixlib::Config
37
- config_strict_mode true
38
-
39
- default :data_dir, HOME + "sqa_data"
40
- default :plotting_library, :gruff
41
- default :lazy_update, false
42
- end
21
+ class << self
22
+ @@config = nil
23
+
24
+ def init(argv=ARGV)
25
+ if argv.is_a? String
26
+ argv = argv.split()
27
+ end
28
+
29
+
30
+ # Ran at SQA::Config elaboration time
31
+ # @@config = Config.new
32
+
33
+ CLI.run(argv) if defined? CLI
34
+
35
+ Daru.lazy_update = config.lazy_update
36
+ Daru.plotting_library = config.plotting_library
37
+
38
+ if config.debug? || config.verbose?
39
+ debug_me{[
40
+ :config
41
+ ]}
42
+ end
43
43
 
44
- def self.init
45
- Daru.lazy_update = Config.lazy_update
46
- Daru.plotting_library = Config.plotting_library
44
+ nil
45
+ end
47
46
 
48
- nil
47
+ def homify(filepath)
48
+ filepath.gsub(/^~/, Nenv.home)
49
+ end
50
+
51
+ def config
52
+ @@config
53
+ end
54
+
55
+ def config=(an_object)
56
+ @@config = an_object
57
+ end
58
+
59
+ def debug?
60
+ @@config.debug?
61
+ end
62
+
63
+ def verbose?
64
+ @@config.verbose?
65
+ end
49
66
  end
50
67
  end
51
68
 
69
+ # require_relative "patches/daru" # TODO: extract Daru::DataFrame in new gem sqa-data_frame
70
+
71
+ require_relative "sqa/config"
72
+ require_relative "sqa/constants"
52
73
  require_relative "sqa/data_frame"
53
74
  require_relative "sqa/errors"
54
75
  require_relative "sqa/indicator"
@@ -56,9 +77,3 @@ require_relative "sqa/portfolio"
56
77
  require_relative "sqa/strategy"
57
78
  require_relative "sqa/stock"
58
79
  require_relative "sqa/trade"
59
- require_relative "sqa/version"
60
-
61
-
62
- SQA::Version.class_eval do
63
- extend VersionGem::Basic
64
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-18 00:00:00.000000000 Z
11
+ date: 2023-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: gruff
56
+ name: hashie
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: mixlib-config
70
+ name: nenv
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,91 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: nenv
84
+ name: tty-logger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: tty-markdown
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-option
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: tty-progressbar
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: tty-prompt
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: tty-reader
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: tty-spinner
85
169
  requirement: !ruby/object:Gem::Requirement
86
170
  requirements:
87
171
  - - ">="
@@ -95,7 +179,7 @@ dependencies:
95
179
  - !ruby/object:Gem::Version
96
180
  version: '0'
97
181
  - !ruby/object:Gem::Dependency
98
- name: version_gem
182
+ name: tty-table
99
183
  requirement: !ruby/object:Gem::Requirement
100
184
  requirements:
101
185
  - - ">="
@@ -199,6 +283,9 @@ files:
199
283
  - checksums/sqa-0.0.4.gem.sha512
200
284
  - checksums/sqa-0.0.5.gem.sha512
201
285
  - checksums/sqa-0.0.6.gem.sha512
286
+ - checksums/sqa-0.0.7.gem.sha512
287
+ - checksums/sqa-0.0.8.gem.sha512
288
+ - docs/.gitignore
202
289
  - docs/README.md
203
290
  - docs/average_true_range.md
204
291
  - docs/bollinger_bands.md
@@ -210,20 +297,33 @@ files:
210
297
  - docs/fibonacci_retracement.md
211
298
  - docs/head_and_shoulders_pattern.md
212
299
  - docs/identify_wave_condition.md
300
+ - docs/libsvm_file_format.md
213
301
  - docs/market_profile.md
214
302
  - docs/mean_reversion.md
215
303
  - docs/momentum.md
216
304
  - docs/moving_average_convergence_divergence.md
217
305
  - docs/peaks_and_valleys.md
306
+ - docs/predict_next_value.md
218
307
  - docs/relative_strength_index.md
219
308
  - docs/requirements.md
220
309
  - docs/simple_moving_average.md
221
310
  - docs/stochastic_oscillator.md
222
311
  - docs/strategy.md
223
312
  - docs/true_range.md
313
+ - lib/patches/daru.rb
314
+ - lib/patches/daru/category.rb
315
+ - lib/patches/daru/data_frame.rb
316
+ - lib/patches/daru/plotting/svg-graph.rb
317
+ - lib/patches/daru/plotting/svg-graph/category.rb
318
+ - lib/patches/daru/plotting/svg-graph/dataframe.rb
319
+ - lib/patches/daru/plotting/svg-graph/vector.rb
320
+ - lib/patches/daru/vector.rb
224
321
  - lib/sqa.rb
225
322
  - lib/sqa/activity.rb
323
+ - lib/sqa/analysis.rb
226
324
  - lib/sqa/cli.rb
325
+ - lib/sqa/config.rb
326
+ - lib/sqa/constants.rb
227
327
  - lib/sqa/data_frame.rb
228
328
  - lib/sqa/data_frame/yahoo_finance.rb
229
329
  - lib/sqa/errors.rb
@@ -243,6 +343,7 @@ files:
243
343
  - lib/sqa/indicator/momentum.rb
244
344
  - lib/sqa/indicator/moving_average_convergence_divergence.rb
245
345
  - lib/sqa/indicator/peaks_and_valleys.rb
346
+ - lib/sqa/indicator/predict_next_value.rb
246
347
  - lib/sqa/indicator/relative_strength_index.rb
247
348
  - lib/sqa/indicator/simple_moving_average.rb
248
349
  - lib/sqa/indicator/simple_moving_average_trend.rb
@@ -263,6 +364,7 @@ files:
263
364
  - lib/sqa/strategy/sma.rb
264
365
  - lib/sqa/trade.rb
265
366
  - lib/sqa/version.rb
367
+ - lib/sqa/web.rb
266
368
  homepage: https://github.com/MadBomber/sqa
267
369
  licenses:
268
370
  - MIT