sqa 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.irbrc +3 -0
  3. data/checksums/sqa-0.0.2.gem.sha512 +1 -0
  4. data/docs/average_true_range.md +9 -0
  5. data/docs/data_frame.md +164 -0
  6. data/docs/fibonacci_retracement.md +30 -0
  7. data/docs/identify_wave_condition.md +14 -0
  8. data/docs/peaks_and_valleys.md +11 -0
  9. data/docs/requirements.md +22 -0
  10. data/docs/stochastic_oscillator.md +4 -0
  11. data/docs/strategy.md +5 -0
  12. data/lib/sqa/cli.rb +1 -1
  13. data/lib/sqa/data_frame/yahoo_finance.rb +24 -0
  14. data/lib/sqa/data_frame.rb +16 -0
  15. data/lib/sqa/indicator/average_true_range.rb +22 -9
  16. data/lib/sqa/indicator/bollinger_bands.rb +2 -2
  17. data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +1 -1
  18. data/lib/sqa/indicator/donchian_channel.rb +1 -1
  19. data/lib/sqa/indicator/double_top_bottom_pattern.rb +1 -1
  20. data/lib/sqa/indicator/elliott_wave_theory.rb +57 -0
  21. data/lib/sqa/indicator/exponential_moving_average.rb +25 -0
  22. data/lib/sqa/indicator/exponential_moving_average_trend.rb +36 -0
  23. data/lib/sqa/indicator/fibonacci_retracement.rb +5 -7
  24. data/lib/sqa/indicator/head_and_shoulders_pattern.rb +1 -1
  25. data/lib/sqa/indicator/{classify_market_profile.rb → market_profile.rb} +7 -8
  26. data/lib/sqa/indicator/mean_reversion.rb +1 -1
  27. data/lib/sqa/indicator/momentum.rb +9 -7
  28. data/lib/sqa/indicator/moving_average_convergence_divergence.rb +7 -3
  29. data/lib/sqa/indicator/peaks_and_valleys.rb +29 -0
  30. data/lib/sqa/indicator/{relative_strength_index.md.rb → relative_strength_index.rb} +2 -2
  31. data/lib/sqa/indicator/simple_moving_average.rb +6 -3
  32. data/lib/sqa/indicator/simple_moving_average_trend.rb +15 -14
  33. data/lib/sqa/indicator/stochastic_oscillator.rb +32 -3
  34. data/lib/sqa/indicator/true_range.rb +14 -12
  35. data/lib/sqa/indicator.rb +4 -4
  36. data/lib/sqa/stock.rb +6 -13
  37. data/lib/sqa/strategy.rb +65 -0
  38. data/lib/sqa/version.rb +3 -1
  39. data/lib/sqa.rb +44 -6
  40. metadata +34 -29
  41. data/lib/sqa/datastore/active_record.rb +0 -89
  42. data/lib/sqa/datastore/csv/yahoo_finance.rb +0 -51
  43. data/lib/sqa/datastore/csv.rb +0 -93
  44. data/lib/sqa/datastore/sqlite.rb +0 -7
  45. data/lib/sqa/datastore.rb +0 -6
  46. data/lib/sqa/indicator/average_true_range.md +0 -9
  47. data/lib/sqa/indicator/ema_analysis.rb +0 -70
  48. data/lib/sqa/indicator/fibonacci_retracement.md +0 -3
  49. data/lib/sqa/indicator/identify_wave_condition.md +0 -6
  50. data/lib/sqa/indicator/identify_wave_condition.rb +0 -40
  51. data/lib/sqa/indicator/stochastic_oscillator.md +0 -5
  52. /data/{lib/sqa/indicator → docs}/README.md +0 -0
  53. /data/{lib/sqa/indicator → docs}/bollinger_bands.md +0 -0
  54. /data/{lib/sqa/indicator → docs}/candlestick_pattern_recognizer.md +0 -0
  55. /data/{lib/sqa/indicator → docs}/donchian_channel.md +0 -0
  56. /data/{lib/sqa/indicator → docs}/double_top_bottom_pattern.md +0 -0
  57. /data/{lib/sqa/indicator/ema_analysis.md → docs/exponential_moving_average.md} +0 -0
  58. /data/{lib/sqa/indicator → docs}/head_and_shoulders_pattern.md +0 -0
  59. /data/{lib/sqa/indicator/classify_market_profile.md → docs/market_profile.md} +0 -0
  60. /data/{lib/sqa/indicator → docs}/mean_reversion.md +0 -0
  61. /data/{lib/sqa/indicator → docs}/momentum.md +0 -0
  62. /data/{lib/sqa/indicator → docs}/moving_average_convergence_divergence.md +0 -0
  63. /data/{lib/sqa/indicator → docs}/relative_strength_index.md +0 -0
  64. /data/{lib/sqa/indicator → docs}/simple_moving_average.md +0 -0
  65. /data/{lib/sqa/indicator → docs}/true_range.md +0 -0
@@ -1,51 +0,0 @@
1
- # lib/sqa/datastore/csv/yahoo_finance.rb
2
-
3
- # processes a CSV file downloaded from finance.yahoo.com
4
- # Date,Open,High,Low,Close,Adj Close,Volume
5
-
6
- require 'csv-importer'
7
-
8
- class SQA::Datastore::CSV::YahooFinance
9
- include CSVImporter
10
-
11
- model ::SQA::Activity # an active record like model
12
-
13
- column :date, to: ->(x) { Date.parse(x)}, required: true
14
- column :open, to: ->(x) {x.to_f}, required: true
15
- column :high, to: ->(x) {x.to_f}, required: true
16
- column :low, to: ->(x) {x.to_f}, required: true
17
- column :close, to: ->(x) {x.to_f}, required: true
18
- column :adj_close, to: ->(x) {x.to_f}, required: true
19
- column :volumn, to: ->(x) {x.to_i}, required: true
20
-
21
- # TODO: make the identifier compound [ticker, date]
22
- # so we can put all the data into a single table.
23
-
24
- identifier :date
25
-
26
- when_invalid :skip # or :abort
27
-
28
-
29
- column :email, to: ->(email) { email.downcase }, required: true
30
- column :first_name, as: [ /first.?name/i, /pr(é|e)nom/i ]
31
- column :last_name, as: [ /last.?name/i, "nom" ]
32
- column :published, to: ->(published, user) { user.published_at = published ? Time.now : nil }
33
-
34
-
35
-
36
-
37
- def self.load(ticker)
38
- import = new(file: "#{ticker.upcase}.csv")
39
-
40
- import.valid_header? # => false
41
- import.report.message # => "The following columns are required: email"
42
-
43
- # Assuming the header was valid, let's run the import!
44
-
45
- import.run!
46
- import.report.success? # => true
47
- import.report.message # => "Import completed. 4 created, 2 updated, 1 failed to update" end
48
-
49
- end
50
- end
51
-
@@ -1,93 +0,0 @@
1
- # lib/sqa/datastore/csv.rb
2
-
3
- require 'csv'
4
- require 'forwardable'
5
-
6
- module SQA::Datastore
7
- class CSV
8
- extend Forwardable
9
- def_delegators :@data, :first, :last, :size, :empty?, :[], :map, :select, :reject
10
-
11
- SOURCE_DOMAIN = "https://query1.finance.yahoo.com/v7/finance/download/"
12
- # curl -o AAPL.csv -L --url "https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=345427200&period2=1691712000&interval=1d&events=history&includeAdjustedClose=true"
13
-
14
-
15
- attr_accessor :ticker
16
- attr_accessor :data
17
-
18
- def initialize(ticker, adapter = YahooFinance)
19
- @ticker = ticker
20
- @data_path = Pathname.pwd + "#{ticker.downcase}.csv"
21
- @adapter = adapter
22
- @data = adapter.load(ticker)
23
- end
24
-
25
-
26
- #######################################################################
27
- # Read the CSV file associated with the give ticker symbol
28
- #
29
- # def read_csv_data
30
- # download_historical_prices unless @data_path.exist?
31
-
32
- # csv_data = []
33
-
34
- # ::CSV.foreach(@data_path, headers: true) do |row|
35
- # csv_data << row.to_h
36
- # end
37
-
38
- # csv_data
39
- # end
40
-
41
- #######################################################################
42
- # download a CSV file from https://query1.finance.yahoo.com
43
- # given a stock ticker symbol as a String
44
- # start and end dates
45
- #
46
- # For ticker "aapl" the downloaded file will be named "aapl.csv"
47
- # That filename will be renamed to "aapl_YYYYmmdd.csv" where the
48
- # date suffix is the end_date of the historical data.
49
- #
50
- # def download_historical_prices(
51
- # start_date: Date.new(2019, 1, 1),
52
- # end_date: previous_dow(:friday, Date.today)
53
- # )
54
-
55
- # start_timestamp = start_date.to_time.to_i # Convert to unix timestamp
56
- # end_timestamp = end_date.to_time.to_i
57
-
58
- # user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0"
59
-
60
- # # TODO: replace curl with Faraday
61
-
62
- # `curl -A "#{user_agent}" --cookie-jar cookies.txt -o #{@data_path} -L --url "#{SOURCE_DOMAIN}/#{ticker.upcase}?period1=#{start_timestamp}&period2=#{end_timestamp}&interval=1d&events=history&includeAdjustedClose=true"`
63
-
64
- # check_csv_file
65
- # end
66
-
67
-
68
- # def check_csv_file
69
- # f = File.open(@data_path, 'r')
70
- # c1 = f.read(1)
71
-
72
- # if '{' == c1
73
- # error_msg = JSON.parse("#{c1}#{f.read}")
74
- # raise "Not OK: #{error_msg}"
75
- # end
76
- # end
77
- end
78
- end
79
-
80
- __END__
81
-
82
- {
83
- "finance": {
84
- "error": {
85
- "code": "Unauthorized",
86
- "description": "Invalid cookie"
87
- }
88
- }
89
- }
90
-
91
-
92
-
93
-
@@ -1,7 +0,0 @@
1
- # lib/sqa/datastore/sqlite.rb
2
-
3
- module Datastore
4
- class Sqlite
5
- def initialize(ticker); end
6
- end
7
- end
data/lib/sqa/datastore.rb DELETED
@@ -1,6 +0,0 @@
1
- # lib/sqa/datastore.rb
2
-
3
- require_relative 'datastore/csv'
4
- require_relative 'datastore/active_record'
5
-
6
- # require_relative 'datastore/sqlite'
@@ -1,9 +0,0 @@
1
- # Average True Range
2
-
3
- Calculates the Average True Range (ATR) for a given set of price data.
4
-
5
- The Average True Range is an indicator that calculates the average of the True Range values over a specified period. It provides a measure of the average volatility of a security over that period.
6
-
7
- The ATR is commonly used to assess the volatility of a security, identify potential trend reversals, and determine appropriate stop-loss levels. Higher ATR values indicate higher volatility, while lower ATR values indicate lower volatility.
8
-
9
- For example, a 14-day Average True Range would calculate the average of the True Range values over the past 14 trading days. Traders and analysts may use this indicator to set stop-loss levels based on the average volatility of the security.
@@ -1,70 +0,0 @@
1
- # lib/sqa/indicator/ema_analysis.rb
2
-
3
- module SQA::Indicator; class << self
4
-
5
- def ema_analysis(
6
- prices, # Array of prices
7
- period # Integer number of entries to consider
8
- )
9
- return {} if prices.empty? || period <= 0
10
-
11
- ema_values = []
12
- ema_values << prices.first
13
-
14
- multiplier = (2.0 / (period + 1))
15
-
16
- (1...prices.length).each do |i|
17
- ema = (prices[i] - ema_values.last) * multiplier + ema_values.last
18
- ema_values << ema.round(2)
19
- end
20
-
21
- analysis = {}
22
-
23
- analysis[:ema_values] = ema_values
24
- analysis[:trend] = ema_determine_trend(ema_values)
25
- analysis[:support] = ema_determine_support(ema_values)
26
- analysis[:resistance] = ema_determine_resistance(ema_values)
27
-
28
- analysis
29
- end
30
-
31
-
32
- # @param ema_values [Array] An array of EMA values.
33
- # @return [Symbol] The trend: :up, :down, or :sideways.
34
- #
35
- private def ema_determine_trend(ema_values)
36
- return :sideways if ema_values.empty?
37
-
38
- last_ema = ema_values.last
39
- previous_ema = ema_values[-2]
40
-
41
- if last_ema > previous_ema
42
- :up
43
- elsif last_ema < previous_ema
44
- :down
45
- else
46
- :sideways
47
- end
48
- end
49
-
50
-
51
- # @param ema_values [Array] An array of EMA values.
52
- # @return [Float] The support level.
53
- #
54
- private def ema_determine_support(ema_values)
55
- return 0.0 if ema_values.empty?
56
-
57
- ema_values.min
58
- end
59
-
60
-
61
- # @param ema_values [Array] An array of EMA values.
62
- # @return [Float] The resistance level.
63
- private def ema_determine_resistance(ema_values)
64
- return 0.0 if ema_values.empty?
65
-
66
- ema_values.max
67
- end
68
-
69
- end; end
70
-
@@ -1,3 +0,0 @@
1
- # Fibonacci Retracement
2
-
3
- Fibonacci retracement uses Fibonacci ratios to identify potential support and resistance levels based on the price's previous significant moves.
@@ -1,6 +0,0 @@
1
- # Wave Theory
2
-
3
- Wave theory, such as Elliott Wave Theory, suggests that price movements follow repetitive patterns or waves. It aims to identify and predict these patterns to make trading decisions.
4
-
5
- Identifies a wave condition in a stock's price history based on a given price series.
6
-
@@ -1,40 +0,0 @@
1
- # lib/sqa/indicator/identify_wave_condition.rb
2
-
3
- module SQA::Indicator; class << self
4
-
5
- def identify_wave_condition?(
6
- prices, # Array of prices
7
- wave_length, # Integer expected length of a wave pattern
8
- tolerance # Float delta change in price that would indicate a wave
9
- )
10
- return false if prices.length < wave_length
11
-
12
- wave_start = 0
13
- wave_end = wave_length - 1
14
-
15
- while wave_end < prices.length
16
- wave = prices[wave_start..wave_end]
17
-
18
- if wave.length == wave_length &&
19
- wave_pattern?(wave, tolerance)
20
- return true
21
- end
22
-
23
- wave_start += 1
24
- wave_end += 1
25
- end
26
-
27
- false
28
- end
29
-
30
-
31
- private def wave_pattern?(wave, tolerance)
32
- wave.each_cons(2) do |a, b|
33
- return false if (b - a).abs > tolerance
34
- end
35
-
36
- true
37
- end
38
-
39
- end; end
40
-
@@ -1,5 +0,0 @@
1
- # Stochastic Oscillator
2
-
3
- Calculates the Stochastic Oscillator for a given set of price data.
4
-
5
- Stochastic Oscillator: The Stochastic Oscillator compares a security's closing price to its price range over a specified period. It helps identify potential trend reversals and overbought/oversold conditions.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes