sqa 0.0.21 → 0.0.22

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: 90a60fb96ea11073c750a7e0b36d8a2d8283bbfeff8322907617794b7111502e
4
- data.tar.gz: dbfa9486131b8b39016b46b9ef6188bdfefc279d8a5adc7a79b6c23f1ad1779b
3
+ metadata.gz: d905658af9c43b28516a66c068064fb83391b278885fbc6804a934be463cf316
4
+ data.tar.gz: c8b8699dc6209b3370d72a34a43a29de70f6cf4f7e543766b676be6a249e879c
5
5
  SHA512:
6
- metadata.gz: 975de4af9b0c063a66b8a2292b99c18859d30d49ab6b7fab82416916a1cbf3685b4c9e5f56ea5e1cbe635ac5e9fb67aacf2432ec95ef74f541da9a0edf1e6c61
7
- data.tar.gz: cf25850a673a96bf60fe40cac0ca488a670c8ba8eb489e7c4502beb3b53bc60d1c716a22c4f5c78ceffd66e6ac92323e13b8278988fa3ffd0e4d26554249b908
6
+ metadata.gz: 8351015c1c4b75c8b75d2460820d4d162ad51b9e29d60c0989ecd413485670f6c4d55a65a2f52667bcf1c24bda04df3c6fc8bad196a92b2f8c3319c005e977c0
7
+ data.tar.gz: 120bef4ce4c29cbf5ab412bb918f710f0875243cefef5bb085bcea8c29080b5754a42a313eb24b5b33aa4d5a3667e2147ceb97567941f528712a7ee42c56b32d
@@ -1,4 +1,5 @@
1
1
  label: "## Table of Contents"
2
2
  patterns:
3
+ - "README.md"
3
4
  - "docs/terms_of_use.md"
4
5
  root_dir: "."
data/README.md CHANGED
@@ -4,6 +4,33 @@ This is a very simplistic set of tools for running technical analysis (quantitat
4
4
 
5
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.
6
6
 
7
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
8
+
9
+ ## Table of Contents
10
+
11
+ - [This is a Work in Progress](#this-is-a-work-in-progress)
12
+ - [Installation](#installation)
13
+ - [Semantic Versioning](#semantic-versioning)
14
+ - [Usage](#usage)
15
+ - [Setup a Config File](#setup-a-config-file)
16
+ - [AlphaVantage](#alphavantage)
17
+ - [TradingView](#tradingview)
18
+ - [Yahoo Finance](#yahoo-finance)
19
+ - [Playing in IRB](#playing-in-irb)
20
+ - [With Stocks and Indicators](#with-stocks-and-indicators)
21
+ - [Get Historical Prices](#get-historical-prices)
22
+ - [Playing in the IRB - Setup](#playing-in-the-irb---setup)
23
+ - [Playing in the IRB - Statistics](#playing-in-the-irb---statistics)
24
+ - [Playing in the IRB - Indicators](#playing-in-the-irb---indicators)
25
+ - [Playing in the IRB - Strategies](#playing-in-the-irb---strategies)
26
+ - [Included Program Examples](#included-program-examples)
27
+ - [Analysis](#analysis)
28
+ - [Web](#web)
29
+ - [Contributing](#contributing)
30
+ - [License](#license)
31
+
32
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
33
+
7
34
  ## This is a Work in Progress
8
35
 
9
36
  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](https://github.com/intridea/hashie) library.
@@ -19,7 +46,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
19
46
 
20
47
  gem install sqa
21
48
 
22
- ### Semantic Versioning
49
+ ## Semantic Versioning
23
50
 
24
51
  `sqa` uses the [sem_version](https://github.com/canton7/sem_version) gem to provide a semantic version object. Sure its old; but, so am I. Doesn't mean we can't do the job.
25
52
 
@@ -31,6 +58,10 @@ sqa --version
31
58
 
32
59
  SQA.version # returns SemVersion object
33
60
  exit(1) unless SQA.version >= SemVersion("1.0.0")
61
+
62
+ # Okay, you're right, you could put that kind of version
63
+ # constraint in a Gemfile and let bundler handle the
64
+ # dependencies for you.
34
65
  ```
35
66
 
36
67
  ## Usage
@@ -72,6 +103,9 @@ Examples:
72
103
 
73
104
  WARNING: This is a toy, a play thing, not intended for serious use.
74
105
  ```
106
+
107
+ More about the two included programs `analysis` and `web` later.
108
+
75
109
  ### Setup a Config File
76
110
 
77
111
  You will need to create a directory to store the `sqa` data and a configuration file. You can start by doing this:
@@ -96,7 +130,7 @@ You can also have one data directory and multiple portfolio and trades files wit
96
130
 
97
131
  Put your API key in the system environment variable `AV_API_KEY`
98
132
 
99
- TODO why is it not part of the configuration? ought to be.
133
+ <!-- TODO: why is it not part of the configuration? ought to be. -->
100
134
 
101
135
 
102
136
  ### TradingView
@@ -105,10 +139,23 @@ TODO why is it not part of the configuration? ought to be.
105
139
 
106
140
  Put your API key in the system environment variable `TV_API_KEY`
107
141
 
108
- TODO why is it not part of the configuration? ought to be.
142
+ <!-- TODO: why is it not part of the configuration? ought to be. -->
109
143
 
110
144
  I kinda like their Terms of Use. I've started crafting an [SQA Terms of Use](docs/terms_of_use.md) document based on theirs. I specifically like sections 7 and 8.
111
145
 
146
+ ### Yahoo Finance
147
+
148
+ The finance.yahoo.com website no longer supports an API. To get information from this website you must scrape it. That is how historical / receint stock prices are being obtained in the DataFrame::YahooFinance class. I do not like doing this and do not necessarily recommend using YahooFinance as a source for stock price data.
149
+
150
+ In the SQA::Stock class the default source is AlphaVantage which has its own limitations.
151
+
152
+ This is not to say that finance.yahoo.com has no use. In fact is is the perfect place to go to manually download CSV files of historical stock price data. When you do that through your browser, the CSV file will be placed in your default downloads directory.
153
+
154
+ To use this downed file within the SQA environment it must be moved into your `SQA.`data_dir` with a filename that is all lowercase. The filename must be the stock's symbol with a `.csv` extension. For example if you downloaded the entire historical stock price data for Apple Computer (AAPL) the filename in the SQA.data_dir should be "aapl.csv"
155
+
156
+ You can manually go to the Yahoo Finance website at [https://finance.yahoo.com/quote/AAPL/history?p=AAPL](https://finance.yahoo.com/quote/AAPL/history?p=AAPL)
157
+
158
+
112
159
  ## Playing in IRB
113
160
 
114
161
  You can play around in IRB with the SQA framework.
@@ -124,7 +171,9 @@ Historical price data is kept in the `SQA.data_dir` in a CSV file whose name is
124
171
 
125
172
  Go to [https::/finance.yahoo.com](https::/finance.yahoo.com) and down some historical price data for your favorite stocks. Put those CSV files into the `SQA.data_dir`.
126
173
 
127
- You may need to create a `portfolio.csv` file or you may not. TODO
174
+ You may need to create a `portfolio.csv` file or you may not.
175
+
176
+ <!-- TODO: Add a section on how to create a portfolio fCSV file -->
128
177
 
129
178
  The CSV files will be named by the stock's ticker symbol as lower case. For example: `aapl.csv`
130
179
 
@@ -275,6 +324,24 @@ Any specific strategy may not work on every stock. Using the historical data, it
275
324
 
276
325
  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.
277
326
 
327
+ ## Included Program Examples
328
+
329
+ <!-- TODO: What is the name of these things? From the help text they are called commands. They are treated in the code base as a class under the SQA module. Its easy to change the CLI help text to call these programs rather than commands. -->
330
+
331
+ There are at least two included programs that make use of the `SQA` library.
332
+
333
+ <!-- TODO: These kinds of things need to be in their own repository. -->
334
+
335
+ <!-- TODO: Need to complete the API for invoking one of these "programs" from the sqa cli. -->
336
+
337
+ ### Analysis
338
+
339
+ Does an analysis of a portfollio of stocks.
340
+
341
+ ### Web
342
+
343
+ Provides a browser-based interface to some stuff.
344
+
278
345
  ## Contributing
279
346
 
280
347
  I can always use some help on this stuff. Got an idea for a new indicator or strategy? Want to improve the math? Make the signals better? Let's collaborate!
@@ -1 +1 @@
1
- bd37c208c9c593043ac51fd79e3cf45eac2d432109b13773af13a534b833bbe5277002f03567d2659bc70150593f084db025d8cd08bed3f803db4db7809e7128
1
+ 5e682462398140077e381829872acc847ce0f2a391af4ab7d66c94f8bebf05dc29a760fcdfecfe07886ad23440496973e6f6cdd7012d6db577b923281e1f67b7
@@ -0,0 +1 @@
1
+ 053cf9a393976ae5292918cd7386b9c2e0567788f43525b77ca06ee574a98b39c3d81d43d65358d2d8cf896060e576897484945c119f1f2d57480d9407c0555a
@@ -1,6 +1,12 @@
1
1
  # lib/sqa/data_frame/yahoo_finance.rb
2
2
  # frozen_string_literal: true
3
3
 
4
+ =begin
5
+ The website financial.yahoo.com no longer supports an API.
6
+ To get recent stock historical price updates you have
7
+ to scrape the webpage.
8
+ =end
9
+
4
10
 
5
11
  class SQA::DataFrame
6
12
  class YahooFinance
@@ -26,30 +26,39 @@ class SQA::DataFrame
26
26
  # mapping is a Hash { old_key => new_key }
27
27
  # transformers is also a Hash { key => Proc}
28
28
  def initialize(
29
- aofh_or_hofa= {}, # Array of Hashes or hash of array or hash
29
+ raw_data= {}, # Array of Hashes or hash of array or hash
30
30
  mapping: {}, # { old_key => new_key }
31
31
  transformers: {} # { key => Proc }
32
32
  )
33
33
 
34
- if aofh_or_hofa.is_a? Hash
35
- initialize_hofa(aofh_or_hofa, mapping: mapping)
34
+ if raw_data.is_a? Hash
35
+ initialize_hofa(raw_data, mapping: mapping)
36
36
 
37
- elsif aofh_or_hofa.is_a?(Array) &&
38
- aofh_or_hofa.first.is_a?(Hash)
39
- initialize_aofh(aofh_or_hofa, mapping: mapping)
37
+ elsif raw_data.is_a?(Array) &&
38
+ raw_data.first.is_a?(Hash)
39
+ initialize_aofh(raw_data, mapping: mapping)
40
40
 
41
41
  else
42
42
  raise BadParameterError, "Expecting Hash or Array of Hashes got: #{aofh_or_hofa.class}"
43
43
  end
44
44
 
45
- coerce_vectors!(transformers) unless transformers.empty?
45
+ coerce_vectors!(transformers) if good_data? && !(transformers.nil? || transformers.empty?)
46
+ end
47
+
48
+
49
+ def good_data?
50
+ return false if @data.empty? || @data.values.all?{|v| v.nil? || v.empty?}
51
+
52
+ true
46
53
  end
47
54
 
48
55
 
49
56
  def initialize_aofh(aofh, mapping:)
50
- hofa = self.class.aofh_to_hofa(
57
+ klass = self.class
58
+
59
+ hofa = klass.aofh_to_hofa(
51
60
  aofh,
52
- mapping: mapping
61
+ mapping: mapping
53
62
  )
54
63
 
55
64
  initialize_hofa(hofa, mapping: mapping)
@@ -57,7 +66,8 @@ class SQA::DataFrame
57
66
 
58
67
 
59
68
  def initialize_hofa(hofa, mapping:)
60
- hofa = self.class.normalize_keys(
69
+ klass = self.class
70
+ hofa = klass.normalize_keys(
61
71
  hofa,
62
72
  adapter_mapping: mapping
63
73
  ) unless mapping.empty?
@@ -283,7 +293,7 @@ class SQA::DataFrame
283
293
  end
284
294
  end
285
295
 
286
- # SMELL: This might be necessary
296
+ # SMELL: This might not be necessary
287
297
  normalize_keys(hofa, adapter_mapping: mapping)
288
298
  end
289
299
 
@@ -291,13 +301,14 @@ class SQA::DataFrame
291
301
  def normalize_keys(hofa, adapter_mapping: {})
292
302
  hofa = rename(adapter_mapping, hofa)
293
303
  mapping = generate_mapping(hofa.keys)
304
+
294
305
  rename(mapping, hofa)
295
306
  end
296
307
 
297
308
 
298
309
  def rename(mapping, hofa)
299
310
  mapping.each_pair do |old_key, new_key|
300
- hofa[new_key] = hofa.delete(old_key)
311
+ hofa[new_key] = hofa.delete(old_key) if hofa.has_key?(old_key)
301
312
  end
302
313
 
303
314
  hofa
data/lib/sqa/stock.rb CHANGED
@@ -101,7 +101,7 @@ class SQA::Stock
101
101
  return if df2.nil? # CSV file is up to date.
102
102
 
103
103
  df_nrows = @df.nrows
104
- @df.append(df2)
104
+ @df.append!(df2)
105
105
 
106
106
  if @df.nrows > df_nrows
107
107
  @df.to_csv(@df_path)
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.21"
4
+ VERSION = "0.0.22"
5
5
 
6
6
  class << self
7
7
  def version
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.21
4
+ version: 0.0.22
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-24 00:00:00.000000000 Z
11
+ date: 2023-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: alphavantage
@@ -248,6 +248,7 @@ files:
248
248
  - checksums/sqa-0.0.2.gem.sha512
249
249
  - checksums/sqa-0.0.20.gem.sha512
250
250
  - checksums/sqa-0.0.21.gem.sha512
251
+ - checksums/sqa-0.0.22.gem.sha512
251
252
  - checksums/sqa-0.0.3.gem.sha512
252
253
  - checksums/sqa-0.0.4.gem.sha512
253
254
  - checksums/sqa-0.0.5.gem.sha512