sqa 0.0.17 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 911775606b7e0fa046261c5a9bc4d3be21ca9caf38c37011141f1393ac6e5063
4
- data.tar.gz: d70ae996a39dbe7c386750286cb4cc437681d584945b31104e91b06c30b1600f
3
+ metadata.gz: a8dd5577340edd8f74a73428779129e4f97bcfbb4b8eaa23ce02c6b1f290baa4
4
+ data.tar.gz: fa03b7e2203edbb69da04b9ff022776a6932a481e33a7290e4ff46b573375a89
5
5
  SHA512:
6
- metadata.gz: '0074688f69947d20d5aae7c81b090a91fb4f06862084b2349b248ecdf2e17376f47d5a1acffbfb7b2700865cf25f5ff5ba054514d00ed88750f46224b4c9360e'
7
- data.tar.gz: 38d1ebf511e9dfa2b87084ed77093e2fc03ccf6eeb6a00e42d1060acca82e135d0b4c0d36a25d9f9bc4a2dd9adf91749a6640aab14b304e33f24fee0c3eb7e15
6
+ metadata.gz: ca34483321c0ac6391d322acef9ed2a9ba5d1e87db15201d4c89f760346e1c620b1ce5182cf203c393b118703a743bf535f84e52f099bad12445eacc1b82d39b
7
+ data.tar.gz: 89cb9767f3febdc9e20970e0d73a679f378f75260b4e6b146bd413dc49d942200a60f03c2ecb7f02ae6e87662ece5744fa45aead39d147fa7aad81d2037128fc
data/README.md CHANGED
@@ -1,22 +1,13 @@
1
- **Replacing Daru** with Hashie::Mash
2
-
3
- This is branch hashie_df
4
-
5
1
  # SQA - Simple Qualitative Analysis
6
2
 
7
- This is a very simplistic set of tools for running technical analysis on a stock portfolio. Simplistic means it is not reliable nor intended for any kind of financial use. Think of it as a training tool. I do. Its helping me understand why I need professional help from people who know what they are doing.
3
+ This is a very simplistic set of tools for running technical analysis (quantitative and qualitative) on a stock portfolio. Simplistic means it is not reliable nor intended for any kind of mission-critical financial use. Think of it as a training tool. I do. Its helping me understand why I need professional help from people who know what they are doing.
8
4
 
9
- The BUY/SELL signals that it generates are part of a game. **DO NOT USE** when real money is at stake.
5
+ The BUY/SELL signals that it generates should not be taken seriously. **DO NOT USE** this library when real money is at stake. If you lose your shirt playing in the stock market don't come crying to me. I think playing in the market is like playing in the street. You are going to get run over.
10
6
 
11
7
  ## This is a Work in Progress
12
8
 
13
- I'm making use of lots of gems which may not be part of the gemspec at this time. I will be adding them as they make the final cut as to fitness for the intended function. Some gems are configurable. For example the default for the plotting library is `gruff`. There are several available that the `daru` gem can use.
14
-
15
- ### DARU or RedAmber
9
+ I am experimenting with different gems to support various functionality. Sometimes they do not work out well. For example I've gone through two different gems to implement the data frame capability. Neither did what I wanted so I ended up creating my own data frame class based upon the old tried and true Hashie library.
16
10
 
17
- I'm just really using `daru` for its data frame object; However, I just learned about the RedAmber data frame object in Ruby based off of Apache Arrow. I'm going to look at that product since it is actively maintained.
18
-
19
- https://github.com/red-data-tools/red_amber
20
11
 
21
12
  ## Installation
22
13
 
@@ -28,62 +19,200 @@ If bundler is not being used to manage dependencies, install the gem by executin
28
19
 
29
20
  gem install sqa
30
21
 
31
- ## ShoutOut To `daru`
22
+ ### Semantic Versioning
23
+
24
+ ```ruby
25
+ SQA.version # returns SemVersion object
26
+ exit(1) unless SQA.version >= SemVersion("1.0.0")
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ **Do not use!** but its okay to play with.
32
32
 
33
- **D**ata **A**nalysis in **RU**by
33
+ `SQA` can be used from the command line or as a library in your own application.
34
34
 
35
- http://github.com/v0dro/daru
35
+ `SQA` has a command line component.
36
36
 
37
- Its `DataFrame` class is a very interesting in memory data structure.
37
+ ```plaintext
38
+ $ sqa --help
39
+ Stock Quantitative Analysis (SQA)
38
40
 
39
- ## Usage
41
+ Usage: sqa [analysis|web] [OPTIONS]
42
+
43
+ A collection of things
44
+
45
+ Options:
46
+ -c, --config string Path to the config file
47
+ --data-dir string Set the directory for the SQA data
48
+ -d, --debug Turn on debugging output
49
+ --dump-config path_to_file Dump the current configuration
50
+ -h, --help Print usage
51
+ -l, --log_level string Set the log level (debug, info, warn, error,
52
+ fatal)
53
+ -p, --portfolio string Set the filename of the portfolio
54
+ -t, --trades string Set the filename into which trades are
55
+ stored
56
+ -v, --verbose Print verbosely
57
+ --version Print version
58
+
59
+ Examples:
60
+ sqa -c ~/.sqa.yml -p portfolio.csv -t trades.csv --data-dir ~/sqa_data
61
+
62
+ Optional Command Available:
63
+ analysis - Provide an Analysis of a Portfolio
64
+ web - Run a web server
65
+
66
+ WARNING: This is a toy, a play thing, not intended for serious use.
67
+ ```
68
+ ### Setup a Config File
69
+
70
+ You will need to create a directory to store the `sqa` data and a configuration file. You can start by doing this:
71
+
72
+ ```ruby
73
+ gem install sqa
74
+ mkdir ~/Documents/sqa_data
75
+ sqa --data-dir ~/Documents/sqa_data --dump-config ~/.sqa.yml
76
+ ```
77
+
78
+ By default `SQA` looks for a configuration file named `.sqa.yml` in the current directory. If it does not find one there it looks in the home directory. You can use the `--config` CLI option to specify a path to your custom config file name.
79
+
80
+
81
+ ### AlphaVantage
82
+
83
+ `SQA` makes use of the `AlphaVantage` API to get some stock related information. You will need an API key in order to use this functionality. They have a free rate limited API key which allows 5 accesses per second; total of 100 accesses in a day. If you are doing more than that you are not playing an ought to purchase one of there serious API key plans.
84
+
85
+ [https://www.alphavantage.co/](https://www.alphavantage.co/)
40
86
 
41
- **Do not use!**
42
87
 
43
88
  ## Playing in IRB
44
89
 
45
- You can play around in IRB with the SQA framework in two different areas. First is the stocks and indicators. The second is with trading strategies.
90
+ You can play around in IRB with the SQA framework.
91
+
46
92
 
47
93
  ### With Stocks and Indicators
48
94
 
49
- You will need some CSV files.
95
+ You will need some CSV files. If you ask for a stock to which you have not existing historical price data in a CSV file, `SQA` can use either Alpha Vantage or Yahoo Finance to get some data. I like Alpha Vantage better because it has a well defined and documented API. Yahoo Finance on the other hand does not. You can manually download historical stock price data from Yahoo Finance into you `sqa data directory`
96
+
97
+ Historical price data is kept in the `SQA.data_dir` in a CSV file whose name is all lowercase. If you download the CSV file for the stock symbol "AAPL" it should be saved in you `SQA.data_dir` as `aapl.csv`
50
98
 
51
99
  #### Get Historical Prices
52
100
 
53
- Go to https::/finance.yahoo.com and down some historical price data for your favorite stocks. Put those CSV files in to the `sqa_data` directory in your HOME directory.
101
+ Go to https::/finance.yahoo.com and down some historical price data for your favorite stocks. Put those CSV files into the `SQA.data_dir`.
54
102
 
55
103
  You may need to create a `portfolio.csv` file or you may not. TODO
56
104
 
57
- The CSV files will be named by the stock's ticker symbol. For example: AAPL.csv
105
+ The CSV files will be named by the stock's ticker symbol. For example: `aapl.csv`
106
+
107
+ ### Playing in the IRB - Setup
58
108
 
59
109
  ```ruby
60
110
  require 'sqa'
61
- # TODO: See the documentation on configurable items
62
- # Omit to use defaults
63
- SQA::Config.from_file(path_to_config_file)
111
+ require 'sqa/cli'
112
+
113
+ # You can pass a set of CLI options in a String
114
+ SQA.init "-c ~/.sqa.yml"
64
115
 
65
- # initialize framework from configuration values
66
- SQA.init
116
+ aapl = SQA::Stock.new(ticker: 'aapl', source: :alpha_vantage)
117
+ #=> aapl with 1207 data points from 2019-01-02 to 2023-10-17
118
+ ```
119
+
120
+ `aapl.df` is the data frame. It is implemented as a Hashie::Mash obect -- a Hash or Arrays.
121
+
122
+ ```ruby
123
+ aapl.df.keys
124
+ #=> [:timestamp, :open_price, :high_price, :low_price, :close_price, :adj_close_price, :volume]
67
125
 
68
- aapl = SQA::Stock.new('aapl')
126
+ aapl.df.adj_close_price.last(5)
127
+ #=> [179.8, 180.71, 178.85, 178.72, 177.15]
69
128
  ```
70
129
 
71
- `aapl.df` is the Daru::DataFrame
72
- see the `daru` gem for how to manipulate the DataFrame
130
+ `aapl.data` is basic static data, company name, industry etc. It is also implemented as a Hassie::Mash object but is primary treated as a plain hash object.
131
+
132
+ ```ruby
133
+ aapl.data.keys
134
+ #=> [:ticker, :source, :indicators, :overview]
135
+
136
+ aapl.data.source
137
+ => "alpha_vantage"
138
+
139
+ aapl.data.overciew.keys
140
+ => [:symbol, :asset_type, :name, :description, :cik, :exchange, :currency, :country, :sector, :industry, :address, :fiscal_year_end, :latest_quarter, :market_capitalization, :ebitda, :pe_ratio, :peg_ratio, :book_value, :dividend_per_share, :dividend_yield, :eps, :revenue_per_share_ttm, :profit_margin, :operating_margin_ttm, :return_on_assets_ttm, :return_on_equity_ttm, :revenue_ttm, :gross_profit_ttm, :diluted_epsttm, :quarterly_earnings_growth_yoy, :quarterly_revenue_growth_yoy, :analyst_target_price, :trailing_pe, :forward_pe, :price_to_sales_ratio_ttm, :price_to_book_ratio, :ev_to_revenue, :ev_to_ebitda, :beta, :"52_week_high", :"52_week_low", :"50_day_moving_average", :"200_day_moving_average", :shares_outstanding, :dividend_date, :ex_dividend_date]
141
+
142
+ ```
143
+
144
+ ### Playing in the IRB - Statistics
145
+
146
+ Basic statistics are available on all of the SQA::DataFrame arrays.
147
+
148
+ ```ruby
149
+ require 'amazing_print' # to get the ap command
150
+
151
+ # Look at some summary stats on the last 5 days of
152
+ # adjusted closing pricess of AAPL
153
+ ap aapl.df.adj_close_price.last(5).summary
154
+ {
155
+ :frequencies => {
156
+ 179.8 => 1,
157
+ 180.71 => 1,
158
+ 178.85 => 1,
159
+ 178.72 => 1,
160
+ 177.15 => 1
161
+ },
162
+ :max => 180.71,
163
+ :mean => 179.046,
164
+ :median => 178.85,
165
+ :midrange => 178.93,
166
+ :min => 177.15,
167
+ :mode => nil,
168
+ :proportions => {
169
+ 179.8 => 0.2,
170
+ 180.71 => 0.2,
171
+ 178.85 => 0.2,
172
+ 178.72 => 0.2,
173
+ 177.15 => 0.2
174
+ },
175
+ :quartile1 => 178.85,
176
+ :quartile2 => 179.8,
177
+ :quartile3 => 180.71,
178
+ :range => 3.5600000000000023,
179
+ :size => 5,
180
+ :sum => 895.23,
181
+ :sample_coefficient_of_variation => 0.006644656242680533,
182
+ :sample_kurtosis => 2.089087404921432,
183
+ :sample_size => 5,
184
+ :sample_skewness => -0.2163861377512453,
185
+ :sample_standard_deviation => 1.1896991216269788,
186
+ :sample_standard_error => 0.532049621745943,
187
+ :sample_variance => 1.415384000000005,
188
+ :sample_zscores => {
189
+ 179.8 => 0.6337736880639895,
190
+ 180.71 => 1.3986729667618856,
191
+ 178.85 => -0.16474753695031497,
192
+ 178.72 => -0.2740188624785824,
193
+ 177.15 => -1.5936802553969298
194
+ }
195
+ }
196
+ #=> nil
197
+ ```
198
+
199
+ ### Playing in the IRB - Indicators
200
+
73
201
  The SQA::Indicator class methods use Arrays not the DataFrame
74
202
  Here is an example:
75
203
 
76
204
 
77
205
  ```ruby
78
- prices = aapl.df.adj_close_price.to_a
206
+ prices = aapl.df.adj_close_price
79
207
  period = 14 # size of the window in prices to analyze
80
208
 
81
209
  rsi = SQA::Indicator.rsi(prices, period)
210
+ #=> {:rsi=>63.46652828230407, :trend=>:normal}
82
211
  ```
83
212
 
84
- ### With Strategies
213
+ ### Playing in the IRB - Strategies
85
214
 
86
- The strategies work off of an Object that contains the information required to make its recommendation. Build on the previous Ruby snippet ...
215
+ The strategies work off of an Object that contains the information required to make its recommendation. Building on the previous Ruby snippet ...
87
216
 
88
217
  ```ruby
89
218
  require 'ostruct'
@@ -100,19 +229,24 @@ ss.add SQA::Strategy::RSI
100
229
 
101
230
  # This is an Array with each "trade" method
102
231
  # that is defined in each strategy added
103
- ss.strategies
232
+ ap ss.strategies
233
+ [
234
+ [0] SQA::Strategy::Random#trade(vector),
235
+ [1] SQA::Strategy::RSI#trade(vector)
236
+ ]
104
237
 
105
238
  # Execute those strategies
106
239
  results = ss.execute(vector)
240
+ #=> [:hold, :hold]
107
241
  ```
108
242
 
109
243
  `results` is an Array with an entry for each strategy executed. The entries are either :buy, :sell or :hold.
110
244
 
111
245
  Currently the strategies are executed sequentially so the results can easily be mapped back to which strategy produced which result. In the future that will change so that the strategies are executed concurrently. When that change is introduced the entries in the `results` object will change -- most likely to an Array of Hashes.
112
246
 
113
- ### See my **experiments** Repository in the **stocks** Directory
247
+ Any specific strategy may not work on every stock. Using the historical data, it is possible to see which strategy works better for a specific stock. **Of course the statistical motto is that historical performance is not a fail-proof indicator for future performance.**
114
248
 
115
- I have a program `analysis.rb` that I'm writing along with this `sqa` gem. Its intended as a practical example/test case for how the gem can be used to analyze a complete portfolio one stock at a time.
249
+ The strategies that come with the `SQA::Strategy` class are examples only. Its expected that you will come up with your own. If you do, consider sharing them.
116
250
 
117
251
  ## Contributing
118
252
 
@@ -0,0 +1 @@
1
+ 0b3d327017ae67b0ce46082acff8bebdb4a981575e9818418c7279de286a233dde003877f3907b37f3f7e0de236015b4ee4404818d692509c805641862025bc6
@@ -0,0 +1 @@
1
+ be42cf0864e1e35a06e177102943577683057e0023751a35421939fc6e096b0e1d16d2e218e33c9c363b45a5a9f57ed22d4361766365154433f5eb371210fb48
@@ -0,0 +1,58 @@
1
+ # sqa/lib/patches/string.rb
2
+
3
+
4
+ #####################################################################
5
+ ###
6
+ ## File: string.rb
7
+ ## Desc: Monkey to the String class.
8
+ #
9
+
10
+ class String
11
+
12
+ ##################################
13
+ ## Convert CamelCase to camel_case
14
+ def to_underscore
15
+ self.gsub(/::/, '/')
16
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
17
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("- ", "_")
18
+ .downcase
19
+ end
20
+
21
+ alias :to_snakecase :to_underscore
22
+ alias :snakecase :to_underscore
23
+ alias :snake_case :to_underscore
24
+ alias :underscore :to_underscore
25
+
26
+
27
+ ##################################
28
+ ## Convert camel_case to CamelCase
29
+ def to_camelcase
30
+ self.gsub(/\/(.?)/) { "::" + $1.upcase }
31
+ .gsub(/(^|_)(.)/) { $2.upcase }
32
+ end
33
+
34
+ alias :camelcase :to_camelcase
35
+ alias :camelize :to_camelcase
36
+
37
+
38
+ ##################################
39
+ ## Convert "CamelCase" into CamelCase
40
+ def to_constant
41
+ names = self.split('::')
42
+ names.shift if names.empty? || names.first.empty?
43
+
44
+ constant = Object
45
+ names.each do |name|
46
+ if '1.9' == RUBY_VERSION[0,3]
47
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
48
+ else
49
+ constant = constant.const_get(name) || constant.const_missing(name)
50
+ end
51
+ end
52
+ constant
53
+ end
54
+
55
+ alias :constantize :to_constant
56
+ end
57
+
58
+
@@ -74,9 +74,11 @@ class SQA::DataFrame
74
74
  def_delegator :@data, :[]=, :[]=
75
75
 
76
76
 
77
+ # same as values.transpose
78
+ # TODO: do benchmark to see if the transpose method if faster
77
79
  def rows
78
80
  result = []
79
- (0..size - 1).each do |x|
81
+ size.times do |x|
80
82
  entry = row(x)
81
83
  result << entry
82
84
  end
@@ -110,14 +112,14 @@ class SQA::DataFrame
110
112
  end
111
113
 
112
114
 
113
- def append(new_df)
115
+ def append!(new_df)
114
116
  raise(BadParameterError, "Key mismatch") if keys != new_df.keys
115
117
 
116
118
  keys.each do |key|
117
119
  @data[key] += new_df[key]
118
120
  end
119
121
  end
120
- alias_method :concat, :append
122
+ alias_method :concat!, :append!
121
123
 
122
124
 
123
125
  # Creates a new instance with new keys
@@ -144,7 +146,7 @@ class SQA::DataFrame
144
146
  # price: -> (v) {v.to_f.round(3)}
145
147
  # }
146
148
  #
147
- def coerce_vectors(transformers)
149
+ def coerce_vectors!(transformers)
148
150
  transformers.each_pair do |key, transformer|
149
151
  @data[key].map!{|v| transformer.call(v)}
150
152
  end
@@ -170,8 +172,8 @@ class SQA::DataFrame
170
172
  #################################################
171
173
  class << self
172
174
 
173
- def append(base_df, other_df)
174
- base_df.append(other_df)
175
+ def concat(base_df, other_df)
176
+ base_df.concat!(other_df)
175
177
  end
176
178
 
177
179
 
@@ -191,7 +193,7 @@ class SQA::DataFrame
191
193
  end
192
194
 
193
195
  unless transformers.empty?
194
- df.coerce_vectors(transformers)
196
+ df.coerce_vectors!(transformers)
195
197
  end
196
198
 
197
199
  df
data/lib/sqa/stock.rb CHANGED
@@ -104,7 +104,7 @@ class SQA::Stock
104
104
  @df.append(df2)
105
105
 
106
106
  if @df.nrows > df_nrows
107
- @df.to_csv(file_path)
107
+ @df.to_csv(@df_path)
108
108
  end
109
109
  end
110
110
 
data/lib/sqa/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SQA
4
- VERSION = "0.0.17"
4
+ VERSION = "0.0.19"
5
5
 
6
6
  class << self
7
7
  def version
data/lib/sqa.rb CHANGED
@@ -16,13 +16,13 @@ end
16
16
  #############################################
17
17
  ## Additional Libraries
18
18
 
19
- require 'active_support/core_ext/string'
20
- require 'alphavantage' # TODO: add rate limiter to it; ** PR submitted! **
19
+ require 'alphavantage'
21
20
  require 'api_key_manager'
22
21
  require 'amazing_print'
23
- require 'descriptive_statistics'
24
22
  require 'faraday'
25
23
  require 'hashie'
24
+ require 'lite/statistics'
25
+ require 'lite/statistics/monkey_patches' # patch to Enumerable
26
26
  require 'nenv'
27
27
  require 'sem_version'
28
28
  require 'sem_version/core_ext'
@@ -30,6 +30,12 @@ require 'tty-option'
30
30
  require 'tty-table'
31
31
 
32
32
 
33
+ #############################################
34
+ ## Apply core class monkey patches
35
+
36
+ require_relative "patches/string.rb"
37
+
38
+
33
39
  #############################################
34
40
  ## SQA soecufuc code
35
41
 
@@ -45,7 +51,7 @@ require_relative 'sqa/init.rb'
45
51
 
46
52
  require_relative "sqa/config"
47
53
  require_relative "sqa/constants" # SMELL: more app than gem
48
- require_relative "sqa/data_frame" # TODO: drop the daru gem
54
+ require_relative "sqa/data_frame"
49
55
  require_relative "sqa/indicator"
50
56
  require_relative "sqa/portfolio"
51
57
  require_relative "sqa/strategy"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.0.19
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-10-09 00:00:00.000000000 Z
11
+ date: 2023-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 7.0.6
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '='
25
- - !ruby/object:Gem::Version
26
- version: 7.0.6
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: alphavantage
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +39,7 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: descriptive_statistics
42
+ name: faraday
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - ">="
@@ -67,33 +53,33 @@ dependencies:
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
- name: faraday
56
+ name: hashie
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - ">="
59
+ - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '0'
61
+ version: 4.1.0
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - ">="
66
+ - - "~>"
81
67
  - !ruby/object:Gem::Version
82
- version: '0'
68
+ version: 4.1.0
83
69
  - !ruby/object:Gem::Dependency
84
- name: hashie
70
+ name: lite-statistics
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - "~>"
73
+ - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: 4.1.0
75
+ version: '0'
90
76
  type: :runtime
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - "~>"
80
+ - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: 4.1.0
82
+ version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: nenv
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -242,6 +228,8 @@ files:
242
228
  - checksums/sqa-0.0.13.gem.sha512
243
229
  - checksums/sqa-0.0.15.gem.sha512
244
230
  - checksums/sqa-0.0.17.gem.sha512
231
+ - checksums/sqa-0.0.18.gem.sha512
232
+ - checksums/sqa-0.0.19.gem.sha512
245
233
  - checksums/sqa-0.0.2.gem.sha512
246
234
  - checksums/sqa-0.0.3.gem.sha512
247
235
  - checksums/sqa-0.0.4.gem.sha512
@@ -276,6 +264,7 @@ files:
276
264
  - docs/stochastic_oscillator.md
277
265
  - docs/strategy.md
278
266
  - docs/true_range.md
267
+ - lib/patches/string.rb
279
268
  - lib/sqa.rb
280
269
  - lib/sqa/activity.rb
281
270
  - lib/sqa/analysis.rb
@@ -349,7 +338,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
349
338
  - !ruby/object:Gem::Version
350
339
  version: '0'
351
340
  requirements: []
352
- rubygems_version: 3.4.20
341
+ rubygems_version: 3.4.21
353
342
  signing_key:
354
343
  specification_version: 4
355
344
  summary: sqa - Stock Qualitative Analysis