Class: IB::Flex

Inherits:
Object
  • Object
show all
Defined in:
lib/ib/flex.rb

Overview

Instance Method Summary collapse

Constructor Details

#initialize(query_id: nil, token: nil, format: :xml, verbose: false, return_hash: false) {|_self| ... } ⇒ Flex

:return_hash => true / false (default)

Yields:

  • (_self)

Yield Parameters:

  • _self (IB::Flex)

    the object that the method was called on



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ib/flex.rb', line 42

def initialize query_id: nil ,  # must be specified
               token: nil ,  # must be specified once
               format: :xml,# or :csv
               verbose:  false,
               return_hash: false  

    # By default, uri is a well known FLEX Web Service URI
  self.uri =
    'https://gdcdyn.interactivebrokers.com/Universal/servlet/FlexStatementService.SendRequest'

  # convert parameters into instance-variables and assign them
  method(__method__).parameters.each do |type, k|
    next unless type == :key
    case k
    when :token
      self.token = token unless token.nil?
    else
      v = eval(k.to_s)
      instance_variable_set("@#{k}", v) unless v.nil?
    end
  end

  error "Token not set", :flex if Flex.token.nil?
  error "query_id not set", :flex if @query_id.nil?
  yield self if block_given?
end

Instance Method Details

#get_content(address, fields) ⇒ Object

Helper method to get (and parse XML) responses from IB Flex Web Service



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ib/flex.rb', line 112

def get_content address, fields
get = -> ( the_uri ) do
server = Net::HTTP.new(the_uri.host, the_uri.port)
server.use_ssl =  true
server.verify_mode = OpenSSL::SSL::VERIFY_NONE if server.use_ssl? # Avoid OpenSSL failures
server.start{ |http| http.request( Net::HTTP::Get.new(the_uri.request_uri) ) }
      end
    
  text_ok = fields.delete(:text_ok)
  the_uri = URI("#{address}?" + fields.map { |k, v| "#{k}=#{URI.encode(v.to_s)}" }.join('&'))
      response = get[ the_uri ] 

  error("URI responded with #{response.code}", :flex) unless response.code.to_i == 200
      if text_ok
response.body
      else
Ox.parse response.body
      end
end

#runObject

Run a pre-defined Flex query against IB Flex Web Service Returns a (parsed) report or raises FlexError in case of problems



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ib/flex.rb', line 71

def run
  # Initiate FLEX request at a known FLEX Web Service URI
      # get_content returns an Ox-Element-Object
      # Nodes > FlexStatementResponse and
      #        > if Status is other then 'suscess'  ErrorCode and ErrorMessage
      #        > otherwise Uri and  ReferenceCode

  statement = get_content( Flex.uri, :t => Flex.token, :q => @query_id, :v => 3)
      if @verbose
puts "the Statement returned by the request of the query" 
puts Ox.load(Ox.dump( statement), mode: :hash)  
      end
      error("Flex Query is invalid", :flex )  unless statement.value == 'FlexStatementResponse'
      error("#{statement.ErrorCode.ox.to_i}: #{statement.ErrorMessage.ox}", :flex) if statement.Status.ox != 'Success'
      #
  # Retrieve the FLEX report
  report = nil
  until report do
    sleep 5  # wait for the report to be prepared 
    report = get_content(statement.Url.ox,:t => Flex.token, :q => statement.ReferenceCode.ox, :v => 3,
                           :text_ok => @format != :xml)

      # If Status is specified, returned xml contains only error message, not actual report
      if report.nodes.include?('Status') && report.Status.ox =~ /Fail|Warn/
        error_code = report.ErrorCode.ox.to_i
        error_message = "#{error_code}: #{report.ErrorMessage.ox}"

        case error_code
        when 1001..1009, 1018, 1019, 1021
          # Report is just not ready yet, wait and retry
          puts error_message if @verbose
          report = nil
        else # Fatal error
          error error_message, :flex
        end
      end
  end
  @return_hash ? Ox.load( Ox.dump(report),  mode: :hash)  : report  # return hash or the Ox-Element
end