ib-api 972.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 +7 -0
 - data/.gitignore +50 -0
 - data/.rspec +3 -0
 - data/.travis.yml +7 -0
 - data/CODE_OF_CONDUCT.md +74 -0
 - data/Gemfile +16 -0
 - data/Gemfile.lock +105 -0
 - data/Guardfile +24 -0
 - data/LICENSE +674 -0
 - data/README.md +65 -0
 - data/Rakefile +11 -0
 - data/VERSION +1 -0
 - data/api.gemspec +43 -0
 - data/bin/console +95 -0
 - data/bin/console.yml +3 -0
 - data/bin/setup +8 -0
 - data/changelog.md +7 -0
 - data/example/README.md +76 -0
 - data/example/account_info +54 -0
 - data/example/account_positions +30 -0
 - data/example/account_summary +88 -0
 - data/example/cancel_orders +74 -0
 - data/example/fa_accounts +25 -0
 - data/example/fundamental_data +40 -0
 - data/example/historic_data_cli +186 -0
 - data/example/list_orders +45 -0
 - data/example/portfolio_csv +81 -0
 - data/example/scanner_data +62 -0
 - data/example/template +19 -0
 - data/example/tick_data +28 -0
 - data/lib/extensions/class-extensions.rb +87 -0
 - data/lib/ib-api.rb +7 -0
 - data/lib/ib/base.rb +103 -0
 - data/lib/ib/base_properties.rb +160 -0
 - data/lib/ib/connection.rb +450 -0
 - data/lib/ib/constants.rb +393 -0
 - data/lib/ib/errors.rb +44 -0
 - data/lib/ib/logger.rb +26 -0
 - data/lib/ib/messages.rb +99 -0
 - data/lib/ib/messages/abstract_message.rb +101 -0
 - data/lib/ib/messages/incoming.rb +251 -0
 - data/lib/ib/messages/incoming/abstract_message.rb +116 -0
 - data/lib/ib/messages/incoming/account_value.rb +78 -0
 - data/lib/ib/messages/incoming/alert.rb +34 -0
 - data/lib/ib/messages/incoming/contract_data.rb +102 -0
 - data/lib/ib/messages/incoming/delta_neutral_validation.rb +23 -0
 - data/lib/ib/messages/incoming/execution_data.rb +50 -0
 - data/lib/ib/messages/incoming/historical_data.rb +84 -0
 - data/lib/ib/messages/incoming/market_depths.rb +44 -0
 - data/lib/ib/messages/incoming/next_valid_id.rb +18 -0
 - data/lib/ib/messages/incoming/open_order.rb +277 -0
 - data/lib/ib/messages/incoming/order_status.rb +85 -0
 - data/lib/ib/messages/incoming/portfolio_value.rb +78 -0
 - data/lib/ib/messages/incoming/real_time_bar.rb +32 -0
 - data/lib/ib/messages/incoming/scanner_data.rb +54 -0
 - data/lib/ib/messages/incoming/ticks.rb +268 -0
 - data/lib/ib/messages/outgoing.rb +437 -0
 - data/lib/ib/messages/outgoing/abstract_message.rb +88 -0
 - data/lib/ib/messages/outgoing/account_requests.rb +112 -0
 - data/lib/ib/messages/outgoing/bar_requests.rb +250 -0
 - data/lib/ib/messages/outgoing/place_order.rb +209 -0
 - data/lib/ib/messages/outgoing/request_marketdata.rb +99 -0
 - data/lib/ib/messages/outgoing/request_tick_data.rb +21 -0
 - data/lib/ib/model.rb +4 -0
 - data/lib/ib/models.rb +14 -0
 - data/lib/ib/server_versions.rb +114 -0
 - data/lib/ib/socket.rb +185 -0
 - data/lib/ib/support.rb +160 -0
 - data/lib/ib/version.rb +6 -0
 - data/lib/models/ib/account.rb +85 -0
 - data/lib/models/ib/account_value.rb +33 -0
 - data/lib/models/ib/bag.rb +55 -0
 - data/lib/models/ib/bar.rb +31 -0
 - data/lib/models/ib/combo_leg.rb +105 -0
 - data/lib/models/ib/condition.rb +245 -0
 - data/lib/models/ib/contract.rb +415 -0
 - data/lib/models/ib/contract_detail.rb +108 -0
 - data/lib/models/ib/execution.rb +67 -0
 - data/lib/models/ib/forex.rb +13 -0
 - data/lib/models/ib/future.rb +15 -0
 - data/lib/models/ib/index.rb +15 -0
 - data/lib/models/ib/option.rb +78 -0
 - data/lib/models/ib/option_detail.rb +55 -0
 - data/lib/models/ib/order.rb +519 -0
 - data/lib/models/ib/order_state.rb +152 -0
 - data/lib/models/ib/portfolio_value.rb +64 -0
 - data/lib/models/ib/stock.rb +16 -0
 - data/lib/models/ib/underlying.rb +34 -0
 - data/lib/models/ib/vertical.rb +96 -0
 - data/lib/requires.rb +12 -0
 - metadata +203 -0
 
    
        data/lib/ib/socket.rb
    ADDED
    
    | 
         @@ -0,0 +1,185 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 2 
     | 
    
         
            +
            module IBSupport
         
     | 
| 
      
 3 
     | 
    
         
            +
              refine  Array do
         
     | 
| 
      
 4 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 5 
     | 
    
         
            +
                  if blank?
         
     | 
| 
      
 6 
     | 
    
         
            +
            	nil.tws
         
     | 
| 
      
 7 
     | 
    
         
            +
                  else
         
     | 
| 
      
 8 
     | 
    
         
            +
            	self.flatten.map( &:tws ).join  # [ "", [] , nil].flatten -> ["", nil]
         
     | 
| 
      
 9 
     | 
    
         
            +
            					# elemets with empty array's are cut 
         
     | 
| 
      
 10 
     | 
    
         
            +
            					# this is the desired behavior!
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              refine  Symbol do
         
     | 
| 
      
 15 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self.to_s.tws
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              refine String do
         
     | 
| 
      
 20 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 21 
     | 
    
         
            +
                  if empty?
         
     | 
| 
      
 22 
     | 
    
         
            +
            	IB::EOL
         
     | 
| 
      
 23 
     | 
    
         
            +
                  else
         
     | 
| 
      
 24 
     | 
    
         
            +
            	self[-1] == IB::EOL ? self : self+IB::EOL
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              refine  Numeric do
         
     | 
| 
      
 30 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 31 
     | 
    
         
            +
                  self.to_s.tws
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              refine TrueClass do
         
     | 
| 
      
 36 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 37 
     | 
    
         
            +
                  1.tws
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              refine  FalseClass do
         
     | 
| 
      
 42 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 43 
     | 
    
         
            +
                  0.tws
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              refine NilClass do
         
     | 
| 
      
 48 
     | 
    
         
            +
                def tws
         
     | 
| 
      
 49 
     | 
    
         
            +
                 IB::EOL
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
            module IB
         
     | 
| 
      
 54 
     | 
    
         
            +
              # includes methods from IBSupport 
         
     | 
| 
      
 55 
     | 
    
         
            +
            	# which adds a tws-method to  
         
     | 
| 
      
 56 
     | 
    
         
            +
            	# - Array
         
     | 
| 
      
 57 
     | 
    
         
            +
            	# - Symbol
         
     | 
| 
      
 58 
     | 
    
         
            +
            	# - String
         
     | 
| 
      
 59 
     | 
    
         
            +
            	# - Numeric
         
     | 
| 
      
 60 
     | 
    
         
            +
            	# - TrueClass, FalseClass and NilClass
         
     | 
| 
      
 61 
     | 
    
         
            +
            	# 
         
     | 
| 
      
 62 
     | 
    
         
            +
              module PrepareData
         
     | 
| 
      
 63 
     | 
    
         
            +
                using IBSupport
         
     | 
| 
      
 64 
     | 
    
         
            +
            		# First call the method #tws on the data-object
         
     | 
| 
      
 65 
     | 
    
         
            +
            		#
         
     | 
| 
      
 66 
     | 
    
         
            +
            		# Then transfom into an Array using the #Pack-Method
         
     | 
| 
      
 67 
     | 
    
         
            +
            		#
         
     | 
| 
      
 68 
     | 
    
         
            +
            		# The optional Block introduces a user-defined pattern to pack the data.
         
     | 
| 
      
 69 
     | 
    
         
            +
            		#
         
     | 
| 
      
 70 
     | 
    
         
            +
            		# Default is "Na*"
         
     | 
| 
      
 71 
     | 
    
         
            +
            		def prepare_message data
         
     | 
| 
      
 72 
     | 
    
         
            +
            			data =  data.tws unless data.is_a?(String) && data[-1]== EOL
         
     | 
| 
      
 73 
     | 
    
         
            +
            			matrize = [data.size,data]
         
     | 
| 
      
 74 
     | 
    
         
            +
            			if block_given?	    # A user defined decoding-sequence is accepted via block
         
     | 
| 
      
 75 
     | 
    
         
            +
            				matrize.pack yield
         
     | 
| 
      
 76 
     | 
    
         
            +
            			else
         
     | 
| 
      
 77 
     | 
    
         
            +
            				matrize.pack  "Na*"
         
     | 
| 
      
 78 
     | 
    
         
            +
            			end
         
     | 
| 
      
 79 
     | 
    
         
            +
            		end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            			# The received package is decoded. The parameter (msg) is an Array
         
     | 
| 
      
 82 
     | 
    
         
            +
            			#
         
     | 
| 
      
 83 
     | 
    
         
            +
            			# The protocol is simple: Every Element is treated as Character. 
         
     | 
| 
      
 84 
     | 
    
         
            +
            			# Exception: The first Element determines the expected length. 
         
     | 
| 
      
 85 
     | 
    
         
            +
            			#
         
     | 
| 
      
 86 
     | 
    
         
            +
            			# The decoded raw-message can further modified by the optional block.
         
     | 
| 
      
 87 
     | 
    
         
            +
            			# 
         
     | 
| 
      
 88 
     | 
    
         
            +
            			# The default is to instantiate a Hash: message_id becomes the key.
         
     | 
| 
      
 89 
     | 
    
         
            +
            			# The Hash is returned
         
     | 
| 
      
 90 
     | 
    
         
            +
            			#
         
     | 
| 
      
 91 
     | 
    
         
            +
            			# If a block is provided, no Hash is build and the modified raw-message is returned
         
     | 
| 
      
 92 
     | 
    
         
            +
            		def decode_message msg
         
     | 
| 
      
 93 
     | 
    
         
            +
            			m = Hash.new
         
     | 
| 
      
 94 
     | 
    
         
            +
            			while not msg.blank?
         
     | 
| 
      
 95 
     | 
    
         
            +
            				# the first item is the length
         
     | 
| 
      
 96 
     | 
    
         
            +
            				size= msg[0..4].unpack("N").first
         
     | 
| 
      
 97 
     | 
    
         
            +
            				msg =  msg[4..-1]
         
     | 
| 
      
 98 
     | 
    
         
            +
            				# followed by a sequence of characters
         
     | 
| 
      
 99 
     | 
    
         
            +
            				message =  msg.unpack("A#{size}").first.split("\0")
         
     | 
| 
      
 100 
     | 
    
         
            +
            				if block_given?
         
     | 
| 
      
 101 
     | 
    
         
            +
            					yield message
         
     | 
| 
      
 102 
     | 
    
         
            +
            				else
         
     | 
| 
      
 103 
     | 
    
         
            +
            					m[message.shift.to_i] = message
         
     | 
| 
      
 104 
     | 
    
         
            +
            				end
         
     | 
| 
      
 105 
     | 
    
         
            +
            				msg =  msg[size..-1]
         
     | 
| 
      
 106 
     | 
    
         
            +
            			end
         
     | 
| 
      
 107 
     | 
    
         
            +
            			return m unless block_given?
         
     | 
| 
      
 108 
     | 
    
         
            +
            		end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            	end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              class IBSocket < TCPSocket
         
     | 
| 
      
 113 
     | 
    
         
            +
                include PrepareData
         
     | 
| 
      
 114 
     | 
    
         
            +
                using IBSupport
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                def initialising_handshake
         
     | 
| 
      
 117 
     | 
    
         
            +
                  v100_prefix = "API".tws.encode 'ascii' 
         
     | 
| 
      
 118 
     | 
    
         
            +
                  v100_version = self.prepare_message Messages::SERVER_VERSION
         
     | 
| 
      
 119 
     | 
    
         
            +
                  write_data v100_prefix+v100_version
         
     | 
| 
      
 120 
     | 
    
         
            +
                ## start tws-log
         
     | 
| 
      
 121 
     | 
    
         
            +
                # [QO] INFO  [JTS-SocketListener-49] - State: HEADER, IsAPI: UNKNOWN
         
     | 
| 
      
 122 
     | 
    
         
            +
                # [QO] INFO  [JTS-SocketListener-49] - State: STOP, IsAPI: YES
         
     | 
| 
      
 123 
     | 
    
         
            +
                # [QO] INFO  [JTS-SocketListener-49] - ArEServer: Adding 392382055 with id 2147483647
         
     | 
| 
      
 124 
     | 
    
         
            +
                # [QO] INFO  [JTS-SocketListener-49] - eServersChanged: 1
         
     | 
| 
      
 125 
     | 
    
         
            +
                # [QO] INFO  [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Starting new conversation with client on 127.0.0.1
         
     | 
| 
      
 126 
     | 
    
         
            +
                # [QO] INFO  [JTS-EServerSocketNotifier-288] - Starting async queue thread
         
     | 
| 
      
 127 
     | 
    
         
            +
                # [QO] INFO  [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Server version is 136
         
     | 
| 
      
 128 
     | 
    
         
            +
                # [QO] INFO  [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Client version is 136
         
     | 
| 
      
 129 
     | 
    
         
            +
                # [QO] INFO  [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] is 3rdParty true
         
     | 
| 
      
 130 
     | 
    
         
            +
                ## end tws-log
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                def read_string
         
     | 
| 
      
 135 
     | 
    
         
            +
                  string = self.gets(EOL)
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                  until string
         
     | 
| 
      
 138 
     | 
    
         
            +
            	# Silently ignores nils
         
     | 
| 
      
 139 
     | 
    
         
            +
            	string = self.gets(EOL)
         
     | 
| 
      
 140 
     | 
    
         
            +
            	sleep 0.1
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  string.chomp
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                # Sends null terminated data string into socket
         
     | 
| 
      
 148 
     | 
    
         
            +
                def write_data data
         
     | 
| 
      
 149 
     | 
    
         
            +
                  self.syswrite data.tws
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                # send the message (containing several instructions) to the socket,
         
     | 
| 
      
 153 
     | 
    
         
            +
                # calls prepare_message to convert data-elements into NULL-terminated strings
         
     | 
| 
      
 154 
     | 
    
         
            +
                def send_messages *data
         
     | 
| 
      
 155 
     | 
    
         
            +
                  self.syswrite prepare_message(data)
         
     | 
| 
      
 156 
     | 
    
         
            +
                rescue Errno::ECONNRESET =>  e
         
     | 
| 
      
 157 
     | 
    
         
            +
                  Connection.logger.error{ "Data not accepted by IB \n
         
     | 
| 
      
 158 
     | 
    
         
            +
            		    #{data.inspect} \n
         
     | 
| 
      
 159 
     | 
    
         
            +
            		    Backtrace:\n "}
         
     | 
| 
      
 160 
     | 
    
         
            +
                  Connection.logger.error   e.backtrace
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                def recieve_messages
         
     | 
| 
      
 164 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 165 
     | 
    
         
            +
            	complete_message_buffer = []
         
     | 
| 
      
 166 
     | 
    
         
            +
            	begin 
         
     | 
| 
      
 167 
     | 
    
         
            +
            	  # this is the blocking version of recv
         
     | 
| 
      
 168 
     | 
    
         
            +
            	  buffer =  self.recvfrom(4096)[0]
         
     | 
| 
      
 169 
     | 
    
         
            +
            	# STDOUT.puts "BUFFER:: #{buffer.inspect}"
         
     | 
| 
      
 170 
     | 
    
         
            +
            	  complete_message_buffer << buffer
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            	end while buffer.size == 4096
         
     | 
| 
      
 173 
     | 
    
         
            +
            	complete_message_buffer.join('')
         
     | 
| 
      
 174 
     | 
    
         
            +
                  rescue Errno::ECONNRESET =>  e
         
     | 
| 
      
 175 
     | 
    
         
            +
            	    Connection.logger.error{ "Data Buffer is not filling \n
         
     | 
| 
      
 176 
     | 
    
         
            +
            		    The Buffer: #{buffer.inspect} \n
         
     | 
| 
      
 177 
     | 
    
         
            +
            		    Backtrace:\n 
         
     | 
| 
      
 178 
     | 
    
         
            +
            	 #{e.backtrace.join("\n") } " }
         
     | 
| 
      
 179 
     | 
    
         
            +
            	Kernel.exit
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
              end # class IBSocket
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            end # module IB
         
     | 
    
        data/lib/ib/support.rb
    ADDED
    
    | 
         @@ -0,0 +1,160 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            module IBSupport
         
     | 
| 
      
 3 
     | 
    
         
            +
            	refine Array do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            		def zero?
         
     | 
| 
      
 6 
     | 
    
         
            +
            			false
         
     | 
| 
      
 7 
     | 
    
         
            +
            		end
         
     | 
| 
      
 8 
     | 
    
         
            +
            		# Returns the integer. 
         
     | 
| 
      
 9 
     | 
    
         
            +
            		# retuns nil otherwise or if no element is left on the stack
         
     | 
| 
      
 10 
     | 
    
         
            +
            		def read_int
         
     | 
| 
      
 11 
     | 
    
         
            +
            			i= self.shift  rescue nil
         
     | 
| 
      
 12 
     | 
    
         
            +
            			i = i.to_i unless i.blank?			# this includes conversion of string to zero(0)
         
     | 
| 
      
 13 
     | 
    
         
            +
            			i.is_a?( Integer ) ?  i : nil
         
     | 
| 
      
 14 
     | 
    
         
            +
            		end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            		def read_float
         
     | 
| 
      
 17 
     | 
    
         
            +
            			i= self.shift  rescue nil
         
     | 
| 
      
 18 
     | 
    
         
            +
            			i = i.to_f unless i.blank?
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            		end
         
     | 
| 
      
 21 
     | 
    
         
            +
            		def read_decimal
         
     | 
| 
      
 22 
     | 
    
         
            +
            			i= self.shift  rescue nil
         
     | 
| 
      
 23 
     | 
    
         
            +
            			i = i.to_d unless i.blank?
         
     | 
| 
      
 24 
     | 
    
         
            +
            			i.is_a?(Numeric)  && i < IB::TWS_MAX ?  i : nil  # return nil, if a very large number is transmitted
         
     | 
| 
      
 25 
     | 
    
         
            +
            		end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            		alias read_decimal_max read_decimal
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            		## Values -1 and below indicate: Not computed (TickOptionComputation)
         
     | 
| 
      
 30 
     | 
    
         
            +
            		def read_decimal_limit_1
         
     | 
| 
      
 31 
     | 
    
         
            +
            			i= read_decimal
         
     | 
| 
      
 32 
     | 
    
         
            +
            			i <= -1 ? nil : i
         
     | 
| 
      
 33 
     | 
    
         
            +
            		end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            		## Values -2 and below indicate: Not computed (TickOptionComputation)
         
     | 
| 
      
 36 
     | 
    
         
            +
            		def read_decimal_limit_2
         
     | 
| 
      
 37 
     | 
    
         
            +
            			i= read_decimal
         
     | 
| 
      
 38 
     | 
    
         
            +
            			i <= -2 ? nil : i
         
     | 
| 
      
 39 
     | 
    
         
            +
            		end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            		def read_string
         
     | 
| 
      
 43 
     | 
    
         
            +
            			self.shift rescue ""
         
     | 
| 
      
 44 
     | 
    
         
            +
            		end
         
     | 
| 
      
 45 
     | 
    
         
            +
            		## reads a string and proofs if NULL ==  IB::TWS_MAX is present.
         
     | 
| 
      
 46 
     | 
    
         
            +
            		## in that case: returns nil. otherwise: returns the string
         
     | 
| 
      
 47 
     | 
    
         
            +
            		def read_string_not_null
         
     | 
| 
      
 48 
     | 
    
         
            +
            			r = read_string
         
     | 
| 
      
 49 
     | 
    
         
            +
            			rd = r.to_d  unless r.blank?
         
     | 
| 
      
 50 
     | 
    
         
            +
            			rd.is_a?(Numeric) && rd >= IB::TWS_MAX ? nil : r
         
     | 
| 
      
 51 
     | 
    
         
            +
            		end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            		def read_symbol
         
     | 
| 
      
 54 
     | 
    
         
            +
            			read_string.to_sym
         
     | 
| 
      
 55 
     | 
    
         
            +
            		end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            		# convert xml into a hash
         
     | 
| 
      
 58 
     | 
    
         
            +
            		def read_xml
         
     | 
| 
      
 59 
     | 
    
         
            +
            			Ox.load( read_string(), mode: :hash_no_attrs)
         
     | 
| 
      
 60 
     | 
    
         
            +
            		end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            		def read_int_date
         
     | 
| 
      
 64 
     | 
    
         
            +
            			t= read_int
         
     | 
| 
      
 65 
     | 
    
         
            +
            				s= Time.at(t)
         
     | 
| 
      
 66 
     | 
    
         
            +
            	#			s.year == 1970  --> data is most likely a date-string
         
     | 
| 
      
 67 
     | 
    
         
            +
            				s.year == 1970 ? Date.parse(t.to_s) : s
         
     | 
| 
      
 68 
     | 
    
         
            +
            		end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            		def read_parse_date
         
     | 
| 
      
 71 
     | 
    
         
            +
            			Time.parse read_string
         
     | 
| 
      
 72 
     | 
    
         
            +
            		end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            		def read_boolean
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            			v = self.shift  rescue nil
         
     | 
| 
      
 77 
     | 
    
         
            +
            			case v
         
     | 
| 
      
 78 
     | 
    
         
            +
            			when "1"
         
     | 
| 
      
 79 
     | 
    
         
            +
            				true
         
     | 
| 
      
 80 
     | 
    
         
            +
            			when "0"
         
     | 
| 
      
 81 
     | 
    
         
            +
            				false
         
     | 
| 
      
 82 
     | 
    
         
            +
            			else nil
         
     | 
| 
      
 83 
     | 
    
         
            +
            			end
         
     | 
| 
      
 84 
     | 
    
         
            +
            		end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            		def read_datetime
         
     | 
| 
      
 88 
     | 
    
         
            +
            			the_string = read_string
         
     | 
| 
      
 89 
     | 
    
         
            +
            			the_string.blank? ? nil : DateTime.parse(the_string)
         
     | 
| 
      
 90 
     | 
    
         
            +
            		end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            		def read_date
         
     | 
| 
      
 93 
     | 
    
         
            +
            			the_string = read_string
         
     | 
| 
      
 94 
     | 
    
         
            +
            			the_string.blank? ? nil : Date.parse(the_string)
         
     | 
| 
      
 95 
     | 
    
         
            +
            		end
         
     | 
| 
      
 96 
     | 
    
         
            +
            		#    def read_array
         
     | 
| 
      
 97 
     | 
    
         
            +
            		#      count = read_int
         
     | 
| 
      
 98 
     | 
    
         
            +
            		#    end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            		## originally provided in socket.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            		#    # Returns loaded Array or [] if count was 0#
         
     | 
| 
      
 102 
     | 
    
         
            +
            		#
         
     | 
| 
      
 103 
     | 
    
         
            +
            		#    Without providing a Block, the elements are treated as string
         
     | 
| 
      
 104 
     | 
    
         
            +
            		def read_array hashmode:false,  &block
         
     | 
| 
      
 105 
     | 
    
         
            +
            			count = read_int
         
     | 
| 
      
 106 
     | 
    
         
            +
            			case	count 
         
     | 
| 
      
 107 
     | 
    
         
            +
            			when  0 
         
     | 
| 
      
 108 
     | 
    
         
            +
            				[]
         
     | 
| 
      
 109 
     | 
    
         
            +
            			when nil
         
     | 
| 
      
 110 
     | 
    
         
            +
            				nil
         
     | 
| 
      
 111 
     | 
    
         
            +
            			else
         
     | 
| 
      
 112 
     | 
    
         
            +
            				count= count + count if hashmode
         
     | 
| 
      
 113 
     | 
    
         
            +
            				if block_given?
         
     | 
| 
      
 114 
     | 
    
         
            +
            					Array.new(count, &block) 
         
     | 
| 
      
 115 
     | 
    
         
            +
            				else
         
     | 
| 
      
 116 
     | 
    
         
            +
            					Array.new( count ){ read_string }
         
     | 
| 
      
 117 
     | 
    
         
            +
            				end
         
     | 
| 
      
 118 
     | 
    
         
            +
            			end 
         
     | 
| 
      
 119 
     | 
    
         
            +
            		end
         
     | 
| 
      
 120 
     | 
    
         
            +
            		#   
         
     | 
| 
      
 121 
     | 
    
         
            +
            		#  Returns a hash 
         
     | 
| 
      
 122 
     | 
    
         
            +
            		#  Expected Buffer-Format: 
         
     | 
| 
      
 123 
     | 
    
         
            +
            		#			count (of Hash-elements)
         
     | 
| 
      
 124 
     | 
    
         
            +
            		#			count* key|Value
         
     | 
| 
      
 125 
     | 
    
         
            +
            		#	 Key's are transformed to symbols, values are treated as string
         
     | 
| 
      
 126 
     | 
    
         
            +
            		def read_hash
         
     | 
| 
      
 127 
     | 
    
         
            +
            			tags = read_array( hashmode: true )  # { |_| [read_string, read_string] }
         
     | 
| 
      
 128 
     | 
    
         
            +
            		result =   if 	tags.nil? || tags.flatten.empty?
         
     | 
| 
      
 129 
     | 
    
         
            +
            								 tags
         
     | 
| 
      
 130 
     | 
    
         
            +
            							 else
         
     | 
| 
      
 131 
     | 
    
         
            +
            								 interim = if  tags.size.modulo(2).zero? 
         
     | 
| 
      
 132 
     | 
    
         
            +
            														 Hash[*tags.flatten]
         
     | 
| 
      
 133 
     | 
    
         
            +
            													 else 
         
     | 
| 
      
 134 
     | 
    
         
            +
            														 Hash[*tags[0..-2].flatten]  # omit the last element
         
     | 
| 
      
 135 
     | 
    
         
            +
            													 end
         
     | 
| 
      
 136 
     | 
    
         
            +
            								 # symbolize Hash
         
     | 
| 
      
 137 
     | 
    
         
            +
            								 Hash[interim.map { |k, v| [k.to_sym, v] unless k.nil? }.compact]
         
     | 
| 
      
 138 
     | 
    
         
            +
            							 end
         
     | 
| 
      
 139 
     | 
    
         
            +
            		end
         
     | 
| 
      
 140 
     | 
    
         
            +
            		#
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            		def read_contract  # read a standard contract and return als hash
         
     | 
| 
      
 143 
     | 
    
         
            +
            			{	 con_id: read_int,
         
     | 
| 
      
 144 
     | 
    
         
            +
            				 symbol: read_string,
         
     | 
| 
      
 145 
     | 
    
         
            +
            				 sec_type: read_string,
         
     | 
| 
      
 146 
     | 
    
         
            +
            				 expiry: read_string,
         
     | 
| 
      
 147 
     | 
    
         
            +
            				 strike: read_decimal,
         
     | 
| 
      
 148 
     | 
    
         
            +
            				 right: read_string,
         
     | 
| 
      
 149 
     | 
    
         
            +
            				 multiplier: read_int,		
         
     | 
| 
      
 150 
     | 
    
         
            +
            				 exchange: read_string,
         
     | 
| 
      
 151 
     | 
    
         
            +
            				 currency: read_string,
         
     | 
| 
      
 152 
     | 
    
         
            +
            				 local_symbol: read_string,
         
     | 
| 
      
 153 
     | 
    
         
            +
            				 trading_class: read_string }  # new Version 8
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            		end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            		alias read_bool read_boolean
         
     | 
| 
      
 159 
     | 
    
         
            +
            	end
         
     | 
| 
      
 160 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/ib/version.rb
    ADDED
    
    
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module IB
         
     | 
| 
      
 2 
     | 
    
         
            +
            	class Account < IB::Model
         
     | 
| 
      
 3 
     | 
    
         
            +
            		include BaseProperties
         
     | 
| 
      
 4 
     | 
    
         
            +
            #		include Redis::Objects
         
     | 
| 
      
 5 
     | 
    
         
            +
            		#  attr_accessible :alias, :account, :connected
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            		prop :account,  # String 
         
     | 
| 
      
 8 
     | 
    
         
            +
            			:alias,     # 
         
     | 
| 
      
 9 
     | 
    
         
            +
            			:type,
         
     | 
| 
      
 10 
     | 
    
         
            +
            			:last_updated,
         
     | 
| 
      
 11 
     | 
    
         
            +
            			:connected => :bool
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            #		redis_id_field :account
         
     | 
| 
      
 14 
     | 
    
         
            +
            #		value :my_alias
         
     | 
| 
      
 15 
     | 
    
         
            +
            #		value :the_account
         
     | 
| 
      
 16 
     | 
    
         
            +
            #		value :active
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            		validates_format_of :account, :with =>  /\A[D]?[UF]{1}\d{5,8}\z/ , :message => 'should be (X)X00000'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            		# in tableless mode the scope is ignored
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            		has_many :account_values
         
     | 
| 
      
 24 
     | 
    
         
            +
            		has_many :portfolio_values
         
     | 
| 
      
 25 
     | 
    
         
            +
            		has_many :contracts
         
     | 
| 
      
 26 
     | 
    
         
            +
            		has_many :orders
         
     | 
| 
      
 27 
     | 
    
         
            +
            		has_many :focuses
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            		def default_attributes
         
     | 
| 
      
 30 
     | 
    
         
            +
            			super.merge account: 'X000000'
         
     | 
| 
      
 31 
     | 
    
         
            +
            			super.merge alias: ''
         
     | 
| 
      
 32 
     | 
    
         
            +
            			super.merge type: 'Account'
         
     | 
| 
      
 33 
     | 
    
         
            +
            			super.merge connected: false
         
     | 
| 
      
 34 
     | 
    
         
            +
            		end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            		def logger  #nodoc#
         
     | 
| 
      
 37 
     | 
    
         
            +
            			Connection.logger
         
     | 
| 
      
 38 
     | 
    
         
            +
            		end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            		# Setze Account connect/disconnect und undate!
         
     | 
| 
      
 41 
     | 
    
         
            +
            		def connect!
         
     | 
| 
      
 42 
     | 
    
         
            +
            			update_attribute :connected , true
         
     | 
| 
      
 43 
     | 
    
         
            +
            		end 
         
     | 
| 
      
 44 
     | 
    
         
            +
            		def disconnect!
         
     | 
| 
      
 45 
     | 
    
         
            +
            			update_attribute :connected , false
         
     | 
| 
      
 46 
     | 
    
         
            +
            		end 
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            		def print_type #nodoc#
         
     | 
| 
      
 49 
     | 
    
         
            +
            			(test_environment? ? "demo_"  : "") + ( user? ? "user" : "advisor" )
         
     | 
| 
      
 50 
     | 
    
         
            +
            		end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            		def advisor?
         
     | 
| 
      
 53 
     | 
    
         
            +
            			!!(type =~ /Advisor/ || account =~ /\A[D]?[F]{1}/)
         
     | 
| 
      
 54 
     | 
    
         
            +
            		end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            		def user?
         
     | 
| 
      
 57 
     | 
    
         
            +
            			!!(type =~ /User/ || account =~ /\A[D]?[U]{1}/)
         
     | 
| 
      
 58 
     | 
    
         
            +
            		end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            		def test_environment?
         
     | 
| 
      
 61 
     | 
    
         
            +
            			!!(account =~ /^[D]{1}/)
         
     | 
| 
      
 62 
     | 
    
         
            +
            		end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            		def == other
         
     | 
| 
      
 65 
     | 
    
         
            +
            			super(other) ||
         
     | 
| 
      
 66 
     | 
    
         
            +
            				other.is_a?(self.class) && account == other.account
         
     | 
| 
      
 67 
     | 
    
         
            +
            		end 
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            		def to_human
         
     | 
| 
      
 70 
     | 
    
         
            +
            			a = if self.alias.present?  && self.alias != account
         
     | 
| 
      
 71 
     | 
    
         
            +
            						" alias: "+ self.alias
         
     | 
| 
      
 72 
     | 
    
         
            +
            					else
         
     | 
| 
      
 73 
     | 
    
         
            +
            						""
         
     | 
| 
      
 74 
     | 
    
         
            +
            					end
         
     | 
| 
      
 75 
     | 
    
         
            +
            				"<#{print_type} #{account}#{a}>"
         
     | 
| 
      
 76 
     | 
    
         
            +
            		end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            		def name  #nodoc#
         
     | 
| 
      
 79 
     | 
    
         
            +
            			self.alias.present? ? self.alias : account
         
     | 
| 
      
 80 
     | 
    
         
            +
            		end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            #		alias :id :account
         
     | 
| 
      
 83 
     | 
    
         
            +
            end # class
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            end # module
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module IB
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Instantiate with a Hash of attributes, to be auto-set via initialize in Model.
         
     | 
| 
      
 3 
     | 
    
         
            +
              class AccountValue < IB::Model
         
     | 
| 
      
 4 
     | 
    
         
            +
                include BaseProperties
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                belongs_to :account 
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                prop  :key,
         
     | 
| 
      
 9 
     | 
    
         
            +
            	  :value,
         
     | 
| 
      
 10 
     | 
    
         
            +
            	  :currency
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                #  comparison
         
     | 
| 
      
 14 
     | 
    
         
            +
                def == other
         
     | 
| 
      
 15 
     | 
    
         
            +
                  super(other) ||
         
     | 
| 
      
 16 
     | 
    
         
            +
                    other.is_a?(self.class) &&
         
     | 
| 
      
 17 
     | 
    
         
            +
                    key == other.key &&
         
     | 
| 
      
 18 
     | 
    
         
            +
                    currency == other.currency &&
         
     | 
| 
      
 19 
     | 
    
         
            +
                    value == other.value 
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                def default_attributes
         
     | 
| 
      
 22 
     | 
    
         
            +
                  super.merge key: 'AccountValue',
         
     | 
| 
      
 23 
     | 
    
         
            +
            	value: 0,
         
     | 
| 
      
 24 
     | 
    
         
            +
            	currency: 'USD'
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def to_human
         
     | 
| 
      
 28 
     | 
    
         
            +
                   "<#{key}=#{value} #{currency}>"
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                alias to_s to_human
         
     | 
| 
      
 32 
     | 
    
         
            +
              end # class 
         
     | 
| 
      
 33 
     | 
    
         
            +
            end # module IB
         
     |