ib-api 10.33.4 → 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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/Gemfile +2 -3
  4. data/Gemfile.lock +52 -67
  5. data/README.md +8 -60
  6. data/VERSION +1 -1
  7. data/api.gemspec +3 -10
  8. data/bin/console +38 -39
  9. data/bin/console.yml +2 -2
  10. data/changelog.md +0 -25
  11. data/example/README.md +76 -0
  12. data/example/account_info +54 -0
  13. data/example/account_positions +30 -0
  14. data/example/account_summary +88 -0
  15. data/example/cancel_orders +74 -0
  16. data/example/fa_accounts +25 -0
  17. data/example/fundamental_data +40 -0
  18. data/example/historic_data_cli +186 -0
  19. data/example/list_orders +45 -0
  20. data/example/portfolio_csv +81 -0
  21. data/example/scanner_data +62 -0
  22. data/example/template +19 -0
  23. data/example/tick_data +28 -0
  24. data/lib/extensions/class-extensions.rb +87 -0
  25. data/lib/ib/base.rb +1 -7
  26. data/lib/ib/base_properties.rb +12 -30
  27. data/lib/ib/connection.rb +269 -418
  28. data/lib/ib/constants.rb +22 -31
  29. data/lib/ib/errors.rb +1 -9
  30. data/lib/ib/logger.rb +26 -0
  31. data/lib/ib/messages/abstract_message.rb +43 -10
  32. data/lib/ib/messages/incoming/abstract_message.rb +98 -98
  33. data/lib/ib/messages/incoming/account_value.rb +78 -0
  34. data/lib/ib/messages/incoming/alert.rb +4 -4
  35. data/lib/ib/messages/incoming/contract_data.rb +29 -32
  36. data/lib/ib/messages/incoming/execution_data.rb +3 -3
  37. data/lib/ib/messages/incoming/historical_data.rb +33 -14
  38. data/lib/ib/messages/incoming/{market_depth.rb → market_depths.rb} +10 -0
  39. data/lib/ib/messages/incoming/next_valid_id.rb +0 -1
  40. data/lib/ib/messages/incoming/open_order.rb +201 -214
  41. data/lib/ib/messages/incoming/order_status.rb +1 -1
  42. data/lib/ib/messages/incoming/portfolio_value.rb +58 -27
  43. data/lib/ib/messages/incoming/scanner_data.rb +1 -1
  44. data/lib/ib/messages/incoming/ticks.rb +268 -0
  45. data/lib/ib/messages/incoming.rb +95 -136
  46. data/lib/ib/messages/outgoing/abstract_message.rb +22 -18
  47. data/lib/ib/messages/outgoing/{request_account_summary.rb → account_requests.rb} +40 -7
  48. data/lib/ib/messages/outgoing/{bar_request_message.rb → bar_requests.rb} +16 -13
  49. data/lib/ib/messages/outgoing/place_order.rb +198 -138
  50. data/lib/ib/messages/outgoing/{request_market_data.rb → request_marketdata.rb} +29 -32
  51. data/lib/ib/messages/outgoing/request_tick_data.rb +21 -0
  52. data/lib/ib/messages/outgoing.rb +160 -133
  53. data/lib/ib/messages.rb +7 -47
  54. data/lib/ib/model.rb +4 -0
  55. data/lib/ib/models.rb +14 -0
  56. data/lib/{server_versions.rb → ib/server_versions.rb} +9 -40
  57. data/lib/ib/socket.rb +147 -45
  58. data/lib/ib/support.rb +158 -240
  59. data/lib/ib/version.rb +1 -1
  60. data/lib/ib-api.rb +5 -42
  61. data/lib/models/ib/account.rb +85 -0
  62. data/{models → lib/models}/ib/account_value.rb +5 -5
  63. data/{models → lib/models}/ib/bag.rb +7 -7
  64. data/{models → lib/models}/ib/bar.rb +2 -2
  65. data/{models → lib/models}/ib/combo_leg.rb +4 -26
  66. data/lib/models/ib/condition.rb +245 -0
  67. data/{models → lib/models}/ib/contract.rb +170 -166
  68. data/{models → lib/models}/ib/contract_detail.rb +15 -25
  69. data/{models → lib/models}/ib/execution.rb +1 -1
  70. data/{models → lib/models}/ib/forex.rb +2 -1
  71. data/lib/models/ib/future.rb +15 -0
  72. data/{models → lib/models}/ib/index.rb +3 -2
  73. data/lib/models/ib/option.rb +78 -0
  74. data/lib/models/ib/option_detail.rb +55 -0
  75. data/{models → lib/models}/ib/order.rb +165 -366
  76. data/{models → lib/models}/ib/order_state.rb +22 -25
  77. data/lib/models/ib/portfolio_value.rb +64 -0
  78. data/lib/models/ib/stock.rb +16 -0
  79. data/{models → lib/models}/ib/underlying.rb +5 -3
  80. data/lib/models/ib/vertical.rb +96 -0
  81. data/lib/requires.rb +12 -0
  82. metadata +64 -188
  83. data/CLAUDE.md +0 -131
  84. data/LLM_GUIDE.md +0 -388
  85. data/bin/simple +0 -91
  86. data/conditions/ib/execution_condition.rb +0 -31
  87. data/conditions/ib/margin_condition.rb +0 -28
  88. data/conditions/ib/order_condition.rb +0 -29
  89. data/conditions/ib/percent_change_condition.rb +0 -34
  90. data/conditions/ib/price_condition.rb +0 -44
  91. data/conditions/ib/time_condition.rb +0 -42
  92. data/conditions/ib/volume_condition.rb +0 -36
  93. data/lib/class_extensions.rb +0 -167
  94. data/lib/ib/contract.rb +0 -30
  95. data/lib/ib/messages/incoming/abstract_tick.rb +0 -25
  96. data/lib/ib/messages/incoming/account_message.rb +0 -26
  97. data/lib/ib/messages/incoming/contract_message.rb +0 -13
  98. data/lib/ib/messages/incoming/histogram_data.rb +0 -30
  99. data/lib/ib/messages/incoming/historical_data_update.rb +0 -50
  100. data/lib/ib/messages/incoming/managed_accounts.rb +0 -21
  101. data/lib/ib/messages/incoming/market_depth_l2.rb +0 -15
  102. data/lib/ib/messages/incoming/position_data.rb +0 -21
  103. data/lib/ib/messages/incoming/positions_multi.rb +0 -15
  104. data/lib/ib/messages/incoming/receive_fa.rb +0 -30
  105. data/lib/ib/messages/incoming/tick_by_tick.rb +0 -77
  106. data/lib/ib/messages/incoming/tick_efp.rb +0 -18
  107. data/lib/ib/messages/incoming/tick_generic.rb +0 -12
  108. data/lib/ib/messages/incoming/tick_option.rb +0 -60
  109. data/lib/ib/messages/incoming/tick_price.rb +0 -60
  110. data/lib/ib/messages/incoming/tick_size.rb +0 -55
  111. data/lib/ib/messages/incoming/tick_string.rb +0 -13
  112. data/lib/ib/messages/outgoing/new-place-order.rb +0 -193
  113. data/lib/ib/messages/outgoing/old-place-order.rb +0 -147
  114. data/lib/ib/messages/outgoing/request_historical_data.rb +0 -182
  115. data/lib/ib/messages/outgoing/request_market_depth.rb +0 -57
  116. data/lib/ib/messages/outgoing/request_real_time_bars.rb +0 -48
  117. data/lib/ib/messages/outgoing/request_scanner_subscription.rb +0 -73
  118. data/lib/ib/messages/outgoing/request_tick_by_tick_data.rb +0 -21
  119. data/lib/ib/order_condition.rb +0 -26
  120. data/lib/ib/plugins.rb +0 -27
  121. data/lib/ib/prepare_data.rb +0 -61
  122. data/lib/ib/raw_message_parser.rb +0 -99
  123. data/lib/support/array_function.rb +0 -28
  124. data/lib/support/logging.rb +0 -45
  125. data/models/ib/account.rb +0 -72
  126. data/models/ib/future.rb +0 -64
  127. data/models/ib/option.rb +0 -149
  128. data/models/ib/option_detail.rb +0 -84
  129. data/models/ib/portfolio_value.rb +0 -86
  130. data/models/ib/spread.rb +0 -176
  131. data/models/ib/stock.rb +0 -25
  132. data/plugins/ib/advanced-account.rb +0 -442
  133. data/plugins/ib/alerts/base-alert.rb +0 -125
  134. data/plugins/ib/alerts/gateway-alerts.rb +0 -15
  135. data/plugins/ib/alerts/order-alerts.rb +0 -73
  136. data/plugins/ib/auto-adjust.rb +0 -0
  137. data/plugins/ib/connection-tools.rb +0 -122
  138. data/plugins/ib/eod.rb +0 -326
  139. data/plugins/ib/greeks.rb +0 -102
  140. data/plugins/ib/managed-accounts.rb +0 -274
  141. data/plugins/ib/market-price.rb +0 -150
  142. data/plugins/ib/option-chain.rb +0 -167
  143. data/plugins/ib/order-flow.rb +0 -157
  144. data/plugins/ib/order-prototypes/abstract.rb +0 -67
  145. data/plugins/ib/order-prototypes/adaptive.rb +0 -40
  146. data/plugins/ib/order-prototypes/all-in-one.rb +0 -46
  147. data/plugins/ib/order-prototypes/combo.rb +0 -46
  148. data/plugins/ib/order-prototypes/forex.rb +0 -40
  149. data/plugins/ib/order-prototypes/limit.rb +0 -193
  150. data/plugins/ib/order-prototypes/market.rb +0 -116
  151. data/plugins/ib/order-prototypes/pegged.rb +0 -169
  152. data/plugins/ib/order-prototypes/premarket.rb +0 -31
  153. data/plugins/ib/order-prototypes/stop.rb +0 -202
  154. data/plugins/ib/order-prototypes/volatility.rb +0 -39
  155. data/plugins/ib/order-prototypes.rb +0 -118
  156. data/plugins/ib/probability-of-expiring.rb +0 -109
  157. data/plugins/ib/process-orders.rb +0 -155
  158. data/plugins/ib/roll.rb +0 -86
  159. data/plugins/ib/spread-prototypes/butterfly.rb +0 -77
  160. data/plugins/ib/spread-prototypes/calendar.rb +0 -97
  161. data/plugins/ib/spread-prototypes/stock-spread.rb +0 -56
  162. data/plugins/ib/spread-prototypes/straddle.rb +0 -70
  163. data/plugins/ib/spread-prototypes/strangle.rb +0 -93
  164. data/plugins/ib/spread-prototypes/vertical.rb +0 -83
  165. data/plugins/ib/spread-prototypes.rb +0 -70
  166. data/plugins/ib/symbols/abstract.rb +0 -136
  167. data/plugins/ib/symbols/bonds.rb +0 -28
  168. data/plugins/ib/symbols/cfd.rb +0 -19
  169. data/plugins/ib/symbols/combo.rb +0 -46
  170. data/plugins/ib/symbols/commodity.rb +0 -17
  171. data/plugins/ib/symbols/forex.rb +0 -41
  172. data/plugins/ib/symbols/futures.rb +0 -127
  173. data/plugins/ib/symbols/index.rb +0 -43
  174. data/plugins/ib/symbols/options.rb +0 -99
  175. data/plugins/ib/symbols/stocks.rb +0 -44
  176. data/plugins/ib/symbols/version.rb +0 -5
  177. data/plugins/ib/symbols.rb +0 -118
  178. data/plugins/ib/verify.rb +0 -226
  179. data/symbols/w20.yml +0 -210
  180. data/t.txt +0 -20
  181. data/update.md +0 -71
@@ -10,7 +10,7 @@ subject to the terms and conditions of the IB API Non-Commercial License or the
10
10
  The known server versions.
11
11
  =end
12
12
 
13
- KNOWN_SERVERS = {
13
+ known_servers = {
14
14
  #min_server_ver_real_time_bars => 34,
15
15
  #min_server_ver_scale_orders => 35,
16
16
  #min_server_ver_snapshot_mkt_data => 35,
@@ -19,7 +19,7 @@ KNOWN_SERVERS = {
19
19
  #min_server_ver_contract_conid => 37,
20
20
  :min_server_ver_pta_orders => 39,
21
21
  :min_server_ver_fundamental_data => 40,
22
- :min_server_ver_delta_neutral => 40,
22
+ :min_server_ver_under_comp => 40,
23
23
  :min_server_ver_contract_data_chain => 40,
24
24
  :min_server_ver_scale_orders2 => 40,
25
25
  :min_server_ver_algo_orders => 41,
@@ -99,47 +99,16 @@ KNOWN_SERVERS = {
99
99
  :min_server_ver_order_container => 145, ### > Version Field in Order dropped
100
100
  :min_server_ver_smart_depth => 146,
101
101
  :min_server_ver_remove_null_all_casting => 147,
102
- :min_server_ver_d_peg_orders => 148,
103
- :min_server_ver_mkt_depth_prim_exchange => 149,
104
- :min_server_ver_completed_orders => 150,
105
- :min_server_ver_price_mgmt_algo => 151,
106
- :min_server_ver_stock_type => 152,
107
- :min_server_ver_encode_msg_ascii7 => 153,
108
- :min_server_ver_send_all_family_codes => 154,
109
- :min_server_ver_no_default_open_close => 155,
110
- :min_server_ver_price_based_volitility => 156,
111
- :min_server_ver_replace_fa_end => 157,
112
- :min_server_ver_duration => 158,
113
- :min_server_ver_market_data_in_shares => 159,
114
- :min_server_ver_post_to_ats => 160,
115
- :min_server_ver_wshe_calendar => 161,
116
- :min_server_ver_auto_cancel_parent => 162,
117
- :min_server_ver_fractional_size_support => 163,
118
- :min_server_ver_size_rules => 164,
119
- :min_server_ver_historical_schedule => 165,
120
- :min_server_ver_advanced_order_reject => 166,
121
- :min_server_ver_user_info => 167,
122
- :min_server_ver_crypto_aggregated_trades => 168,
123
- :min_server_ver_manual_order_time => 169,
124
- :min_server_ver_pegbest_pegmid_offsets => 170,
125
- :min_server_ver_wsh_event_data_filters => 171,
126
- :min_server_ver_ipo_prices => 172,
127
- :min_server_ver_wsh_event_data_filters_date => 173,
128
- :min_server_ver_instrument_timezone => 174,
129
- :min_server_ver_hmds_market_data_in_shares => 175,
130
- :min_server_ver_bond_issuerid => 176,
131
- :min_server_ver_fa_profile_desupport => 177,
132
- :min_server_ver_pending_price_revision => 178,
133
- :min_server_ver_fund_data_fields => 179,
134
- :min_server_ver_manual_order_time_exercise_options => 180,
135
- :min_server_ver_open_order_ad_strategy => 181,
136
- :min_server_ver_last_trade_date => 182,
137
- :min_server_ver_customer_account => 183,
138
- :min_server_ver_professional_customer => 184
102
+ :min_server_ver_d_peg_orders => 148
103
+
104
+
105
+
106
+
139
107
  }
140
108
  # 100+ messaging */
141
109
  # 100 = enhanced handshake, msg length prefixes
142
110
 
143
111
  MIN_CLIENT_VER = 100
144
- MAX_CLIENT_VER = KNOWN_SERVERS[:min_server_ver_historical_schedule] # 165
112
+ MAX_CLIENT_VER = 137 #known_servers[:min_server_ver_d_peg_orders]
113
+
145
114
  # imessages/outgoing/request_tick_Data is prepared for change to ver. 140 , its commented for now
data/lib/ib/socket.rb CHANGED
@@ -1,31 +1,133 @@
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
1
53
  module IB
2
- # includes methods from IB:.Support
3
- # which adds a tws-method to
4
- # - Array
5
- # - Symbol
6
- # - String
7
- # - Numeric
8
- # - TrueClass, FalseClass and NilClass
9
- #
10
- class Socket < TCPSocket
11
- include IB::PrepareData
12
- using IB::Support
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
13
115
 
14
116
  def initialising_handshake
15
- v100_prefix = "API".tws.encode 'ascii'
117
+ v100_prefix = "API".tws.encode 'ascii'
16
118
  v100_version = self.prepare_message Messages::SERVER_VERSION
17
119
  write_data v100_prefix+v100_version
18
- ## start tws-log
19
- # [QO] INFO [JTS-SocketListener-49] - State: HEADER, IsAPI: UNKNOWN
20
- # [QO] INFO [JTS-SocketListener-49] - State: STOP, IsAPI: YES
21
- # [QO] INFO [JTS-SocketListener-49] - ArEServer: Adding 392382055 with id 2147483647
22
- # [QO] INFO [JTS-SocketListener-49] - eServersChanged: 1
23
- # [QO] INFO [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Starting new conversation with client on 127.0.0.1
24
- # [QO] INFO [JTS-EServerSocketNotifier-288] - Starting async queue thread
25
- # [QO] INFO [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Server version is 136
26
- # [QO] INFO [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] Client version is 136
27
- # [QO] INFO [JTS-EServerSocket-287] - [2147483647:136:136:1:0:0:0:SYS] is 3rdParty true
28
- ## end tws-log
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
29
131
  end
30
132
 
31
133
 
@@ -33,9 +135,9 @@ module IB
33
135
  string = self.gets(EOL)
34
136
 
35
137
  until string
36
- # Silently ignores nils
37
- string = self.gets(EOL)
38
- sleep 0.1
138
+ # Silently ignores nils
139
+ string = self.gets(EOL)
140
+ sleep 0.1
39
141
  end
40
142
 
41
143
  string.chomp
@@ -52,32 +154,32 @@ module IB
52
154
  def send_messages *data
53
155
  self.syswrite prepare_message(data)
54
156
  rescue Errno::ECONNRESET => e
55
- Connection.logger.fatal{ "Data not accepted by IB \n
56
- #{data.inspect} \n
57
- Backtrace:\n "}
157
+ Connection.logger.error{ "Data not accepted by IB \n
158
+ #{data.inspect} \n
159
+ Backtrace:\n "}
58
160
  Connection.logger.error e.backtrace
59
161
  end
60
162
 
61
- def receive_messages
163
+ def recieve_messages
62
164
  begin
63
- complete_message_buffer = []
64
- begin
65
- # this is the blocking version of recv
66
- buffer = self.recvfrom(8192)[0]
67
- # STDOUT.puts "BUFFER:: #{buffer.inspect}"
68
- complete_message_buffer << buffer
69
-
70
- end while buffer.size == 8192
71
- complete_message_buffer.join('')
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('')
72
174
  rescue Errno::ECONNRESET => e
73
- Connection.logger.fatal{ "Data Buffer is not filling \n
74
- The Buffer: #{buffer.inspect} \n
75
- Backtrace:\n
76
- #{e.backtrace.join("\n") } " }
77
- Kernel.exit
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
78
180
  end
79
181
  end
80
182
 
81
- end # class Socket
183
+ end # class IBSocket
82
184
 
83
185
  end # module IB
data/lib/ib/support.rb CHANGED
@@ -1,242 +1,160 @@
1
- # Class-extensions only applied when data are read from the tws
2
- # Array : read several formats
3
- # Array, String, Symbol, true, false, nil : apply tws.method
4
- #
5
- # Apply through: module aaxx
6
- # using IB::Support
7
- #
8
- module IB
9
- module Support
10
-
11
- refine Array do
12
-
13
- def zero?
14
- false
15
- end
16
- # Returns the integer.
17
- # retuns nil otherwise or if no element is left on the stack
18
- def read_int
19
- i= self.shift rescue nil
20
- i = i.to_i unless i.blank? # this includes conversion of string to zero(0)
21
- i.is_a?( Integer ) && i != 2147483647 ? i : nil
22
-
23
- end
24
-
25
- def read_float
26
- i= self.shift rescue nil
27
- i = i.to_f unless i.blank?
28
-
29
- end
30
- def read_decimal
31
- i = self.shift rescue nil
32
- return nil if i.blank?
33
- d = i.to_d
34
- return nil unless d.is_a?(Numeric) && d < IB::TWS_MAX
35
- if d == d.to_i
36
- d.to_i
37
- else
38
- d.to_f
39
- end
40
- end
41
-
42
- alias read_decimal_max read_decimal
43
-
44
- ## Values -1 and below indicate: Not computed (TickOptionComputation)
45
- def read_decimal_limit_1
46
- i= read_decimal
47
- i <= -1 ? nil : i
48
- end
49
-
50
- ## Values -2 and below indicate: Not computed (TickOptionComputation)
51
- def read_decimal_limit_2
52
- i= read_decimal
53
- i <= -2 ? nil : i
54
- end
55
-
56
-
57
- def read_string
58
- self.shift rescue ""
59
- end
60
- ## reads a string and checks if NULL == IB::TWS_MAX is present.
61
- ## in that case: returns nil. otherwise: returns the string
62
- def read_string_not_null
63
- r = read_string
64
- rd = r.to_d unless r.blank?
65
- rd.is_a?(Numeric) && rd >= IB::TWS_MAX ? nil : r
66
- end
67
-
68
- def read_symbol
69
- read_string.to_sym
70
- end
71
-
72
- # convert xml into a hash
73
- def read_xml
74
- Ox.load( read_string(), mode: :hash_no_attrs)
75
- end
76
-
77
-
78
- def read_int_date
79
- t= read_int
80
- s= Time.at(t.to_i)
81
- # s.year == 1970 --> data is most likely a date-string
82
- s.year == 1970 ? Date.parse(t.to_s) : s
83
- end
84
-
85
- def read_parse_date
86
- Time.parse read_string
87
- end
88
-
89
- def read_boolean
90
-
91
- v = self.shift rescue nil
92
- case v
93
- when "1"
94
- true
95
- when "0"
96
- false
97
- else nil
98
- end
99
- end
100
-
101
-
102
- def read_datetime
103
- the_string = read_string
104
- the_string.blank? ? nil : DateTime.parse(the_string)
105
- end
106
-
107
- def read_date
108
- the_string = read_string
109
- the_string.blank? ? nil : Date.parse(the_string)
110
- end
111
- # def read_array
112
- # count = read_int
113
- # end
114
-
115
- ## originally provided in socket.rb
116
- # # Returns loaded Array or [] if count was 0#
117
- #
118
- # Without providing a Block, the elements are treated as string
119
- def read_array hashmode:false, &block
120
- count = read_int
121
- case count
122
- when 0
123
- []
124
- when nil
125
- nil
126
- else
127
- count= count + count if hashmode
128
- if block_given?
129
- Array.new(count, &block)
130
- else
131
- Array.new( count ){ read_string }
132
- end
133
- end
134
- end
135
- #
136
- # Returns a hash
137
- # Expected Buffer-Format:
138
- # count (of Hash-elements)
139
- # count* key|Value
140
- # Key's are transformed to symbols, values are treated as string
141
- def read_hash
142
- tags = read_array( hashmode: true ) # { |_| [read_string, read_string] }
143
- result = if tags.nil? || tags.flatten.empty?
144
- tags # {}
145
- else
146
- interim = if tags.size.modulo(2).zero?
147
- Hash[*tags.flatten]
148
- else
149
- Hash[*tags[0..-2].flatten] # omit the last element
150
- end
151
- # symbolize Hash
152
- interim.map { |k, v| [k.to_sym, v] unless k.nil? }.compact.to_h
153
- end
154
- end
155
- #
156
-
157
- def read_contract # read a standard contract and return als hash
158
- { con_id: read_int,
159
- symbol: read_string,
160
- sec_type: read_string,
161
- expiry: read_string,
162
- strike: read_decimal,
163
- right: read_string,
164
- multiplier: read_decimal,
165
- exchange: read_string,
166
- currency: read_string,
167
- local_symbol: read_string,
168
- trading_class: read_string }
169
- end
170
-
171
-
172
- def read_bar # read a Historical data bar
173
- # ** historicalDataUpdate: time open close high low ** covered here
174
- # historicalData time open high low close <- covered in messages/incomming
175
- { :time => read_int_date, # conversion of epoche-time-integer to Dateime
176
- # requires format_date in request to be "2"
177
- # (outgoing/bar_requests # RequestHistoricalData#Encoding)
178
- :open => read_decimal,
179
- :close => read_decimal,
180
- :high => read_decimal,
181
- :low => read_decimal,
182
- :wap => read_decimal,
183
- :volume => read_int,
184
- # :has_gaps => read_string, # only in ServerVersion < 124
185
- :trades => read_int }
186
-
187
- end
188
-
189
-
190
- alias read_bool read_boolean
191
-
192
- def tws
193
- if blank?
194
- nil.tws
195
- else
196
- self.flatten.map( &:tws ).join # [ "", [] , nil].flatten -> ["", nil]
197
- # elements with empty array's are cut
198
- # this is the desired behavior!
199
- end
200
- end
201
- end # refining array
202
- refine Symbol do
203
- def tws
204
- self.to_s.tws
205
- end
206
- end
207
- refine String do
208
- def tws
209
- if empty?
210
- IB::EOL
211
- else
212
- self[-1] == IB::EOL ? self : self+IB::EOL
213
- end
214
- end
215
- end
216
-
217
- refine Numeric do
218
- def tws
219
- self.to_s.tws
220
- end
221
- end
222
-
223
- refine TrueClass do
224
- def tws
225
- 1.tws
226
- end
227
- end
228
-
229
- refine FalseClass do
230
- def tws
231
- 0.tws
232
- end
233
- end
234
-
235
- refine NilClass do
236
- def tws
237
- IB::EOL
238
- end
239
- end
240
- end
241
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
242
160
  end
data/lib/ib/version.rb CHANGED
@@ -2,5 +2,5 @@ require 'pathname'
2
2
 
3
3
  module IB
4
4
  VERSION_FILE = Pathname.new(__FILE__).dirname + '../../VERSION' # :nodoc:
5
- Version = VERSION = VERSION_FILE.exist? ? VERSION_FILE.read.strip : nil
5
+ VERSION = VERSION_FILE.exist? ? VERSION_FILE.read.strip : nil
6
6
  end