questrade_api 1.1.0 → 1.2.0
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/CHANGELOG.md +4 -0
- data/README.md +5 -5
- data/lib/questrade_api/client.rb +2 -0
- data/lib/questrade_api/modules/market_call.rb +13 -0
- data/lib/questrade_api/modules/order_call.rb +9 -0
- data/lib/questrade_api/rest/account.rb +1 -1
- data/lib/questrade_api/rest/base.rb +12 -1
- data/lib/questrade_api/rest/execution.rb +0 -2
- data/lib/questrade_api/rest/option_quote.rb +45 -0
- data/lib/questrade_api/rest/order.rb +44 -11
- data/lib/questrade_api/rest/position.rb +0 -2
- data/lib/questrade_api/rest/quote.rb +0 -2
- data/lib/questrade_api/rest/strategy_quote.rb +45 -0
- data/lib/questrade_api/rest/symbol.rb +22 -30
- data/lib/questrade_api/rest/time.rb +0 -2
- data/lib/questrade_api/version.rb +1 -1
- data/spec/fixtures/json/create_update_order.json +50 -0
- data/spec/fixtures/json/option_quotes.json +33 -0
- data/spec/fixtures/json/strategy_quotes.json +19 -0
- data/spec/questrade_api/modules/market_call_spec.rb +14 -0
- data/spec/questrade_api/rest/option_quote_spec.rb +81 -0
- data/spec/questrade_api/rest/order_spec.rb +146 -0
- data/spec/questrade_api/rest/strategy_quote_spec.rb +75 -0
- metadata +15 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e8141f3ee50e781f3ea23d1701d46e77c6ce6201
         | 
| 4 | 
            +
              data.tar.gz: 3002e00f9d7ab48cc1a0c575c1a54ff7ae4f30ee
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4d711919248d827c1d06287dfc53995c158f463e612d1d64d1a1c798bbbec8f388724eb8b89435c6640276e85acea3280938ceba6c96888be2a180965a16a1be
         | 
| 7 | 
            +
              data.tar.gz: c9cba6dd7b09f80af88519766594862a118cd64bf5bdc6f4bc2d14a9111c1add1125caf4a8adc808e1e7b10f3c973f2d3142a2e3f5c7e5a1eff8bf8899a82998
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -83,9 +83,9 @@ client.candles('123', startTime: DateTime.yesterday.to_s, endTime: DateTime.now. | |
| 83 83 | 
             
            # In case you already have a valid access token and its respective URL, you can use the QuestradeApi::REST objects. Example:
         | 
| 84 84 | 
             
            # authorization can be any object that responds to url and access_token
         | 
| 85 85 | 
             
            authorization = QuestradeApi::Authorization.new(access_token: 'access_token', api_server: 'url')
         | 
| 86 | 
            -
            accounts = QuestradeApi::REST::Account.fetch( | 
| 86 | 
            +
            accounts = QuestradeApi::REST::Account.fetch(authorization)
         | 
| 87 87 | 
             
            ```
         | 
| 88 | 
            -
            For more advanced options, check out our [documentation](http://www.rubydoc.info/gems/questrade_api/1. | 
| 88 | 
            +
            For more advanced options, check out our [documentation](http://www.rubydoc.info/gems/questrade_api/1.1.0).
         | 
| 89 89 |  | 
| 90 90 | 
             
            ## Current Status
         | 
| 91 91 |  | 
| @@ -109,14 +109,14 @@ Check the tables below for more details. | |
| 109 109 | 
             
            | Endpoint                   | Development   | Documentation |
         | 
| 110 110 | 
             
            | ---                        | ---           | ---           |
         | 
| 111 111 | 
             
            | /symbols/                  | DONE          |               |
         | 
| 112 | 
            -
            | /symbols/:id               | | 
| 112 | 
            +
            | /symbols/:id               | DONE          |               |
         | 
| 113 113 | 
             
            | /symbols/search            | DONE          |               |
         | 
| 114 114 | 
             
            | /symbols/:id/options       | DONE          |               |
         | 
| 115 115 | 
             
            | /markets                   | DONE          |               |
         | 
| 116 116 | 
             
            | /markets/quotes/           | DONE          |               |
         | 
| 117 117 | 
             
            | /markets/quotes/:id        | DONE          |               |
         | 
| 118 | 
            -
            | /markets/quotes/options    | | 
| 119 | 
            -
            | /markets/quotes/strategies | | 
| 118 | 
            +
            | /markets/quotes/options    | DONE          |               |
         | 
| 119 | 
            +
            | /markets/quotes/strategies | DONE          |               |
         | 
| 120 120 | 
             
            | /markets/candles/:id       | DONE          |               |
         | 
| 121 121 |  | 
| 122 122 | 
             
            ### Order Calls
         | 
    
        data/lib/questrade_api/client.rb
    CHANGED
    
    | @@ -2,12 +2,14 @@ require 'questrade_api/authorization' | |
| 2 2 |  | 
| 3 3 | 
             
            require 'questrade_api/modules/account_call'
         | 
| 4 4 | 
             
            require 'questrade_api/modules/market_call'
         | 
| 5 | 
            +
            require 'questrade_api/modules/order_call'
         | 
| 5 6 |  | 
| 6 7 | 
             
            module QuestradeApi
         | 
| 7 8 | 
             
              # @author Bruno Meira <goesmeira@gmail.com>
         | 
| 8 9 | 
             
              class Client
         | 
| 9 10 | 
             
                include QuestradeApi::AccountCall
         | 
| 10 11 | 
             
                include QuestradeApi::MarketCall
         | 
| 12 | 
            +
                include QuestradeApi::OrderCall
         | 
| 11 13 |  | 
| 12 14 | 
             
                attr_accessor :authorization
         | 
| 13 15 |  | 
| @@ -3,6 +3,8 @@ require 'questrade_api/rest/symbol' | |
| 3 3 | 
             
            require 'questrade_api/rest/quote'
         | 
| 4 4 | 
             
            require 'questrade_api/rest/candle'
         | 
| 5 5 | 
             
            require 'questrade_api/rest/option'
         | 
| 6 | 
            +
            require 'questrade_api/rest/option_quote'
         | 
| 7 | 
            +
            require 'questrade_api/rest/strategy_quote'
         | 
| 6 8 |  | 
| 7 9 | 
             
            module QuestradeApi
         | 
| 8 10 | 
             
              module MarketCall
         | 
| @@ -38,6 +40,17 @@ module QuestradeApi | |
| 38 40 | 
             
                  quote
         | 
| 39 41 | 
             
                end
         | 
| 40 42 |  | 
| 43 | 
            +
                def quote_options(filters, option_ids)
         | 
| 44 | 
            +
                  QuestradeApi::REST::OptionQuote.fetch(authorization,
         | 
| 45 | 
            +
                                                        filters: filters,
         | 
| 46 | 
            +
                                                        optionIds: option_ids)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def quote_strategies(variants)
         | 
| 50 | 
            +
                  QuestradeApi::REST::StrategyQuote.fetch(authorization,
         | 
| 51 | 
            +
                                                          variants: variants)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 41 54 | 
             
                def candles(symbol_id, params)
         | 
| 42 55 | 
             
                  QuestradeApi::REST::Candle.fetch(authorization, symbol_id, params)
         | 
| 43 56 | 
             
                end
         | 
| @@ -10,7 +10,8 @@ module QuestradeApi | |
| 10 10 |  | 
| 11 11 | 
             
                  BASE_ENDPOINT = '/v1'.freeze
         | 
| 12 12 | 
             
                  attr_accessor :connection, :raw_body, :endpoint,
         | 
| 13 | 
            -
                                :authorization, :data
         | 
| 13 | 
            +
                                :authorization, :data, :account_id, :id
         | 
| 14 | 
            +
             | 
| 14 15 |  | 
| 15 16 | 
             
                  # Initialize an instance of QuestradeApi::REST::Base
         | 
| 16 17 | 
             
                  #
         | 
| @@ -41,6 +42,7 @@ module QuestradeApi | |
| 41 42 | 
             
             #         faraday.response :logger
         | 
| 42 43 | 
             
                      faraday.adapter Faraday.default_adapter
         | 
| 43 44 | 
             
                      faraday.headers['Content-Type'] = 'application/json'
         | 
| 45 | 
            +
                      faraday.headers['User-Agent'] = "QuestradeApi v#{QuestradeApi::VERSION}"
         | 
| 44 46 | 
             
                      faraday.headers['Authorization'] = "Bearer #{params[:access_token]}"
         | 
| 45 47 | 
             
                    end
         | 
| 46 48 | 
             
                  end
         | 
| @@ -82,6 +84,15 @@ module QuestradeApi | |
| 82 84 | 
             
                        end
         | 
| 83 85 | 
             
                      end
         | 
| 84 86 | 
             
                    end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                    def post(params = {})
         | 
| 89 | 
            +
                      connection = connection(params)
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      connection.post do |req|
         | 
| 92 | 
            +
                        req.path = params[:endpoint]
         | 
| 93 | 
            +
                        req.body = params[:body] if params[:body]
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    end
         | 
| 85 96 | 
             
                  end
         | 
| 86 97 | 
             
                end
         | 
| 87 98 | 
             
              end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require 'questrade_api/rest/base'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module QuestradeApi
         | 
| 4 | 
            +
              module REST
         | 
| 5 | 
            +
                class OptionQuote < QuestradeApi::REST::Base
         | 
| 6 | 
            +
                  def initialize(params)
         | 
| 7 | 
            +
                    @raw_body = params[:data]
         | 
| 8 | 
            +
                    build_data(params[:data]) if @raw_body
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def self.fetch(authorization, params)
         | 
| 12 | 
            +
                    response = post(access_token: authorization.access_token,
         | 
| 13 | 
            +
                                    endpoint: endpoint,
         | 
| 14 | 
            +
                                    url: authorization.url,
         | 
| 15 | 
            +
                                    body: params.to_json)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    if response.status == 200
         | 
| 18 | 
            +
                      result = OpenStruct.new(optionQuotes: [])
         | 
| 19 | 
            +
                      result.optionQuotes = parse_option_quotes(response.body)
         | 
| 20 | 
            +
                      response = result
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    response
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def self.endpoint
         | 
| 27 | 
            +
                    "#{BASE_ENDPOINT}/markets/quotes/options"
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def self.parse_option_quotes(body)
         | 
| 31 | 
            +
                    raw = JSON.parse(body)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    options = []
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    raw['optionQuotes'].each do |option|
         | 
| 36 | 
            +
                      options << new(data: option)
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    options
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  private_class_method :parse_option_quotes
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -3,8 +3,6 @@ require 'questrade_api/rest/base' | |
| 3 3 | 
             
            module QuestradeApi
         | 
| 4 4 | 
             
              module REST
         | 
| 5 5 | 
             
                class Order < QuestradeApi::REST::Base
         | 
| 6 | 
            -
                  attr_accessor :account_id, :id
         | 
| 7 | 
            -
             | 
| 8 6 | 
             
                  def initialize(authorization, params = {})
         | 
| 9 7 | 
             
                    super(authorization)
         | 
| 10 8 |  | 
| @@ -15,20 +13,37 @@ module QuestradeApi | |
| 15 13 | 
             
                    build_data(params[:data]) if @raw_body
         | 
| 16 14 | 
             
                  end
         | 
| 17 15 |  | 
| 18 | 
            -
                  def  | 
| 16 | 
            +
                  def update(params = {})
         | 
| 17 | 
            +
                    params[:accountNumber] = account_id
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    response = self.class.post(access_token: authorization.access_token,
         | 
| 20 | 
            +
                                               endpoint: endpoint,
         | 
| 21 | 
            +
                                               url: authorization.url,
         | 
| 22 | 
            +
                                               body: params.to_json)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    parse_order(response.body) if response.status == 200
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    response
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def self.create(authorization, account_number, params = {})
         | 
| 30 | 
            +
                    params[:accountNumber] = account_number
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    response = post(access_token: authorization.access_token,
         | 
| 33 | 
            +
                                    endpoint: endpoint(account_number),
         | 
| 34 | 
            +
                                    url: authorization.url,
         | 
| 35 | 
            +
                                    body: params.to_json)
         | 
| 19 36 |  | 
| 37 | 
            +
                    build_orders(authorization, account_number, response)
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def self.fetch(authorization, account_number, params)
         | 
| 20 41 | 
             
                    response = super(access_token: authorization.access_token,
         | 
| 21 42 | 
             
                                     endpoint: endpoint(account_number),
         | 
| 22 43 | 
             
                                     url: authorization.url,
         | 
| 23 44 | 
             
                                     params: params)
         | 
| 24 45 |  | 
| 25 | 
            -
                     | 
| 26 | 
            -
             | 
| 27 | 
            -
                    if response.status == 200
         | 
| 28 | 
            -
                      result.orders = parse_orders(authorization, account_number, response.body)
         | 
| 29 | 
            -
                    end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                    result
         | 
| 46 | 
            +
                    build_orders(authorization, account_number, response)
         | 
| 32 47 | 
             
                  end
         | 
| 33 48 |  | 
| 34 49 | 
             
                  def endpoint
         | 
| @@ -39,6 +54,13 @@ module QuestradeApi | |
| 39 54 | 
             
                    "#{BASE_ENDPOINT}/accounts/#{account_id}/orders"
         | 
| 40 55 | 
             
                  end
         | 
| 41 56 |  | 
| 57 | 
            +
                  private
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def parse_order(body)
         | 
| 60 | 
            +
                    raw = JSON.parse(body)
         | 
| 61 | 
            +
                    build_data(raw['orders'].first) if raw['orders'].size > 0
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 42 64 | 
             
                  def self.parse_orders(authorization, account_id, body)
         | 
| 43 65 | 
             
                    raw = JSON.parse(body)
         | 
| 44 66 |  | 
| @@ -52,7 +74,18 @@ module QuestradeApi | |
| 52 74 | 
             
                    orders
         | 
| 53 75 | 
             
                  end
         | 
| 54 76 |  | 
| 55 | 
            -
                   | 
| 77 | 
            +
                  def self.build_orders(authorization, account_number, response)
         | 
| 78 | 
            +
                    result = response
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    if response.status == 200
         | 
| 81 | 
            +
                      result = OpenStruct.new(orders: [])
         | 
| 82 | 
            +
                      result.orders = parse_orders(authorization, account_number, response.body)
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    result
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  private_class_method :parse_orders, :build_orders
         | 
| 56 89 | 
             
                end
         | 
| 57 90 | 
             
              end
         | 
| 58 91 | 
             
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require 'questrade_api/rest/base'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module QuestradeApi
         | 
| 4 | 
            +
              module REST
         | 
| 5 | 
            +
                class StrategyQuote < QuestradeApi::REST::Base
         | 
| 6 | 
            +
                  def initialize(params)
         | 
| 7 | 
            +
                    @raw_body = params[:data]
         | 
| 8 | 
            +
                    build_data(params[:data]) if @raw_body
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def self.fetch(authorization, params)
         | 
| 12 | 
            +
                    response = post(access_token: authorization.access_token,
         | 
| 13 | 
            +
                                    endpoint: endpoint,
         | 
| 14 | 
            +
                                    url: authorization.url,
         | 
| 15 | 
            +
                                    body: params.to_json)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    if response.status == 200
         | 
| 18 | 
            +
                      result = OpenStruct.new(strategyQuotes: [])
         | 
| 19 | 
            +
                      result.strategyQuotes = parse_strategy_quotes(response.body)
         | 
| 20 | 
            +
                      response = result
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    response
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def self.endpoint
         | 
| 27 | 
            +
                    "#{BASE_ENDPOINT}/markets/quotes/strategies"
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def self.parse_strategy_quotes(body)
         | 
| 31 | 
            +
                    raw = JSON.parse(body)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    strategies = []
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    raw['strategyQuotes'].each do |strategy|
         | 
| 36 | 
            +
                      strategies << new(data: strategy)
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    strategies
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  private_class_method :parse_strategy_quotes
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -3,8 +3,6 @@ require 'questrade_api/rest/base' | |
| 3 3 | 
             
            module QuestradeApi
         | 
| 4 4 | 
             
              module REST
         | 
| 5 5 | 
             
                class Symbol < QuestradeApi::REST::Base
         | 
| 6 | 
            -
                  attr_accessor :id
         | 
| 7 | 
            -
             | 
| 8 6 | 
             
                  def initialize(authorization, params = {})
         | 
| 9 7 | 
             
                    super(authorization)
         | 
| 10 8 |  | 
| @@ -38,13 +36,7 @@ module QuestradeApi | |
| 38 36 | 
             
                                                url: authorization.url,
         | 
| 39 37 | 
             
                                                params: params)
         | 
| 40 38 |  | 
| 41 | 
            -
                     | 
| 42 | 
            -
                      result = OpenStruct.new(symbols: [])
         | 
| 43 | 
            -
                      result.symbols = parse_symbols(authorization, response.body)
         | 
| 44 | 
            -
                      response = result
         | 
| 45 | 
            -
                    end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                    response
         | 
| 39 | 
            +
                    build_symbols(authorization, response)
         | 
| 48 40 | 
             
                  end
         | 
| 49 41 |  | 
| 50 42 | 
             
                  def self.fetch(authorization, params = {})
         | 
| @@ -56,29 +48,39 @@ module QuestradeApi | |
| 56 48 | 
             
                                     url: authorization.url,
         | 
| 57 49 | 
             
                                     params: params)
         | 
| 58 50 |  | 
| 51 | 
            +
                    build_symbols(authorization, response)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  private
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def parse_symbols(body)
         | 
| 57 | 
            +
                    raw = JSON.parse(body)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    raw['symbols'].each do |symbol|
         | 
| 60 | 
            +
                      build_data(symbol)
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def self.build_symbols(authorization, response)
         | 
| 65 | 
            +
                    result = response
         | 
| 66 | 
            +
             | 
| 59 67 | 
             
                    if response.status == 200
         | 
| 60 68 | 
             
                      result = OpenStruct.new(symbols: [])
         | 
| 61 69 | 
             
                      result.symbols = parse_symbols(authorization, response.body)
         | 
| 62 | 
            -
                      response = result
         | 
| 63 70 | 
             
                    end
         | 
| 64 71 |  | 
| 65 | 
            -
                     | 
| 72 | 
            +
                    result
         | 
| 66 73 | 
             
                  end
         | 
| 67 74 |  | 
| 68 | 
            -
                  # TODO: Review this later
         | 
| 69 75 | 
             
                  def self.parse_symbols(authorization, body)
         | 
| 70 76 | 
             
                    raw = JSON.parse(body)
         | 
| 71 77 |  | 
| 72 78 | 
             
                    symbols = []
         | 
| 73 79 |  | 
| 74 | 
            -
                     | 
| 75 | 
            -
                      raw['symbols'].each do |symbol|
         | 
| 76 | 
            -
                        symbols << new(authorization, id: symbol['symbolId'], data: symbol)
         | 
| 77 | 
            -
                      end
         | 
| 78 | 
            -
                    end
         | 
| 80 | 
            +
                    results = raw['symbols'] || raw['symbol']
         | 
| 79 81 |  | 
| 80 | 
            -
                    if  | 
| 81 | 
            -
                       | 
| 82 | 
            +
                    if results
         | 
| 83 | 
            +
                      results.each do |symbol|
         | 
| 82 84 | 
             
                        symbols << new(authorization, id: symbol['symbolId'], data: symbol)
         | 
| 83 85 | 
             
                      end
         | 
| 84 86 | 
             
                    end
         | 
| @@ -86,17 +88,7 @@ module QuestradeApi | |
| 86 88 | 
             
                    symbols
         | 
| 87 89 | 
             
                  end
         | 
| 88 90 |  | 
| 89 | 
            -
                  private_class_method :parse_symbols
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                  private
         | 
| 92 | 
            -
             | 
| 93 | 
            -
                  def parse_symbols(body)
         | 
| 94 | 
            -
                    raw = JSON.parse(body)
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                    raw['symbols'].each do |symbol|
         | 
| 97 | 
            -
                      build_data(symbol)
         | 
| 98 | 
            -
                    end
         | 
| 99 | 
            -
                  end
         | 
| 91 | 
            +
                  private_class_method :parse_symbols, :build_symbols
         | 
| 100 92 | 
             
                end
         | 
| 101 93 | 
             
              end
         | 
| 102 94 | 
             
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "orderId": 177106005,
         | 
| 3 | 
            +
              "orders": [
         | 
| 4 | 
            +
                {
         | 
| 5 | 
            +
                  "id": 177106005,
         | 
| 6 | 
            +
                  "symbol": "AAPL",
         | 
| 7 | 
            +
                  "symbolId": 8049,
         | 
| 8 | 
            +
                  "totalQuantity": 10,
         | 
| 9 | 
            +
                  "openQuantity": 10,
         | 
| 10 | 
            +
                  "filledQuantity": 0,
         | 
| 11 | 
            +
                  "canceledQuantity": 0,
         | 
| 12 | 
            +
                  "side": "Buy",
         | 
| 13 | 
            +
                  "orderType": "Limit",
         | 
| 14 | 
            +
                  "limitPrice": 537,
         | 
| 15 | 
            +
                  "stopPrice": null,
         | 
| 16 | 
            +
                  "isAllOrNone": true,
         | 
| 17 | 
            +
                  "isAnonymous": false,
         | 
| 18 | 
            +
                  "icebergQty": 1,
         | 
| 19 | 
            +
                  "minQuantity": null,
         | 
| 20 | 
            +
                  "avgExecPrice": null,
         | 
| 21 | 
            +
                  "lastExecPrice": null,
         | 
| 22 | 
            +
                  "source": "TradingAPI",
         | 
| 23 | 
            +
                  "timeInForce": "GoodTillCanceled",
         | 
| 24 | 
            +
                  "gtdDate": null,
         | 
| 25 | 
            +
                  "state": "Pending",
         | 
| 26 | 
            +
                  "clientReasonStr": "",
         | 
| 27 | 
            +
                  "chainId": 177106005,
         | 
| 28 | 
            +
                  "creationTime": "2014-10-24T17:48:20.546000-04:00",
         | 
| 29 | 
            +
                  "updateTime": "2014-10-24T17:48:20.876000-04:00",
         | 
| 30 | 
            +
                  "notes": "",
         | 
| 31 | 
            +
                  "primaryRoute": "LAMP",
         | 
| 32 | 
            +
                  "secondaryRoute": "AUTO",
         | 
| 33 | 
            +
                  "orderRoute": "LAMP",
         | 
| 34 | 
            +
                  "venueHoldingOrder": "",
         | 
| 35 | 
            +
                  "comissionCharged": 0,
         | 
| 36 | 
            +
                  "exchangeOrderId": "",
         | 
| 37 | 
            +
                  "isSignificantShareHolder": false,
         | 
| 38 | 
            +
                  "isInsider": false,
         | 
| 39 | 
            +
                  "isLimitOffsetInDollar": false,
         | 
| 40 | 
            +
                  "userId": 3000124,
         | 
| 41 | 
            +
                  "placementCommission": null,
         | 
| 42 | 
            +
                  "legs": [],
         | 
| 43 | 
            +
                  "strategyType": "SingleLeg",
         | 
| 44 | 
            +
                  "triggerStopPrice": null,
         | 
| 45 | 
            +
                  "orderGroupId": 0,
         | 
| 46 | 
            +
                  "orderClass": null,
         | 
| 47 | 
            +
                  "mainChainId": 0
         | 
| 48 | 
            +
                }
         | 
| 49 | 
            +
              ]
         | 
| 50 | 
            +
            }
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "optionQuotes": [
         | 
| 3 | 
            +
                {
         | 
| 4 | 
            +
                  "underlying": "MSFT",
         | 
| 5 | 
            +
                  "underlyingId": 27426,
         | 
| 6 | 
            +
                  "symbol": "MSFT20Jan17C70.00",
         | 
| 7 | 
            +
                  "symbolId": 7413503,
         | 
| 8 | 
            +
                  "bidPrice": 4.90,
         | 
| 9 | 
            +
                  "bidSize": 0,
         | 
| 10 | 
            +
                  "askPrice": 4.95,
         | 
| 11 | 
            +
                  "askSize": 0,
         | 
| 12 | 
            +
                  "lastTradePriceTrHrs": 4.93,
         | 
| 13 | 
            +
                  "lastTradePrice": 4.93,
         | 
| 14 | 
            +
                  "lastTradeSize": 0,
         | 
| 15 | 
            +
                  "lastTradeTick": "Equal",
         | 
| 16 | 
            +
                  "lastTradeTime": "2015-08-17T00:00:00.000000-04:00",
         | 
| 17 | 
            +
                  "volume": 0,
         | 
| 18 | 
            +
                  "openPrice": 0,
         | 
| 19 | 
            +
                  "highPrice": 4.93,
         | 
| 20 | 
            +
                  "lowPrice": 0,
         | 
| 21 | 
            +
                  "volatility": 52.374257,
         | 
| 22 | 
            +
                  "delta": 0.06985,
         | 
| 23 | 
            +
                  "gamma": 0.01038,
         | 
| 24 | 
            +
                  "theta": -0.001406,
         | 
| 25 | 
            +
                  "vega": 0.074554,
         | 
| 26 | 
            +
                  "rho": 0.04153,
         | 
| 27 | 
            +
                  "openInterest": 2292,
         | 
| 28 | 
            +
                  "delay": 0,
         | 
| 29 | 
            +
                  "isHalted": false,
         | 
| 30 | 
            +
                  "VWAP": 0
         | 
| 31 | 
            +
                }
         | 
| 32 | 
            +
              ]
         | 
| 33 | 
            +
            }
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "strategyQuotes": [
         | 
| 3 | 
            +
                {
         | 
| 4 | 
            +
                  "variantId": 1,
         | 
| 5 | 
            +
                  "bidPrice": 27.2,
         | 
| 6 | 
            +
                  "askPrice": 27.23,
         | 
| 7 | 
            +
                  "underlying": "MSFT",
         | 
| 8 | 
            +
                  "underlyingId": 27426,
         | 
| 9 | 
            +
                  "openPrice": null,
         | 
| 10 | 
            +
                  "volatility": 0,
         | 
| 11 | 
            +
                  "delta": 1,
         | 
| 12 | 
            +
                  "gamma": 0,
         | 
| 13 | 
            +
                  "theta": 0,
         | 
| 14 | 
            +
                  "vega": 0,
         | 
| 15 | 
            +
                  "rho": 0,
         | 
| 16 | 
            +
                  "isRealTime": true
         | 
| 17 | 
            +
                }
         | 
| 18 | 
            +
              ]
         | 
| 19 | 
            +
            }
         | 
| @@ -59,6 +59,20 @@ describe QuestradeApi::MarketCall do | |
| 59 59 | 
             
                end
         | 
| 60 60 | 
             
              end
         | 
| 61 61 |  | 
| 62 | 
            +
              context '.quote_options' do
         | 
| 63 | 
            +
                it 'calls proper endpoint' do
         | 
| 64 | 
            +
                  expect(QuestradeApi::REST::OptionQuote).to receive(:fetch).and_return([])
         | 
| 65 | 
            +
                  expect(subject.quote_options([], [])).to eq([])
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              context '.quote_strategies' do
         | 
| 70 | 
            +
                it 'calls proper endpoint' do
         | 
| 71 | 
            +
                  expect(QuestradeApi::REST::StrategyQuote).to receive(:fetch).and_return([])
         | 
| 72 | 
            +
                  expect(subject.quote_strategies([])).to eq([])
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 62 76 | 
             
              context '.candles' do
         | 
| 63 77 | 
             
                it 'calls proper endpoint' do
         | 
| 64 78 | 
             
                  expect(QuestradeApi::REST::Candle).to receive(:fetch).and_return([])
         | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'questrade_api/rest/option_quote'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe QuestradeApi::REST::OptionQuote do
         | 
| 5 | 
            +
              include JSONFixtures
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:access_token) { 'XXXX' }
         | 
| 8 | 
            +
              let(:url) { 'http://test.com'}
         | 
| 9 | 
            +
              let(:authorization) { OpenStruct.new(access_token: access_token, url: url) }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              context '.fetch' do
         | 
| 12 | 
            +
                it 'fetches option chain for an specific symbol' do
         | 
| 13 | 
            +
                  params = {
         | 
| 14 | 
            +
                    filters: [
         | 
| 15 | 
            +
                      {
         | 
| 16 | 
            +
                        optionType: "Call",
         | 
| 17 | 
            +
                        underlyingId: 27426,
         | 
| 18 | 
            +
                        expiryDate: "2017-01-20T00:00:00.000000-05:00",
         | 
| 19 | 
            +
                        minstrikePrice: 70,
         | 
| 20 | 
            +
                        maxstrikePrice: 80
         | 
| 21 | 
            +
                      }
         | 
| 22 | 
            +
                    ],
         | 
| 23 | 
            +
                    optionIds: [ 9907637, 9907638 ]
         | 
| 24 | 
            +
                  }
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  headers = { 'Accept' => '*/*',
         | 
| 27 | 
            +
                              'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
         | 
| 28 | 
            +
                              'Authorization' => 'Bearer XXXX',
         | 
| 29 | 
            +
                              'Content-Type' => 'application/json',
         | 
| 30 | 
            +
                              'User-Agent' => "QuestradeApi v#{QuestradeApi::VERSION}" }
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  stub_request(:post, 'http://test.com/v1/markets/quotes/options')
         | 
| 33 | 
            +
                    .with(body: params.to_json, headers: headers)
         | 
| 34 | 
            +
                    .to_return(status: 200, body: json_string('option_quotes.json'))
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  response = QuestradeApi::REST::OptionQuote.fetch(authorization, params)
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  expect(response.optionQuotes.size).to be(1)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  first_option = response.optionQuotes.first
         | 
| 41 | 
            +
                  expect(first_option.data.to_h).to eq(
         | 
| 42 | 
            +
                    {
         | 
| 43 | 
            +
                      underlying: "MSFT",
         | 
| 44 | 
            +
                      underlying_id: 27426,
         | 
| 45 | 
            +
                      symbol: "MSFT20Jan17C70.00",
         | 
| 46 | 
            +
                      symbol_id: 7413503,
         | 
| 47 | 
            +
                      bid_price: 4.90,
         | 
| 48 | 
            +
                      bid_size: 0,
         | 
| 49 | 
            +
                      ask_price: 4.95,
         | 
| 50 | 
            +
                      ask_size: 0,
         | 
| 51 | 
            +
                      last_trade_price_tr_hrs: 4.93,
         | 
| 52 | 
            +
                      last_trade_price: 4.93,
         | 
| 53 | 
            +
                      last_trade_size: 0,
         | 
| 54 | 
            +
                      last_trade_tick: "Equal",
         | 
| 55 | 
            +
                      last_trade_time: "2015-08-17T00:00:00.000000-04:00",
         | 
| 56 | 
            +
                      volume: 0,
         | 
| 57 | 
            +
                      open_price: 0,
         | 
| 58 | 
            +
                      high_price: 4.93,
         | 
| 59 | 
            +
                      low_price: 0,
         | 
| 60 | 
            +
                      volatility: 52.374257,
         | 
| 61 | 
            +
                      delta: 0.06985,
         | 
| 62 | 
            +
                      gamma: 0.01038,
         | 
| 63 | 
            +
                      theta: -0.001406,
         | 
| 64 | 
            +
                      vega: 0.074554,
         | 
| 65 | 
            +
                      rho: 0.04153,
         | 
| 66 | 
            +
                      open_interest: 2292,
         | 
| 67 | 
            +
                      delay: 0,
         | 
| 68 | 
            +
                      is_halted: false,
         | 
| 69 | 
            +
                      vwap: 0
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                  )
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              context '.endpoint' do
         | 
| 76 | 
            +
                it 'returns the right endpoint' do
         | 
| 77 | 
            +
                  url = "/v1/markets/quotes/options"
         | 
| 78 | 
            +
                  expect(QuestradeApi::REST::OptionQuote.endpoint).to eq(url)
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
| @@ -9,6 +9,152 @@ describe QuestradeApi::REST::Order do | |
| 9 9 | 
             
              let(:account_id) { '123456' }
         | 
| 10 10 | 
             
              let(:url) { 'http://test.com'}
         | 
| 11 11 | 
             
              let(:authorization) { OpenStruct.new(access_token: access_token, url: url) }
         | 
| 12 | 
            +
              let(:params) {
         | 
| 13 | 
            +
                {
         | 
| 14 | 
            +
                  accountNumber: account_id,
         | 
| 15 | 
            +
                  symbolId: 8049,
         | 
| 16 | 
            +
                  quantity: 10,
         | 
| 17 | 
            +
                  icebergQuantity: 1,
         | 
| 18 | 
            +
                  limitPrice: 537,
         | 
| 19 | 
            +
                  isAllOrNone: true,
         | 
| 20 | 
            +
                  isAnonymous: false,
         | 
| 21 | 
            +
                  orderType: "Limit",
         | 
| 22 | 
            +
                  timeInForce: "GoodTillCanceled",
         | 
| 23 | 
            +
                  action: "Buy",
         | 
| 24 | 
            +
                  primaryRoute: "AUTO",
         | 
| 25 | 
            +
                  secondaryRoute: "AUTO"
         | 
| 26 | 
            +
                }
         | 
| 27 | 
            +
              }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              let(:headers) {
         | 
| 30 | 
            +
                { 'Accept' => '*/*',
         | 
| 31 | 
            +
                  'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
         | 
| 32 | 
            +
                  'Authorization' => 'Bearer XXXX',
         | 
| 33 | 
            +
                  'Content-Type' => 'application/json',
         | 
| 34 | 
            +
                  'User-Agent' => "QuestradeApi v#{QuestradeApi::VERSION}" }
         | 
| 35 | 
            +
              }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              context '#update' do
         | 
| 38 | 
            +
                let(:id) { 177106005 }
         | 
| 39 | 
            +
                subject { QuestradeApi::REST::Order.new(authorization,
         | 
| 40 | 
            +
                                                        id: id, account_id: account_id ) }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                it 'updates an existing order' do
         | 
| 43 | 
            +
                  url = "http://test.com/v1/accounts/#{account_id}/orders/#{id}"
         | 
| 44 | 
            +
                  stub_request(:post, url)
         | 
| 45 | 
            +
                    .with(body: params.to_json, headers: headers)
         | 
| 46 | 
            +
                    .to_return(status: 200, body: json_string('create_update_order.json'))
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  subject.update(params)
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  expect(subject.data.to_h).to eq(
         | 
| 51 | 
            +
                    id: 177106005,
         | 
| 52 | 
            +
                    symbol: "AAPL",
         | 
| 53 | 
            +
                    symbol_id: 8049,
         | 
| 54 | 
            +
                    total_quantity: 10,
         | 
| 55 | 
            +
                    open_quantity: 10,
         | 
| 56 | 
            +
                    filled_quantity: 0,
         | 
| 57 | 
            +
                    canceled_quantity: 0,
         | 
| 58 | 
            +
                    side: "Buy",
         | 
| 59 | 
            +
                    order_type: "Limit",
         | 
| 60 | 
            +
                    limit_price: 537,
         | 
| 61 | 
            +
                    stop_price: nil,
         | 
| 62 | 
            +
                    is_all_or_none: true,
         | 
| 63 | 
            +
                    is_anonymous: false,
         | 
| 64 | 
            +
                    iceberg_qty: 1,
         | 
| 65 | 
            +
                    min_quantity: nil,
         | 
| 66 | 
            +
                    avg_exec_price: nil,
         | 
| 67 | 
            +
                    last_exec_price: nil,
         | 
| 68 | 
            +
                    source: "TradingAPI",
         | 
| 69 | 
            +
                    time_in_force: "GoodTillCanceled",
         | 
| 70 | 
            +
                    gtd_date: nil,
         | 
| 71 | 
            +
                    state: "Pending",
         | 
| 72 | 
            +
                    client_reason_str: "",
         | 
| 73 | 
            +
                    chain_id: 177106005,
         | 
| 74 | 
            +
                    creation_time: "2014-10-24T17:48:20.546000-04:00",
         | 
| 75 | 
            +
                    update_time: "2014-10-24T17:48:20.876000-04:00",
         | 
| 76 | 
            +
                    notes: "",
         | 
| 77 | 
            +
                    primary_route: "LAMP",
         | 
| 78 | 
            +
                    secondary_route: "AUTO",
         | 
| 79 | 
            +
                    order_route: "LAMP",
         | 
| 80 | 
            +
                    venue_holding_order: "",
         | 
| 81 | 
            +
                    comission_charged: 0,
         | 
| 82 | 
            +
                    exchange_order_id: "",
         | 
| 83 | 
            +
                    is_significant_share_holder: false,
         | 
| 84 | 
            +
                    is_insider: false,
         | 
| 85 | 
            +
                    is_limit_offset_in_dollar: false,
         | 
| 86 | 
            +
                    user_id: 3000124,
         | 
| 87 | 
            +
                    placement_commission: nil,
         | 
| 88 | 
            +
                    legs: [],
         | 
| 89 | 
            +
                    strategy_type: "SingleLeg",
         | 
| 90 | 
            +
                    trigger_stop_price: nil,
         | 
| 91 | 
            +
                    order_group_id: 0,
         | 
| 92 | 
            +
                    order_class: nil,
         | 
| 93 | 
            +
                    main_chain_id: 0
         | 
| 94 | 
            +
                  )
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              context '.create' do
         | 
| 99 | 
            +
                it "places an order" do
         | 
| 100 | 
            +
                  url = "http://test.com/v1/accounts/#{account_id}/orders"
         | 
| 101 | 
            +
                  stub_request(:post, url)
         | 
| 102 | 
            +
                    .with(body: params.to_json, headers: headers)
         | 
| 103 | 
            +
                    .to_return(status: 200, body: json_string('create_update_order.json'))
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  response = QuestradeApi::REST::Order.create(authorization, account_id, params)
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  expect(response.orders.size).to be(1)
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  first_order = response.orders.first
         | 
| 110 | 
            +
                  expect(first_order.account_id).to eq(account_id)
         | 
| 111 | 
            +
                  expect(first_order.data.to_h).to eq(
         | 
| 112 | 
            +
                    id: 177106005,
         | 
| 113 | 
            +
                    symbol: "AAPL",
         | 
| 114 | 
            +
                    symbol_id: 8049,
         | 
| 115 | 
            +
                    total_quantity: 10,
         | 
| 116 | 
            +
                    open_quantity: 10,
         | 
| 117 | 
            +
                    filled_quantity: 0,
         | 
| 118 | 
            +
                    canceled_quantity: 0,
         | 
| 119 | 
            +
                    side: "Buy",
         | 
| 120 | 
            +
                    order_type: "Limit",
         | 
| 121 | 
            +
                    limit_price: 537,
         | 
| 122 | 
            +
                    stop_price: nil,
         | 
| 123 | 
            +
                    is_all_or_none: true,
         | 
| 124 | 
            +
                    is_anonymous: false,
         | 
| 125 | 
            +
                    iceberg_qty: 1,
         | 
| 126 | 
            +
                    min_quantity: nil,
         | 
| 127 | 
            +
                    avg_exec_price: nil,
         | 
| 128 | 
            +
                    last_exec_price: nil,
         | 
| 129 | 
            +
                    source: "TradingAPI",
         | 
| 130 | 
            +
                    time_in_force: "GoodTillCanceled",
         | 
| 131 | 
            +
                    gtd_date: nil,
         | 
| 132 | 
            +
                    state: "Pending",
         | 
| 133 | 
            +
                    client_reason_str: "",
         | 
| 134 | 
            +
                    chain_id: 177106005,
         | 
| 135 | 
            +
                    creation_time: "2014-10-24T17:48:20.546000-04:00",
         | 
| 136 | 
            +
                    update_time: "2014-10-24T17:48:20.876000-04:00",
         | 
| 137 | 
            +
                    notes: "",
         | 
| 138 | 
            +
                    primary_route: "LAMP",
         | 
| 139 | 
            +
                    secondary_route: "AUTO",
         | 
| 140 | 
            +
                    order_route: "LAMP",
         | 
| 141 | 
            +
                    venue_holding_order: "",
         | 
| 142 | 
            +
                    comission_charged: 0,
         | 
| 143 | 
            +
                    exchange_order_id: "",
         | 
| 144 | 
            +
                    is_significant_share_holder: false,
         | 
| 145 | 
            +
                    is_insider: false,
         | 
| 146 | 
            +
                    is_limit_offset_in_dollar: false,
         | 
| 147 | 
            +
                    user_id: 3000124,
         | 
| 148 | 
            +
                    placement_commission: nil,
         | 
| 149 | 
            +
                    legs: [],
         | 
| 150 | 
            +
                    strategy_type: "SingleLeg",
         | 
| 151 | 
            +
                    trigger_stop_price: nil,
         | 
| 152 | 
            +
                    order_group_id: 0,
         | 
| 153 | 
            +
                    order_class: nil,
         | 
| 154 | 
            +
                    main_chain_id: 0
         | 
| 155 | 
            +
                  )
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
              end
         | 
| 12 158 |  | 
| 13 159 | 
             
              context '.fetch' do
         | 
| 14 160 | 
             
                it "returns an object that contains a list of all user's orders" do
         | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'questrade_api/rest/strategy_quote'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe QuestradeApi::REST::StrategyQuote do
         | 
| 5 | 
            +
              include JSONFixtures
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              let(:access_token) { 'XXXX' }
         | 
| 8 | 
            +
              let(:url) { 'http://test.com'}
         | 
| 9 | 
            +
              let(:authorization) { OpenStruct.new(access_token: access_token, url: url) }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              context '.fetch' do
         | 
| 12 | 
            +
                it 'fetches strategy chain for an specific symbol' do
         | 
| 13 | 
            +
                  params = {
         | 
| 14 | 
            +
                    variants: [
         | 
| 15 | 
            +
                      {
         | 
| 16 | 
            +
                        variantId: 1,
         | 
| 17 | 
            +
                        strategy: "Custom",
         | 
| 18 | 
            +
                        legs: [
         | 
| 19 | 
            +
                          {
         | 
| 20 | 
            +
                            symbolId: 27426,
         | 
| 21 | 
            +
                            ratio: 1000,
         | 
| 22 | 
            +
                            action: "Buy"
         | 
| 23 | 
            +
                          },
         | 
| 24 | 
            +
                          {
         | 
| 25 | 
            +
                            symbolId: 10550014,
         | 
| 26 | 
            +
                            ratio: 10,
         | 
| 27 | 
            +
                            action: "Sell"
         | 
| 28 | 
            +
                          }
         | 
| 29 | 
            +
                        ]
         | 
| 30 | 
            +
                      }
         | 
| 31 | 
            +
                    ]
         | 
| 32 | 
            +
                  }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  headers = { 'Accept' => '*/*',
         | 
| 35 | 
            +
                              'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
         | 
| 36 | 
            +
                              'Authorization' => 'Bearer XXXX',
         | 
| 37 | 
            +
                              'Content-Type' => 'application/json',
         | 
| 38 | 
            +
                              'User-Agent' => "QuestradeApi v#{QuestradeApi::VERSION}" }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  stub_request(:post, 'http://test.com/v1/markets/quotes/strategies')
         | 
| 41 | 
            +
                    .with(body: params.to_json, headers: headers)
         | 
| 42 | 
            +
                    .to_return(status: 200, body: json_string('strategy_quotes.json'))
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  response = QuestradeApi::REST::StrategyQuote.fetch(authorization, params)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  expect(response.strategyQuotes.size).to be(1)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  first_strategy = response.strategyQuotes.first
         | 
| 49 | 
            +
                  expect(first_strategy.data.to_h).to eq(
         | 
| 50 | 
            +
                    {
         | 
| 51 | 
            +
                      variant_id: 1,
         | 
| 52 | 
            +
                      bid_price: 27.2,
         | 
| 53 | 
            +
                      ask_price: 27.23,
         | 
| 54 | 
            +
                      underlying: "MSFT",
         | 
| 55 | 
            +
                      underlying_id: 27426,
         | 
| 56 | 
            +
                      open_price: nil,
         | 
| 57 | 
            +
                      volatility: 0,
         | 
| 58 | 
            +
                      delta: 1,
         | 
| 59 | 
            +
                      gamma: 0,
         | 
| 60 | 
            +
                      theta: 0,
         | 
| 61 | 
            +
                      vega: 0,
         | 
| 62 | 
            +
                      rho: 0,
         | 
| 63 | 
            +
                      is_real_time: true
         | 
| 64 | 
            +
                    }
         | 
| 65 | 
            +
                  )
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              context '.endpoint' do
         | 
| 70 | 
            +
                it 'returns the right endpoint' do
         | 
| 71 | 
            +
                  url = "/v1/markets/quotes/strategies"
         | 
| 72 | 
            +
                  expect(QuestradeApi::REST::StrategyQuote.endpoint).to eq(url)
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: questrade_api
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Bruno Meira
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017- | 
| 11 | 
            +
            date: 2017-03-17 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rspec
         | 
| @@ -88,6 +88,7 @@ files: | |
| 88 88 | 
             
            - lib/questrade_api/client.rb
         | 
| 89 89 | 
             
            - lib/questrade_api/modules/account_call.rb
         | 
| 90 90 | 
             
            - lib/questrade_api/modules/market_call.rb
         | 
| 91 | 
            +
            - lib/questrade_api/modules/order_call.rb
         | 
| 91 92 | 
             
            - lib/questrade_api/modules/util.rb
         | 
| 92 93 | 
             
            - lib/questrade_api/rest/account.rb
         | 
| 93 94 | 
             
            - lib/questrade_api/rest/activity.rb
         | 
| @@ -97,9 +98,11 @@ files: | |
| 97 98 | 
             
            - lib/questrade_api/rest/execution.rb
         | 
| 98 99 | 
             
            - lib/questrade_api/rest/market.rb
         | 
| 99 100 | 
             
            - lib/questrade_api/rest/option.rb
         | 
| 101 | 
            +
            - lib/questrade_api/rest/option_quote.rb
         | 
| 100 102 | 
             
            - lib/questrade_api/rest/order.rb
         | 
| 101 103 | 
             
            - lib/questrade_api/rest/position.rb
         | 
| 102 104 | 
             
            - lib/questrade_api/rest/quote.rb
         | 
| 105 | 
            +
            - lib/questrade_api/rest/strategy_quote.rb
         | 
| 103 106 | 
             
            - lib/questrade_api/rest/symbol.rb
         | 
| 104 107 | 
             
            - lib/questrade_api/rest/time.rb
         | 
| 105 108 | 
             
            - lib/questrade_api/version.rb
         | 
| @@ -108,13 +111,16 @@ files: | |
| 108 111 | 
             
            - spec/fixtures/json/activities.json
         | 
| 109 112 | 
             
            - spec/fixtures/json/balances.json
         | 
| 110 113 | 
             
            - spec/fixtures/json/candles.json
         | 
| 114 | 
            +
            - spec/fixtures/json/create_update_order.json
         | 
| 111 115 | 
             
            - spec/fixtures/json/executions.json
         | 
| 112 116 | 
             
            - spec/fixtures/json/markets.json
         | 
| 117 | 
            +
            - spec/fixtures/json/option_quotes.json
         | 
| 113 118 | 
             
            - spec/fixtures/json/options.json
         | 
| 114 119 | 
             
            - spec/fixtures/json/orders.json
         | 
| 115 120 | 
             
            - spec/fixtures/json/positions.json
         | 
| 116 121 | 
             
            - spec/fixtures/json/quote_01.json
         | 
| 117 122 | 
             
            - spec/fixtures/json/quotes.json
         | 
| 123 | 
            +
            - spec/fixtures/json/strategy_quotes.json
         | 
| 118 124 | 
             
            - spec/fixtures/json/symbol_01.json
         | 
| 119 125 | 
             
            - spec/fixtures/json/symbols.json
         | 
| 120 126 | 
             
            - spec/fixtures/json/symbols_search.json
         | 
| @@ -129,10 +135,12 @@ files: | |
| 129 135 | 
             
            - spec/questrade_api/rest/candle_spec.rb
         | 
| 130 136 | 
             
            - spec/questrade_api/rest/execution_spec.rb
         | 
| 131 137 | 
             
            - spec/questrade_api/rest/market_spec.rb
         | 
| 138 | 
            +
            - spec/questrade_api/rest/option_quote_spec.rb
         | 
| 132 139 | 
             
            - spec/questrade_api/rest/option_spec.rb
         | 
| 133 140 | 
             
            - spec/questrade_api/rest/order_spec.rb
         | 
| 134 141 | 
             
            - spec/questrade_api/rest/position_spec.rb
         | 
| 135 142 | 
             
            - spec/questrade_api/rest/quote_spec.rb
         | 
| 143 | 
            +
            - spec/questrade_api/rest/strategy_quote_spec.rb
         | 
| 136 144 | 
             
            - spec/questrade_api/rest/symbol_spec.rb
         | 
| 137 145 | 
             
            - spec/questrade_api/rest/time_spec.rb
         | 
| 138 146 | 
             
            - spec/spec_helper.rb
         | 
| @@ -166,13 +174,16 @@ test_files: | |
| 166 174 | 
             
            - spec/fixtures/json/activities.json
         | 
| 167 175 | 
             
            - spec/fixtures/json/balances.json
         | 
| 168 176 | 
             
            - spec/fixtures/json/candles.json
         | 
| 177 | 
            +
            - spec/fixtures/json/create_update_order.json
         | 
| 169 178 | 
             
            - spec/fixtures/json/executions.json
         | 
| 170 179 | 
             
            - spec/fixtures/json/markets.json
         | 
| 180 | 
            +
            - spec/fixtures/json/option_quotes.json
         | 
| 171 181 | 
             
            - spec/fixtures/json/options.json
         | 
| 172 182 | 
             
            - spec/fixtures/json/orders.json
         | 
| 173 183 | 
             
            - spec/fixtures/json/positions.json
         | 
| 174 184 | 
             
            - spec/fixtures/json/quote_01.json
         | 
| 175 185 | 
             
            - spec/fixtures/json/quotes.json
         | 
| 186 | 
            +
            - spec/fixtures/json/strategy_quotes.json
         | 
| 176 187 | 
             
            - spec/fixtures/json/symbol_01.json
         | 
| 177 188 | 
             
            - spec/fixtures/json/symbols.json
         | 
| 178 189 | 
             
            - spec/fixtures/json/symbols_search.json
         | 
| @@ -187,10 +198,12 @@ test_files: | |
| 187 198 | 
             
            - spec/questrade_api/rest/candle_spec.rb
         | 
| 188 199 | 
             
            - spec/questrade_api/rest/execution_spec.rb
         | 
| 189 200 | 
             
            - spec/questrade_api/rest/market_spec.rb
         | 
| 201 | 
            +
            - spec/questrade_api/rest/option_quote_spec.rb
         | 
| 190 202 | 
             
            - spec/questrade_api/rest/option_spec.rb
         | 
| 191 203 | 
             
            - spec/questrade_api/rest/order_spec.rb
         | 
| 192 204 | 
             
            - spec/questrade_api/rest/position_spec.rb
         | 
| 193 205 | 
             
            - spec/questrade_api/rest/quote_spec.rb
         | 
| 206 | 
            +
            - spec/questrade_api/rest/strategy_quote_spec.rb
         | 
| 194 207 | 
             
            - spec/questrade_api/rest/symbol_spec.rb
         | 
| 195 208 | 
             
            - spec/questrade_api/rest/time_spec.rb
         | 
| 196 209 | 
             
            - spec/spec_helper.rb
         |