ib-extensions 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Fetching market-prices for 500 Contracts
4
- #
5
- # Ensure to run `ruby input.rb` prior to the first run.
6
- # That initializes the watchlist `W500`.
7
- #
8
- # First a (fast) asynchron request is fired.
9
- # Second a (much slower) synchron attempt is drawn
10
-
11
- require 'bundler/setup'
12
- require 'ib/symbols'
13
- require 'ib/market-price'
14
- require 'yaml'
15
-
16
- # First, connect to IB TWS and subscribe for events.
17
- ib = IB::Connection.new :client_id => 1112 do | gw | #, :port => 7497 # TWS
18
-
19
- # Subscribe to TWS alerts/errors
20
- gw.subscribe(:Alert) { |msg| puts msg.to_human }
21
- # Set log level
22
- gw.logger.level = Logger::FATAL # DEBUG -- INFO -- WARN -- ERROR -- FATAL
23
-
24
- end
25
- # Put your code here
26
- # ...
27
- IB::Symbols.allocate_collection :w500
28
-
29
- puts
30
- puts '*'*40
31
- puts "(1) asynchon fetching of snapshot data "
32
- start = Time.now;
33
- IB::Symbols::W500.bunch(45,1){|x| x.map{|y| y.market_price(thread: true)}};
34
-
35
- print "Finished Time:"
36
- puts second_duration = Time.now - start
37
- puts "Prices: "; sleep(7)
38
- puts IB::Symbols::W500.map{|x| x.misc}.join( ' - ' )
39
-
40
- IB::Connection.current.disconnect
41
- IB::Connection.current.connect
42
- puts '*'*40
43
- puts "(2) sequencial fetching of snapshot data "
44
- start = Time.now;
45
- prices = IB::Symbols::W500.map &:market_price
46
-
47
- print "Finished Time:"
48
- puts first_duration = Time.now - start
49
-
50
- puts "Prices: #{prices.map( &:to_s ).join(" - ")}"
51
-
52
-
53
- puts
54
- puts "first_duration: #{first_duration} s "
55
- puts "second_duration: #{second_duration} s "
56
-
57
- puts "finished"
@@ -1,67 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Gets the OptionChain of GE
4
-
5
- require 'bundler/setup'
6
- require 'ib-api'
7
- require 'ib/verify'
8
-
9
- # First, connect to IB TWS and subscribe for events.
10
- ib = IB::Connection.new :client_id => 1112 do | gw | #, :port => 7497 # TWS
11
-
12
- # Subscribe to TWS alerts/errors
13
- gw.subscribe(:Alert) { |msg| puts msg.to_human }
14
- # Set log level
15
- gw.logger.level = Logger::ERROR # DEBUG # -- INFO -- WARN -- ERROR -- FATAL
16
-
17
- end
18
-
19
- TheYear = 2021
20
- TheStrike = 6
21
- TheRight = :put
22
-
23
- # get expiries (last-trading-days)
24
- the_contract = IB::Option.new symbol: 'GE',
25
- currency: 'USD',
26
- exchange: 'SMART',
27
- expiry: TheYear,
28
- strike: TheStrike,
29
- right: TheRight
30
-
31
- provided_expiries = Array.new
32
-
33
- puts "Using #{the_contract.to_human}"
34
-
35
- # get all available expiries
36
- the_contract.verify do | detected_contract |
37
- # last trading day: format yyyy-mm-dd
38
- # expiry: format yyyymmdd
39
- provided_expiries << detected_contract.last_trading_day
40
- end
41
- puts "detected Expiries #{provided_expiries.sort{|a,b| a.to_f <=> b.to_f }.join(" -- ")}"
42
- puts
43
-
44
-
45
-
46
- # get provided strikes
47
- option_matrix = provided_expiries.map do | last_trading_day |
48
- provided_strikes = Array.new
49
-
50
- # because we used last_trading day as input to the expiry's array, it has to be assigned that way, too
51
- the_contract = IB::Option.new symbol: 'GE', currency: 'USD', exchange: 'SMART', last_trading_day: last_trading_day, right: TheRight
52
-
53
- the_contract.verify do | detected_contract |
54
- provided_strikes << detected_contract.strike
55
- end
56
- puts "Expiry: #{the_contract.expiry}"
57
- puts "Strikes: "+ provided_strikes.join(" -- ")
58
- provided_strikes # return array
59
-
60
- end
61
-
62
- puts "NOTICE: Strikes are not sorted when :RequestContractData is used"
63
- # print summary
64
- #option_matrix.zip( provided_expiries) do | strikes, expiry|
65
- # puts "expiry #{strikes}"
66
- # puts "provided strikes: #{strikes.join(' ')}"
67
- #end
@@ -1,162 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- ## This script places WFC buy order for 100 lots
4
- #
5
- ## RUN ONLY ON A DEMO ACCOUNT
6
-
7
- module OrderPlacement
8
-
9
- # Utility Method
10
- #
11
- # gets the most recent price of the asset
12
- # User has to specify order in the block provided
13
- # returns the order_id
14
- #
15
- def place_the_order( contract: IB::Symbols::Stocks.wfc, modus: :place ) # modus: place or modify
16
- # First, get the current connection
17
- ib = IB::Connection.current
18
- raise 'Unable to place order, no connection' unless ib && ib.connected?
19
- # Ask the TWS for the last available price for the asset,
20
- # Optional: switch to delayed data, if no market-data subscription is booked;
21
- # Unsubscribe from the Marketdata-Feed after successfully received the data
22
- ib.send_message :RequestMarketDataType, :market_data_type => :delayed
23
- the_id = ib.send_message :RequestMarketData, contract: contract
24
- ib.wait_for :TickPrice
25
- ib.send_message :CancelMarketData, id: the_id
26
- # We received High, Low, (perhaps open and close, too), choose the maximum value for reference
27
- # and clear the received-array for proper bookkeeping
28
- last_price = ib.received[:TickPrice].price.map(&:to_f).max
29
- ib.clear_received :TickPrice
30
- # let the calling method decide how to use the price
31
- # the calling method should return a valid order
32
- order = yield(last_price.presence || 47)
33
- # to finish, we place the order using the given contract and return the order_id
34
- the_order_id = if modus == :place
35
- ib.place_order order, contract
36
- else
37
- ib.modify_order order, contract
38
- end
39
- ib.wait_for :OpenOrder, 3
40
- the_order_id # return value
41
- end
42
- end
43
-
44
-
45
-
46
-
47
-
48
-
49
- require 'bundler/setup'
50
- require 'ib-api'
51
- require 'ib/symbols'
52
- require 'ib/order-prototypes'
53
-
54
- include OrderPlacement
55
-
56
- # Only for Advisor accounts: you need to provide account_code such as DU666777
57
- account_code = ARGV[0] || ''
58
- puts "\n" * 3
59
- puts "*" * 50
60
- puts " We are going to place a BUY-order on Wells Fargo on the account #{account_code} "
61
- puts ""
62
- puts " The Order is placed by the Order-Prototye »Limit.order»"
63
- puts " "
64
- puts " The Order is left open after finishing this script. You have to cancel it manualy"
65
- puts "*" * 50
66
- puts "\n" * 3
67
- #
68
- # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
69
- ib = IB::Connection.new client_id: 1112 do | gw | #, :port => 7496 # TWS
70
-
71
- # Subscribe to TWS alerts/errors and order-related messages prior to the connection of the client
72
- gw.subscribe(:Alert, :ManagedAccounts, :OpenOrder, :OrderStatus, :ContractDataEnd ) { |msg| puts msg.to_human }
73
- gw.subscribe(:ContractData ) do |msg|
74
- puts msg.contract.to_human + "\n"
75
- end
76
- gw.logger.level = Logger::FATAL # DEBUG -- INFO -- WARN -- ERROR -- FATAL
77
-
78
- end
79
-
80
- buy_order = nil # placeholder for buy_order defined in the block
81
- contract = IB::Symbols::Stocks.wfc
82
- puts '*'*10 + ' Introduction '+ '*'*10
83
- puts IB::Limit.summary
84
- puts "\nSupported Parameter \n -------------------------- "
85
- puts IB::Limit.parameters
86
-
87
- buy_order = IB::Limit.order size: 100,
88
- price: 0, # dummy, specified later
89
- action: :buy,
90
- account: account_code
91
-
92
- the_initial_order_id = place_the_order( contract: contract ) do | asset_price |
93
- buy_order.limit_price = ( asset_price -( asset_price * 0.1)).round
94
- puts buy_order.to_human
95
- buy_order # return_value
96
- end
97
-
98
-
99
- puts "going to modify the order "
100
-
101
- puts "\n******** Press <Enter> to proceed... *********\n\n"
102
- STDIN.gets
103
-
104
- puts "changing price by 1$"
105
-
106
- the_modified_order_id = place_the_order( contract: contract, modus: :modify ) do | asset_price |
107
- buy_order.limit_price = ( asset_price - 1 - ( asset_price * 0.1)).round
108
- puts buy_order.to_human
109
- buy_order # return_value
110
- end
111
-
112
-
113
- ib.send_message :RequestAllOpenOrders
114
-
115
-
116
- puts "\n******** Press <Enter> to cancel... *********\n\n"
117
- STDIN.gets
118
-
119
-
120
- ## RUN ONLY ON A DEMO ACCOUNT
121
- #
122
- #
123
- # expected output
124
- #
125
- #12:13:05.096 Got message 15 (IB::Messages::Incoming::ManagedAccounts)
126
- #12:13:05.097 No subscribers for message IB::Messages::Incoming::ManagedAccounts!
127
- #12:13:05.137 Got message 9 (IB::Messages::Incoming::NextValidId)
128
- #12:13:05.137 Got next valid order id: 1.
129
- #------sendto ---------(debugging output in outgoing/abstract_message)
130
- #["'9", "8", "56", "", "WFC", "STK", "", "0.0", "", "", "NYSE", "", "USD", "", "", "0", "", "", "\""]
131
- #------sendto ---------
132
- # A Limit order is an order to buy or sell at a specified price or better.
133
- # The Limit order ensures that if the order fills, it will not fill at a price less favorable than
134
- # your limit price, but it does not guarantee a fill.
135
- # It appears in the orderbook.
136
- #Supported Parameter
137
- # --------------------------
138
- #Required : action --> {"B"=>:buy, "S"=>:sell, "T"=>:short, "X"=>:short_exempt}
139
- # : total_quantity --> also aliased as :size
140
- # : limit_price --> decimal
141
- # ---------------
142
- #Optional : account --> Account(number) to trade on
143
- # ---------------
144
- #<Order: LMT GTC buy 100 1.13 New #/ from /DU167348>
145
- #------sendto ---------(debugging output in outgoing/abstract_message)
146
- #["\\xB03", "45", "1", "", "WFC", "STK", "", "0.0", "", "", "NYSE", "", "USD", "", "", "", "", "BUY", "100", "LMT", "1.13", "", "GTC", "", "DU167348", "O", "0", "", "1", "0", "0", "0", "0", "0", "0", "0", "", "0", "", "", "", "", "", "", "", "0", "", "-1", "0", "", "", "0", "", "", "1", "1", "", "0", "", "", "", "", "", "0", "", "", "", "", "0", "", "", "", "", "", "", "", "", "", "", "0", "", "", "0", "0", "", "", "0", "", "0", "0", "0", "0", "", "", "", "", "", "", "", "", "", "", "", "\""]
147
- #------sendto ---------
148
- #12:13:05.290 Got message 10 (IB::Messages::Incoming::ContractData)
149
- #<Stock: WFC USD>
150
- #12:13:05.291 Got message 52 (IB::Messages::Incoming::ContractDataEnd)
151
- #<ContractDataEnd: request_id 56 >
152
- #
153
- #******** Press <Enter> to cancel... *********
154
- #
155
- #12:13:05.303 Got message 3 (IB::Messages::Incoming::OrderStatus)
156
- #<OrderStatus: <OrderState: ApiPending #1/0 from 1112 filled 0.0/100.0 at 0.0/0.0>>
157
- #12:13:05.304 Got message 53 (IB::Messages::Incoming::OpenOrderEnd)
158
- #12:13:05.304 No subscribers for message IB::Messages::Incoming::OpenOrderEnd!
159
- #12:13:05.712 Got message 5 (IB::Messages::Incoming::OpenOrder)
160
- #<OpenOrder: <Stock: WFC USD> <Order: LMT GTC buy 100.0 1.13 Submitted #1/1562725191 from 1112/DU167348 fee 0.0>>
161
- #12:13:05.714 Got message 3 (IB::Messages::Incoming::OrderStatus)
162
- #<OrderStatus: <OrderState: Submitted #1/1562725191 from 1112 filled 0.0/100.0 at 0.0/0.0 why_held >>
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script places WFC bracketed buy order.
4
- # Two child orders are attached:
5
- # STOP order
6
- # LIMIT order (profit target)
7
-
8
- require 'rubygems'
9
- require 'bundler/setup'
10
- require 'ib-api'
11
- require 'ib/symbols'
12
- require 'ib/order-prototypes'
13
- # Only for Advisor accounts: you need to provide account_code such as U666777
14
- account_code = ARGV[0] || ''
15
- # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
16
- ib = IB::Connection.new :client_id => 1112 do | gw | #, :port => 7497 # TWS
17
-
18
- # Subscribe to TWS alerts/errors and order-related messages
19
- gw.subscribe(:Alert, :OpenOrder, :OrderStatus, :ManagedAccounts) { |msg| puts msg.to_human }
20
- end
21
-
22
- symbol = IB::Symbols::Stocks[:wfc]
23
-
24
- order_price = 24
25
- stop_price = order_price - 0.25
26
- profit_price = order_price + 0.25
27
-
28
- #-- Parent Order --
29
- buy_order = IB::Limit.order :total_quantity => 100,
30
- :price => order_price,
31
- :action => :buy,
32
- :algo_strategy => '',
33
- :transmit => false,
34
- account: account_code
35
- ib.wait_for :NextValidId
36
-
37
- #-- Child STOP --
38
- stop_order = IB::SimpleStop.order :total_quantity => 100,
39
- :price => stop_price,
40
- :action => :sell,
41
- :parent_id => buy_order.local_id,
42
- account: account_code
43
- #-- Profit LMT
44
- profit_order = IB::Limit.order :total_quantity => 100,
45
- :price => profit_price,
46
- :action => :sell,
47
- :parent_id => buy_order.local_id,
48
- account: account_code
49
-
50
- # place parent order
51
- ib.place_order buy_order, symbol
52
- stop_order.parent_id = buy_order.local_id
53
- profit_order.parent_id = buy_order.local_id
54
-
55
- # place child orders
56
- ib.place_order stop_order, symbol
57
- ib.place_order profit_order, symbol
58
-
59
- ib.send_message :RequestAllOpenOrders
60
-
61
- puts "\n******** Press <Enter> to cancel... *********\n\n"
62
- STDIN.gets
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This script places GOOG option butterfly combo order
4
-
5
- require 'rubygems'
6
- require 'bundler/setup'
7
- require 'ib-api'
8
- require 'ib/verify'
9
- require 'ib/market-price'
10
- require 'ib/order-prototypes'
11
-
12
- # Utility method that helps us build multi-legged (BAG) Orders
13
- def butterfly symbol, expiry, right, *strikes
14
-
15
- legs = strikes.zip([1, -2, 1]).map do |strike, weight|
16
- # Create contract
17
- the_leg = nil
18
- IB::Option.new( :symbol => symbol,
19
- :expiry => expiry,
20
- :right => right,
21
- :strike => strike).verify do | c |
22
-
23
- # Create Comboleg from con_id and weight
24
- the_leg = IB::ComboLeg.new :con_id => c.con_id, :weight => weight
25
- end
26
- the_leg # return_value
27
- end
28
- if legs.size < 3
29
- puts "Could'nd initialize all legs"
30
- nil # return nil
31
- else
32
- # Create and return new Combo contract
33
- IB::Bag.new :symbol => symbol,
34
- :currency => "USD", # Only US options in combo Contracts
35
- :exchange => "SMART",
36
- :combo_legs => legs
37
- end
38
- end
39
-
40
- # Only for Advisor accounts: you need to provide account_code such as U666777
41
- account_code = ARGV[0] || ''
42
-
43
- #
44
- # First, connect to IB TWS. Arbitrary :client_id is used to identify your script
45
- ib = IB::Connection.new :client_id => 1112 do | gw | #, :port => 7497 # TWS
46
-
47
- # Subscribe to TWS alerts/errors and order-related messages
48
- gw.subscribe(:Alert, :OpenOrder, :OrderStatus, :ManagedAccounts) { |msg| puts msg.to_human }
49
- end
50
- ib.wait_for :NextValidId
51
-
52
- # Create multi-legged option Combo using utility method above
53
- combo = butterfly 'WMT', '20201218', 'CALL', 145, 150 , 155
54
- unless combo.nil?
55
- puts "MARKETPRICE: #{combo.market_price}"
56
- # Create Order stub
57
- order = IB::Limit.order total_quantity: 10, # 10 butterflies
58
- limit_price: 0.06, # at 0.06 x 100 USD per contract
59
- action: :buy,
60
- account: account_code
61
-
62
-
63
- ib.place_order order, combo
64
-
65
- ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2]
66
-
67
- puts "\n******** Press <Enter> to cancel... *********\n\n"
68
- STDIN.gets
69
- end
70
-
71
- ### Expected output
72
-
73
- #./place_butterfly_order DU167349
74
- #Connected to server, version: 137,
75
- # connection time: 2020-09-03 05:13:24 +0000 local, 2020-09-03T05:13:24+00:00 remote.
76
- #< ManagedAccounts: DF167347 - DU167348 - DU167349>
77
- #Got next valid order id: 65.
78
- #TWS Warning 2104: Market data farm connection is OK:eufarm
79
- #TWS Warning 2104: Market data farm connection is OK:usopt
80
- #TWS Warning 2104: Market data farm connection is OK:usfarm
81
- #TWS Warning 2107: HMDS data farm connection is inactive but should be available upon demand.euhmds
82
- #TWS Error 354: Requested market data is not subscribed.
83
- #MARKETPRICE: []
84
- #<OpenOrder: <Bag: WMT SMART USD legs: 418440165|1,418440170|-2,418440175|1 > <Order: LMT GTC buy 10.0 @ 0.06 PreSubmitted #65/1750019075 from 1112/DU167349>>
85
- #<OrderState: PreSubmitted #65/1750019075 from 1112 filled 0.0/10.0 at 0.0/0.0 why_held locate>
86
- #
87
- #******** Press <Enter> to cancel... *********
88
- #
89
- #<OpenOrder: <Bag: WMT SMART USD legs: 418440165|1,418440170|-2,418440175|1 > <Order: LMT GTC buy 10.0 @ 0.06 Submitted #65/1750019075 from 1112/DU167349>>
90
- #<OrderState: Submitted #65/1750019075 from 1112 filled 0.0/10.0 at 0.0/0.0 why_held >
91
- #
92
- #./cancel_orders
93
- #< ManagedAccounts: DF167347 - DU167348 - DU167349>
94
- #TWS Warning 2104: Market data farm connection is OK:eufarm
95
- #TWS Warning 2104: Market data farm connection is OK:usopt
96
- #TWS Warning 2104: Market data farm connection is OK:usfarm
97
- #TWS Warning 2107: HMDS data farm connection is inactive but should be available upon demand.euhmds
98
- #-------------------------------------------------------
99
- #Remaining Orders
100
- #-------------------------------------------------------
101
- #<OpenOrder: <Bag: WMT SMART USD legs: 418440165|1,418440170|-2,418440175|1 > <Order: LMT GTC buy 10.0 @ 0.06 PendingCancel #65/1750019075 from 1112/DU167349>>
102
- #<OrderState: PendingCancel #65/1750019075 from 1112 filled 0.0/10.0 at 0.0/0.0 why_held >
103
- #<OpenOrderEnd: >
104
- ##