sqa 0.0.14 → 0.0.17
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/README.md +4 -0
- data/checksums/sqa-0.0.15.gem.sha512 +1 -0
- data/checksums/sqa-0.0.17.gem.sha512 +1 -0
- data/docs/alpha_vantage_technical_indicators.md +62 -0
- data/lib/sqa/cli.rb +0 -1
- data/lib/sqa/config.rb +7 -6
- data/lib/sqa/data_frame/alpha_vantage.rb +24 -71
- data/lib/sqa/data_frame/yahoo_finance.rb +4 -48
- data/lib/sqa/data_frame.rb +282 -32
- data/lib/sqa/errors.rb +27 -3
- data/lib/sqa/init.rb +51 -0
- data/lib/sqa/stock.rb +102 -45
- data/lib/sqa/strategy.rb +1 -1
- data/lib/sqa/version.rb +1 -4
- data/lib/sqa/web.rb +1 -1
- data/lib/sqa.rb +33 -54
- metadata +25 -71
- data/checksums/sqa-0.0.14.gem.sha512 +0 -1
- data/lib/patches/daru/category.rb +0 -19
- data/lib/patches/daru/data_frame.rb +0 -19
- data/lib/patches/daru/plotting/svg-graph/category.rb +0 -55
- data/lib/patches/daru/plotting/svg-graph/dataframe.rb +0 -105
- data/lib/patches/daru/plotting/svg-graph/vector.rb +0 -102
- data/lib/patches/daru/plotting/svg-graph.rb +0 -7
- data/lib/patches/daru/vector.rb +0 -19
- data/lib/patches/daru.rb +0 -19
    
        data/lib/sqa/errors.rb
    CHANGED
    
    | @@ -1,6 +1,30 @@ | |
| 1 1 | 
             
            # lib/sqa/errors.rb
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 3 | 
            +
            # raised when a method is still in TODO state
         | 
| 4 | 
            +
            class ApiError < RuntimeError
         | 
| 5 | 
            +
              def self.raise(why)
         | 
| 6 | 
            +
                puts "="*64
         | 
| 7 | 
            +
                puts "== API Error"
         | 
| 8 | 
            +
                puts why
         | 
| 9 | 
            +
                puts
         | 
| 10 | 
            +
                puts "Callback trace:"
         | 
| 11 | 
            +
                puts caller
         | 
| 12 | 
            +
                puts "="*64
         | 
| 13 | 
            +
                super
         | 
| 14 | 
            +
              end
         | 
| 6 15 | 
             
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            # raised when a method is still in TODO state
         | 
| 18 | 
            +
            class NotImplemented < RuntimeError
         | 
| 19 | 
            +
              def self.raise
         | 
| 20 | 
            +
                puts "="*64
         | 
| 21 | 
            +
                puts "== Not Yet Implemented"
         | 
| 22 | 
            +
                puts "Callback trace:"
         | 
| 23 | 
            +
                puts caller
         | 
| 24 | 
            +
                puts "="*64
         | 
| 25 | 
            +
                super
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            # raised when an API contract is broken
         | 
| 30 | 
            +
            class BadParameterError < ArgumentError; end
         | 
    
        data/lib/sqa/init.rb
    ADDED
    
    | @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            # sqa/lib/sqa/init.rb
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module SQA
         | 
| 4 | 
            +
            	class << self
         | 
| 5 | 
            +
            		@@config 	= nil
         | 
| 6 | 
            +
            		@@av 			= ApiKeyManager::RateLimited.new(
         | 
| 7 | 
            +
            									api_keys: 		ENV['AV_API_KEYS'],
         | 
| 8 | 
            +
            									delay: 				true,
         | 
| 9 | 
            +
            									rate_count: 	ENV['AV_RATE_CNT'] ||  5,
         | 
| 10 | 
            +
            									rate_period: 	ENV['AV_RATE_PER'] || 60
         | 
| 11 | 
            +
            								)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            		# Initializes the SQA modules
         | 
| 14 | 
            +
            		# returns the configuration
         | 
| 15 | 
            +
            		#
         | 
| 16 | 
            +
            		def init(argv=ARGV)
         | 
| 17 | 
            +
            			if argv.is_a? String
         | 
| 18 | 
            +
            				argv = argv.split()
         | 
| 19 | 
            +
            			end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
            			# Ran at SQA::Config elaboration time
         | 
| 23 | 
            +
            			# @@config = Config.new
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            			if defined? CLI
         | 
| 26 | 
            +
            				CLI.run(argv)
         | 
| 27 | 
            +
            			else
         | 
| 28 | 
            +
            				# There are no real command line parameters
         | 
| 29 | 
            +
            				# because the sqa gem is being required within
         | 
| 30 | 
            +
            				# the context of a larger program.
         | 
| 31 | 
            +
            			end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            			config.data_dir = homify(config.data_dir)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            			config
         | 
| 36 | 
            +
            		end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            		def av() 								= @@av
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            		def debug?() 						= @@config.debug?
         | 
| 41 | 
            +
            		def verbose?() 					= @@config.verbose?
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            		def homify(filepath) 		= filepath.gsub(/^~/, Nenv.home)
         | 
| 44 | 
            +
            		def data_dir() 					= Pathname.new(config.data_dir)
         | 
| 45 | 
            +
            		def config()            = @@config
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            		def config=(an_object)
         | 
| 48 | 
            +
            			@@config = an_object
         | 
| 49 | 
            +
            		end
         | 
| 50 | 
            +
            	end
         | 
| 51 | 
            +
            end
         | 
    
        data/lib/sqa/stock.rb
    CHANGED
    
    | @@ -1,91 +1,148 @@ | |
| 1 1 | 
             
            # lib/sqa/stock.rb
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'active_support/core_ext/string' # for String#underscore
         | 
| 4 | 
            -
            require 'hashie' # for Hashie::Mash
         | 
| 5 | 
            -
             | 
| 6 3 |  | 
| 7 4 | 
             
            # SMELL:  SQA::Stock is now pretty coupled to the Alpha Vantage
         | 
| 8 5 | 
             
            #         API service.  Should that stuff be extracted into a
         | 
| 9 6 | 
             
            #         separate class and injected by the requiring program?
         | 
| 10 7 |  | 
| 11 8 | 
             
            class SQA::Stock
         | 
| 9 | 
            +
              extend Forwardable
         | 
| 10 | 
            +
             | 
| 12 11 | 
             
              CONNECTION = Faraday.new(url: "https://www.alphavantage.co")
         | 
| 13 12 |  | 
| 14 | 
            -
              attr_accessor : | 
| 15 | 
            -
              attr_accessor :df | 
| 16 | 
            -
             | 
| 17 | 
            -
              attr_accessor : | 
| 18 | 
            -
              attr_accessor : | 
| 13 | 
            +
              attr_accessor :data # General Info      -- SQA::DataFrame::Data
         | 
| 14 | 
            +
              attr_accessor :df   # Historical Prices -- SQA::DataFrame::Data
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              attr_accessor :klass        # class of historical and current prices
         | 
| 17 | 
            +
              attr_accessor :transformers # procs for changing column values from String to Numeric
         | 
| 19 18 |  | 
| 20 19 | 
             
              def initialize(
         | 
| 21 20 | 
             
                    ticker:,
         | 
| 22 | 
            -
                    source: :alpha_vantage | 
| 23 | 
            -
                    type:   :csv
         | 
| 21 | 
            +
                    source: :alpha_vantage
         | 
| 24 22 | 
             
                  )
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                @ticker     = ticker.downcase
         | 
| 25 | 
            +
                @source     = source
         | 
| 26 | 
            +
             | 
| 25 27 | 
             
                raise "Invalid Ticker #{ticker}" unless SQA::Ticker.valid?(ticker)
         | 
| 26 28 |  | 
| 27 | 
            -
                 | 
| 28 | 
            -
                 | 
| 29 | 
            -
                #       save an additiona hash lookup?
         | 
| 29 | 
            +
                @data_path  = SQA.data_dir + "#{@ticker}.json"
         | 
| 30 | 
            +
                @df_path    = SQA.data_dir + "#{@ticker}.csv"
         | 
| 30 31 |  | 
| 31 | 
            -
                 | 
| 32 | 
            +
                @klass         = "SQA::DataFrame::#{@source.to_s.camelize}".constantize
         | 
| 33 | 
            +
                @transformers  = "SQA::DataFrame::#{@source.to_s.camelize}::TRANSFORMERS".constantize
         | 
| 32 34 |  | 
| 33 | 
            -
                @ | 
| 34 | 
            -
             | 
| 35 | 
            -
                 | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 35 | 
            +
                if @data_path.exist?
         | 
| 36 | 
            +
                  load
         | 
| 37 | 
            +
                else
         | 
| 38 | 
            +
                  create
         | 
| 39 | 
            +
                  update
         | 
| 40 | 
            +
                  save
         | 
| 41 | 
            +
                end
         | 
| 39 42 |  | 
| 40 43 | 
             
                update_the_dataframe
         | 
| 41 44 | 
             
              end
         | 
| 42 45 |  | 
| 43 46 |  | 
| 44 | 
            -
              def  | 
| 45 | 
            -
                 | 
| 46 | 
            -
             | 
| 47 | 
            +
              def load
         | 
| 48 | 
            +
                @data = SQA::DataFrame::Data.new(
         | 
| 49 | 
            +
                          JSON.parse(@data_path.read)
         | 
| 50 | 
            +
                        )
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 54 | 
            +
              def create
         | 
| 55 | 
            +
                @data =
         | 
| 56 | 
            +
                  SQA::DataFrame::Data.new(
         | 
| 57 | 
            +
                    {
         | 
| 58 | 
            +
                      ticker:       @ticker,
         | 
| 59 | 
            +
                      source:       @source,
         | 
| 60 | 
            +
                      indicators:   { xyzzy: "Magic" },
         | 
| 61 | 
            +
                    }
         | 
| 62 | 
            +
                  )
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
             | 
| 66 | 
            +
              def update
         | 
| 67 | 
            +
                merge_overview
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
             | 
| 71 | 
            +
              def save
         | 
| 72 | 
            +
                @data_path.write @data.to_json
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
             | 
| 76 | 
            +
              def_delegator :@data, :ticker,      :ticker
         | 
| 77 | 
            +
              def_delegator :@data, :name,        :name
         | 
| 78 | 
            +
              def_delegator :@data, :exchange,    :exchange
         | 
| 79 | 
            +
              def_delegator :@data, :source,      :source
         | 
| 80 | 
            +
              def_delegator :@data, :indicators,  :indicators
         | 
| 81 | 
            +
              def_delegator :@data, :indicators=, :indicators=
         | 
| 82 | 
            +
              def_delegator :@data, :overview,    :overview
         | 
| 47 83 |  | 
| 48 | 
            -
                df1_nrows = df1.nrows
         | 
| 49 | 
            -
                @df       = @klass.append(df1, df2)
         | 
| 50 84 |  | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 85 | 
            +
             | 
| 86 | 
            +
              def update_the_dataframe
         | 
| 87 | 
            +
                if @df_path.exist?
         | 
| 88 | 
            +
                  @df     = SQA::DataFrame.load(
         | 
| 89 | 
            +
                    source:       @df_path,
         | 
| 90 | 
            +
                    transformers: @transformers
         | 
| 91 | 
            +
                  )
         | 
| 92 | 
            +
                else
         | 
| 93 | 
            +
                  @df     = klass.recent(@ticker, full: true)
         | 
| 94 | 
            +
                  @df.to_csv(@df_path)
         | 
| 95 | 
            +
                  return
         | 
| 53 96 | 
             
                end
         | 
| 54 97 |  | 
| 55 | 
            -
                 | 
| 56 | 
            -
                 | 
| 57 | 
            -
             | 
| 58 | 
            -
                 | 
| 98 | 
            +
                from_date = Date.parse(@df.timestamp.last) + 1
         | 
| 99 | 
            +
                df2       = klass.recent(@ticker, from_date: from_date)
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                return if df2.nil?  # CSV file is up to date.
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                df_nrows  = @df.nrows
         | 
| 104 | 
            +
                @df.append(df2)
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                if @df.nrows > df_nrows
         | 
| 107 | 
            +
                  @df.to_csv(file_path)
         | 
| 108 | 
            +
                end
         | 
| 59 109 | 
             
              end
         | 
| 60 110 |  | 
| 111 | 
            +
             | 
| 61 112 | 
             
              def to_s
         | 
| 62 113 | 
             
                "#{ticker} with #{@df.size} data points from #{@df.timestamp.first} to #{@df.timestamp.last}"
         | 
| 63 114 | 
             
              end
         | 
| 115 | 
            +
              alias_method :inspect, :to_s
         | 
| 64 116 |  | 
| 65 | 
            -
              # TODO: Turn this into a class Stock::Overview
         | 
| 66 | 
            -
              #       which is a sub-class of Hashie::Dash
         | 
| 67 | 
            -
              def overview
         | 
| 68 | 
            -
                return @overview unless @overview.nil?
         | 
| 69 117 |  | 
| 118 | 
            +
              def merge_overview
         | 
| 70 119 | 
             
                temp = JSON.parse(
         | 
| 71 | 
            -
                  CONNECTION.get("/query?function=OVERVIEW&symbol=#{ | 
| 120 | 
            +
                  CONNECTION.get("/query?function=OVERVIEW&symbol=#{ticker.upcase}&apikey=#{SQA.av.key}")
         | 
| 72 121 | 
             
                    .to_hash[:body]
         | 
| 73 122 | 
             
                )
         | 
| 74 123 |  | 
| 124 | 
            +
                if temp.has_key? "Information"
         | 
| 125 | 
            +
                  ApiError.raise(temp["Information"])
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 75 128 | 
             
                # TODO: CamelCase hash keys look common in Alpha Vantage
         | 
| 76 129 | 
             
                #       JSON; look at making a special Hashie-based class
         | 
| 77 130 | 
             
                #       to convert the keys to normal Ruby standards.
         | 
| 78 131 |  | 
| 79 132 | 
             
                temp2 = {}
         | 
| 80 133 |  | 
| 81 | 
            -
                string_values = %w[ address asset_type cik country currency | 
| 134 | 
            +
                string_values = %w[ address asset_type cik country currency
         | 
| 135 | 
            +
                                    description dividend_date ex_dividend_date
         | 
| 136 | 
            +
                                    exchange fiscal_year_end industry latest_quarter
         | 
| 137 | 
            +
                                    name sector symbol
         | 
| 138 | 
            +
                                  ]
         | 
| 82 139 |  | 
| 83 140 | 
             
                temp.keys.each do |k|
         | 
| 84 141 | 
             
                  new_k         = k.underscore
         | 
| 85 142 | 
             
                  temp2[new_k]  = string_values.include?(new_k) ? temp[k] : temp[k].to_f
         | 
| 86 143 | 
             
                end
         | 
| 87 144 |  | 
| 88 | 
            -
                @overview =  | 
| 145 | 
            +
                @data.overview = temp2
         | 
| 89 146 | 
             
              end
         | 
| 90 147 |  | 
| 91 148 |  | 
| @@ -101,13 +158,13 @@ class SQA::Stock | |
| 101 158 | 
             
                def top
         | 
| 102 159 | 
             
                  return @@top unless @@top.nil?
         | 
| 103 160 |  | 
| 104 | 
            -
                   | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
                  )
         | 
| 161 | 
            +
                  a_hash  = JSON.parse(
         | 
| 162 | 
            +
                              CONNECTION.get(
         | 
| 163 | 
            +
                                "/query?function=TOP_GAINERS_LOSERS&apikey=#{SQA.av.key}"
         | 
| 164 | 
            +
                              ).to_hash[:body]
         | 
| 165 | 
            +
                            )
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  mash = Hashie::Mash.new(a_hash)
         | 
| 111 168 |  | 
| 112 169 | 
             
                  keys = mash.top_gainers.first.keys
         | 
| 113 170 |  | 
    
        data/lib/sqa/strategy.rb
    CHANGED
    
    | @@ -8,7 +8,7 @@ class SQA::Strategy | |
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 10 | 
             
              def add(a_strategy)
         | 
| 11 | 
            -
                raise  | 
| 11 | 
            +
                raise BadParameterError unless [Class, Method].include? a_strategy.class
         | 
| 12 12 |  | 
| 13 13 | 
             
                a_proc  = if Class == a_strategy.class
         | 
| 14 14 | 
             
                            a_strategy.method(:trade)
         | 
    
        data/lib/sqa/version.rb
    CHANGED
    
    
    
        data/lib/sqa/web.rb
    CHANGED
    
    
    
        data/lib/sqa.rb
    CHANGED
    
    | @@ -1,77 +1,56 @@ | |
| 1 1 | 
             
            # lib/sqa.rb
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
            require 'active_support/core_ext/string'
         | 
| 6 | 
            -
            require 'amazing_print'
         | 
| 7 | 
            -
            require 'daru'
         | 
| 8 | 
            -
            require 'date'
         | 
| 9 | 
            -
            require 'descriptive_statistics'
         | 
| 10 | 
            -
            require 'nenv'
         | 
| 11 | 
            -
            require 'pathname'
         | 
| 4 | 
            +
            # TODO: Create a new gem for the dumbstockapi website
         | 
| 12 5 |  | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 6 | 
            +
            #############################################
         | 
| 7 | 
            +
            ## Standard Libraries
         | 
| 15 8 |  | 
| 9 | 
            +
            require 'date'
         | 
| 10 | 
            +
            require 'pathname'
         | 
| 16 11 |  | 
| 17 12 | 
             
            unless defined?(HOME)
         | 
| 18 | 
            -
            	HOME = Pathname.new( | 
| 13 | 
            +
            	HOME = Pathname.new(ENV['HOME'])
         | 
| 19 14 | 
             
            end
         | 
| 20 15 |  | 
| 16 | 
            +
            #############################################
         | 
| 17 | 
            +
            ## Additional Libraries
         | 
| 21 18 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
            			# Ran at SQA::Config elaboration time
         | 
| 36 | 
            -
            			# @@config = Config.new
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            			if defined? CLI
         | 
| 39 | 
            -
            				CLI.run(argv)
         | 
| 40 | 
            -
            			else
         | 
| 41 | 
            -
            				# There are no real command line parameters
         | 
| 42 | 
            -
            				# because the sqa gem is being required within
         | 
| 43 | 
            -
            				# the context of a larger program.
         | 
| 44 | 
            -
            			end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
            			config.data_dir = homify(config.data_dir)
         | 
| 19 | 
            +
            require 'active_support/core_ext/string'
         | 
| 20 | 
            +
            require 'alphavantage' 	# TODO: add rate limiter to it; ** PR submitted! **
         | 
| 21 | 
            +
            require 'api_key_manager'
         | 
| 22 | 
            +
            require 'amazing_print'
         | 
| 23 | 
            +
            require 'descriptive_statistics'
         | 
| 24 | 
            +
            require 'faraday'
         | 
| 25 | 
            +
            require 'hashie'
         | 
| 26 | 
            +
            require 'nenv'
         | 
| 27 | 
            +
            require 'sem_version'
         | 
| 28 | 
            +
            require 'sem_version/core_ext'
         | 
| 29 | 
            +
            require 'tty-option'
         | 
| 30 | 
            +
            require 'tty-table'
         | 
| 47 31 |  | 
| 48 | 
            -
            			Daru.lazy_update 			= config.lazy_update
         | 
| 49 | 
            -
            			Daru.plotting_library = config.plotting_library
         | 
| 50 32 |  | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 33 | 
            +
            #############################################
         | 
| 34 | 
            +
            ## SQA soecufuc code
         | 
| 53 35 |  | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 36 | 
            +
            require_relative "sqa/version"
         | 
| 37 | 
            +
            require_relative "sqa/errors"
         | 
| 56 38 |  | 
| 57 | 
            -
             | 
| 58 | 
            -
            		def data_dir() 					= Pathname.new(config.data_dir)
         | 
| 59 | 
            -
            		def config()            = @@config
         | 
| 39 | 
            +
            require_relative 'sqa/init.rb'
         | 
| 60 40 |  | 
| 61 | 
            -
            		def config=(an_object)
         | 
| 62 | 
            -
            			@@config = an_object
         | 
| 63 | 
            -
            		end
         | 
| 64 | 
            -
            	end
         | 
| 65 | 
            -
            end
         | 
| 66 41 |  | 
| 67 | 
            -
            #  | 
| 42 | 
            +
            # TODO: Some of these components make direct calls to the
         | 
| 43 | 
            +
            # 			Alpha Vantage API.  Convert them to use the
         | 
| 44 | 
            +
            # 			alphavantage gem.
         | 
| 68 45 |  | 
| 69 46 | 
             
            require_relative "sqa/config"
         | 
| 70 | 
            -
            require_relative "sqa/constants"
         | 
| 71 | 
            -
            require_relative "sqa/data_frame"
         | 
| 47 | 
            +
            require_relative "sqa/constants" 	# SMELL: more app than gem
         | 
| 48 | 
            +
            require_relative "sqa/data_frame" # TODO: drop the daru gem
         | 
| 72 49 | 
             
            require_relative "sqa/indicator"
         | 
| 73 50 | 
             
            require_relative "sqa/portfolio"
         | 
| 74 51 | 
             
            require_relative "sqa/strategy"
         | 
| 75 52 | 
             
            require_relative "sqa/stock"
         | 
| 76 53 | 
             
            require_relative "sqa/ticker"
         | 
| 77 | 
            -
            require_relative "sqa/trade"
         | 
| 54 | 
            +
            require_relative "sqa/trade" # SMELL: Not really a core gem; more of an application thing
         | 
| 55 | 
            +
             | 
| 56 | 
            +
             | 
    
        metadata
    CHANGED
    
    | @@ -1,45 +1,31 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: sqa
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.17
         | 
| 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-09 | 
| 11 | 
            +
            date: 2023-10-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 18 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: '0'
         | 
| 20 | 
            -
              type: :runtime
         | 
| 21 | 
            -
              prerelease: false
         | 
| 22 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            -
                requirements:
         | 
| 24 | 
            -
                - - ">="
         | 
| 25 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: '0'
         | 
| 27 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            -
              name: daru
         | 
| 29 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            -
                requirements:
         | 
| 31 | 
            -
                - - ">="
         | 
| 17 | 
            +
                - - '='
         | 
| 32 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version:  | 
| 19 | 
            +
                    version: 7.0.6
         | 
| 34 20 | 
             
              type: :runtime
         | 
| 35 21 | 
             
              prerelease: false
         | 
| 36 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 23 | 
             
                requirements:
         | 
| 38 | 
            -
                - -  | 
| 24 | 
            +
                - - '='
         | 
| 39 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version:  | 
| 26 | 
            +
                    version: 7.0.6
         | 
| 41 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            -
              name:  | 
| 28 | 
            +
              name: alphavantage
         | 
| 43 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 30 | 
             
                requirements:
         | 
| 45 31 | 
             
                - - ">="
         | 
| @@ -53,7 +39,7 @@ dependencies: | |
| 53 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 40 | 
             
                    version: '0'
         | 
| 55 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            -
              name:  | 
| 42 | 
            +
              name: api_key_manager
         | 
| 57 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 44 | 
             
                requirements:
         | 
| 59 45 | 
             
                - - ">="
         | 
| @@ -67,35 +53,7 @@ dependencies: | |
| 67 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 54 | 
             
                    version: '0'
         | 
| 69 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            -
              name:  | 
| 71 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            -
                requirements:
         | 
| 73 | 
            -
                - - ">="
         | 
| 74 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: '0'
         | 
| 76 | 
            -
              type: :runtime
         | 
| 77 | 
            -
              prerelease: false
         | 
| 78 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            -
                requirements:
         | 
| 80 | 
            -
                - - ">="
         | 
| 81 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version: '0'
         | 
| 83 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 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
         | 
| 56 | 
            +
              name: descriptive_statistics
         | 
| 99 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 58 | 
             
                requirements:
         | 
| 101 59 | 
             
                - - ">="
         | 
| @@ -109,7 +67,7 @@ dependencies: | |
| 109 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 68 | 
             
                    version: '0'
         | 
| 111 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            -
              name:  | 
| 70 | 
            +
              name: faraday
         | 
| 113 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 72 | 
             
                requirements:
         | 
| 115 73 | 
             
                - - ">="
         | 
| @@ -123,21 +81,21 @@ dependencies: | |
| 123 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 82 | 
             
                    version: '0'
         | 
| 125 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 126 | 
            -
              name:  | 
| 84 | 
            +
              name: hashie
         | 
| 127 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 86 | 
             
                requirements:
         | 
| 129 | 
            -
                - - " | 
| 87 | 
            +
                - - "~>"
         | 
| 130 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            -
                    version:  | 
| 89 | 
            +
                    version: 4.1.0
         | 
| 132 90 | 
             
              type: :runtime
         | 
| 133 91 | 
             
              prerelease: false
         | 
| 134 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 93 | 
             
                requirements:
         | 
| 136 | 
            -
                - - " | 
| 94 | 
            +
                - - "~>"
         | 
| 137 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            -
                    version:  | 
| 96 | 
            +
                    version: 4.1.0
         | 
| 139 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            -
              name:  | 
| 98 | 
            +
              name: nenv
         | 
| 141 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 100 | 
             
                requirements:
         | 
| 143 101 | 
             
                - - ">="
         | 
| @@ -151,7 +109,7 @@ dependencies: | |
| 151 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 152 110 | 
             
                    version: '0'
         | 
| 153 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 154 | 
            -
              name:  | 
| 112 | 
            +
              name: sem_version
         | 
| 155 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 156 114 | 
             
                requirements:
         | 
| 157 115 | 
             
                - - ">="
         | 
| @@ -165,7 +123,7 @@ dependencies: | |
| 165 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| 166 124 | 
             
                    version: '0'
         | 
| 167 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 168 | 
            -
              name: tty- | 
| 126 | 
            +
              name: tty-option
         | 
| 169 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 170 128 | 
             
                requirements:
         | 
| 171 129 | 
             
                - - ">="
         | 
| @@ -282,7 +240,8 @@ files: | |
| 282 240 | 
             
            - checksums/sqa-0.0.11.gem.sha512
         | 
| 283 241 | 
             
            - checksums/sqa-0.0.12.gem.sha512
         | 
| 284 242 | 
             
            - checksums/sqa-0.0.13.gem.sha512
         | 
| 285 | 
            -
            - checksums/sqa-0.0. | 
| 243 | 
            +
            - checksums/sqa-0.0.15.gem.sha512
         | 
| 244 | 
            +
            - checksums/sqa-0.0.17.gem.sha512
         | 
| 286 245 | 
             
            - checksums/sqa-0.0.2.gem.sha512
         | 
| 287 246 | 
             
            - checksums/sqa-0.0.3.gem.sha512
         | 
| 288 247 | 
             
            - checksums/sqa-0.0.4.gem.sha512
         | 
| @@ -293,6 +252,7 @@ files: | |
| 293 252 | 
             
            - checksums/sqa-0.0.9.gem.sha512
         | 
| 294 253 | 
             
            - docs/.gitignore
         | 
| 295 254 | 
             
            - docs/README.md
         | 
| 255 | 
            +
            - docs/alpha_vantage_technical_indicators.md
         | 
| 296 256 | 
             
            - docs/average_true_range.md
         | 
| 297 257 | 
             
            - docs/bollinger_bands.md
         | 
| 298 258 | 
             
            - docs/candlestick_pattern_recognizer.md
         | 
| @@ -316,14 +276,6 @@ files: | |
| 316 276 | 
             
            - docs/stochastic_oscillator.md
         | 
| 317 277 | 
             
            - docs/strategy.md
         | 
| 318 278 | 
             
            - docs/true_range.md
         | 
| 319 | 
            -
            - lib/patches/daru.rb
         | 
| 320 | 
            -
            - lib/patches/daru/category.rb
         | 
| 321 | 
            -
            - lib/patches/daru/data_frame.rb
         | 
| 322 | 
            -
            - lib/patches/daru/plotting/svg-graph.rb
         | 
| 323 | 
            -
            - lib/patches/daru/plotting/svg-graph/category.rb
         | 
| 324 | 
            -
            - lib/patches/daru/plotting/svg-graph/dataframe.rb
         | 
| 325 | 
            -
            - lib/patches/daru/plotting/svg-graph/vector.rb
         | 
| 326 | 
            -
            - lib/patches/daru/vector.rb
         | 
| 327 279 | 
             
            - lib/sqa.rb
         | 
| 328 280 | 
             
            - lib/sqa/activity.rb
         | 
| 329 281 | 
             
            - lib/sqa/analysis.rb
         | 
| @@ -356,6 +308,7 @@ files: | |
| 356 308 | 
             
            - lib/sqa/indicator/simple_moving_average_trend.rb
         | 
| 357 309 | 
             
            - lib/sqa/indicator/stochastic_oscillator.rb
         | 
| 358 310 | 
             
            - lib/sqa/indicator/true_range.rb
         | 
| 311 | 
            +
            - lib/sqa/init.rb
         | 
| 359 312 | 
             
            - lib/sqa/portfolio.rb
         | 
| 360 313 | 
             
            - lib/sqa/stock.rb
         | 
| 361 314 | 
             
            - lib/sqa/strategy.rb
         | 
| @@ -379,7 +332,8 @@ licenses: | |
| 379 332 | 
             
            metadata:
         | 
| 380 333 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 381 334 | 
             
              homepage_uri: https://github.com/MadBomber/sqa
         | 
| 382 | 
            -
              source_code_uri: https://github.com/MadBomber/ | 
| 335 | 
            +
              source_code_uri: https://github.com/MadBomber/sqa
         | 
| 336 | 
            +
              changelog_uri: https://github.com/MadBomber/sqa
         | 
| 383 337 | 
             
            post_install_message:
         | 
| 384 338 | 
             
            rdoc_options: []
         | 
| 385 339 | 
             
            require_paths:
         | 
| @@ -395,7 +349,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 395 349 | 
             
                - !ruby/object:Gem::Version
         | 
| 396 350 | 
             
                  version: '0'
         | 
| 397 351 | 
             
            requirements: []
         | 
| 398 | 
            -
            rubygems_version: 3.4. | 
| 352 | 
            +
            rubygems_version: 3.4.20
         | 
| 399 353 | 
             
            signing_key:
         | 
| 400 354 | 
             
            specification_version: 4
         | 
| 401 355 | 
             
            summary: sqa - Stock Qualitative Analysis
         | 
| @@ -1 +0,0 @@ | |
| 1 | 
            -
            c5eea4fb74e6ab7b7b1715a81598585ec540a3eb1e9b902ca339ff0a2ba9cc7624ae3f43e00b5fbbad1d3d510ed938e8f91154c0bee2e14d6503564b1b0ccfb1
         | 
| @@ -1,19 +0,0 @@ | |
| 1 | 
            -
            # lib/patches/daru/category.rb
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Daru
         | 
| 4 | 
            -
            	module Category
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            		def plotting_lig lib
         | 
| 7 | 
            -
            			if :svg_graph = lib
         | 
| 8 | 
            -
                    @plotting_library = lib
         | 
| 9 | 
            -
                    if Daru.send("has_#{lib}?".to_sym)
         | 
| 10 | 
            -
                      extend Module.const_get(
         | 
| 11 | 
            -
                        "Daru::Plotting::Category::#{lib.to_s.capitalize}Library"
         | 
| 12 | 
            -
                      )
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
            			else
         | 
| 15 | 
            -
            				super
         | 
| 16 | 
            -
            			end
         | 
| 17 | 
            -
            		end
         | 
| 18 | 
            -
            	end
         | 
| 19 | 
            -
            end
         | 
| @@ -1,19 +0,0 @@ | |
| 1 | 
            -
            # lib/patches/daru/data_frame.rb
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Daru
         | 
| 4 | 
            -
            	module DataFrame
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            		def plotting_lig lib
         | 
| 7 | 
            -
            			if :svg_graph = lib
         | 
| 8 | 
            -
                    @plotting_library = lib
         | 
| 9 | 
            -
                    if Daru.send("has_#{lib}?".to_sym)
         | 
| 10 | 
            -
                      extend Module.const_get(
         | 
| 11 | 
            -
                        "Daru::Plotting::DataFrame::#{lib.to_s.capitalize}Library"
         | 
| 12 | 
            -
                      )
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
            			else
         | 
| 15 | 
            -
            				super
         | 
| 16 | 
            -
            			end
         | 
| 17 | 
            -
            		end
         | 
| 18 | 
            -
            	end
         | 
| 19 | 
            -
            end
         |