Skip to content

Commit

Permalink
Merge pull request #13 from ib-ruby/technical_analyisis
Browse files Browse the repository at this point in the history
Support for IB-Message 90 (HistoricalDataUpdate)
  • Loading branch information
topofocus authored May 4, 2021
2 parents 3a5338f + 96b53fe commit 7f03dcb
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 23 deletions.
15 changes: 13 additions & 2 deletions lib/ib/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
require 'ib/logger'
require 'ib/messages'

module TechnicalAnalysis
module Signals
end
end

module IB
# Encapsulates API connection to TWS or Gateway
class Connection
Expand Down Expand Up @@ -100,7 +105,7 @@ def initialize host: '127.0.0.1',
def update_next_order_id
i,finish = 0, false
sub = self.subscribe(:NextValidID) { finish = true }
connected? ? self.send_message( :RequestIds ) : open()
connected? ? self.send_message( :RequestIds ) : open()
Timeout::timeout(1, IB::TransmissionError,"Could not get NextValidId" ) do
loop { sleep 0.1; break if finish }
end
Expand Down Expand Up @@ -186,7 +191,13 @@ def subscribe *args, &block
when what.is_a?(Class) && what < Messages::Incoming::AbstractMessage
[what]
when what.is_a?(Symbol)
[Messages::Incoming.const_get(what)]
if Messages::Incoming.const_defined?(what)
[Messages::Incoming.const_get(what)]
elsif TechnicalAnalysis::Signals.const_defined?(what)
[TechnicalAnalysis::Signals.const_get?(what)]
else
error "#{what} is no IB::Messages or TechnicalAnalyis::Signals class"
end
when what.is_a?(Regexp)
Messages::Incoming::Classes.values.find_all { |klass| klass.to_s =~ what }
else
Expand Down
30 changes: 25 additions & 5 deletions lib/ib/messages/incoming/historical_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ def load
IB::Bar.new :time => buffer.read_int_date, # conversion of epoche-time-integer to Dateime
# requires format_date in request to be "2"
# (outgoing/bar_requests # RequestHistoricalData#Encoding)
:open => buffer.read_decimal,
:high => buffer.read_decimal,
:low => buffer.read_decimal,
:close => buffer.read_decimal,
:open => buffer.read_float,
:high => buffer.read_float,
:low => buffer.read_float,
:close => buffer.read_float,
:volume => buffer.read_int,
:wap => buffer.read_decimal,
:wap => buffer.read_float,
# :has_gaps => buffer.read_string, # only in ServerVersion < 124
:trades => buffer.read_int
end
Expand Down Expand Up @@ -79,6 +79,26 @@ def load
end
end

HistoricalDataUpdate = def_message [90, 0] ,
[:request_id, :int] ,
[:count, :int],
[:bar, :bar] # defined in support.rb

class HistoricalDataUpdate
attr_accessor :results
using IBSupport # extended Array-Class from abstract_message

def bar
@bar = IB::Bar.new @data[:bar]
end

def to_human
"<HistDataUpdate #{request_id} #{bar}>"
end
end



end # module Incoming
end # module Messages
end # module IB
45 changes: 30 additions & 15 deletions lib/ib/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def read_xml

def read_int_date
t= read_int
s= Time.at(t)
s= Time.at(t.to_i)
# s.year == 1970 --> data is most likely a date-string
s.year == 1970 ? Date.parse(t.to_s) : s
end
Expand Down Expand Up @@ -139,20 +139,35 @@ def read_hash
end
#

def read_contract # read a standard contract and return als hash
{ con_id: read_int,
symbol: read_string,
sec_type: read_string,
expiry: read_string,
strike: read_decimal,
right: read_string,
multiplier: read_int,
exchange: read_string,
currency: read_string,
local_symbol: read_string,
trading_class: read_string } # new Version 8

end
def read_contract # read a standard contract and return als hash
{ con_id: read_int,
symbol: read_string,
sec_type: read_string,
expiry: read_string,
strike: read_decimal,
right: read_string,
multiplier: read_int,
exchange: read_string,
currency: read_string,
local_symbol: read_string,
trading_class: read_string } # new Version 8
end


def read_bar # read a standard bar (Historical data bars)
{ :time => read_int_date, # conversion of epoche-time-integer to Dateime
# requires format_date in request to be "2"
# (outgoing/bar_requests # RequestHistoricalData#Encoding)
:open => read_float,
:high => read_float,
:low => read_float,
:close => read_float,
:wap => read_float,
:volume => read_int,
# :has_gaps => read_string, # only in ServerVersion < 124
:trades => read_int }

end


alias read_bool read_boolean
Expand Down
2 changes: 1 addition & 1 deletion lib/models/ib/bar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Bar < IB::Model
validates_numericality_of :open, :high, :low, :close, :volume

def to_human
"<Bar: #{time} wap #{wap} OHLC #{open} #{high} #{low} #{close} " +
"<Bar: #{time.strftime("(%d.%m.%y)%X")} wap #{wap.round(3)} OHLC #{open} #{high} #{low} #{close} " +
(trades ? "trades #{trades}" : "") + " vol #{volume}>"
end

Expand Down

0 comments on commit 7f03dcb

Please sign in to comment.