Skip to content

Don't try to compare if decimal value is nil. #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

metrix78
Copy link
Collaborator

@metrix78 metrix78 commented Jul 19, 2022

Gem fails reading opton greeks if a decimal value is empty. Modified code to check for nils before running a comparison.

Error:

Traceback (most recent call last): > 12: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:381:in block in start_reader' 11: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:297:in process_messages' 10: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:401:in process_message' 9: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/socket.rb:101:in decode_message' 8: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:413:in block in process_message' 7: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:413:in new' 6: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:41:in initialize' 5: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:63:in load' 4: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:52:in simple_load' 3: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:73:in load_map' 2: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:73:in each' 1: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:96:in block in load_map' /home/metrix/.gems/gems/ib-api-972.5/lib/ib/support.rb:38:in read_decimal_limit_2': undefined method <=' for nil:NilClass (NoMethodError) 13: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:381:in block in start_reader' 12: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:297:in process_messages' 11: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:401:in process_message' 10: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/socket.rb:101:in decode_message' 9: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:413:in block in process_message' 8: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/connection.rb:413:in new' 7: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:41:in initialize' 6: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:63:in load' 5: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:52:in simple_load' 4: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:73:in load_map' 3: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:73:in each' 2: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:95:in block in load_map' 1: from /home/metrix/.gems/gems/ib-api-972.5/lib/ib/messages/incoming/abstract_message.rb:98:in rescue in block in load_map' /home/metrix/.gems/gems/ib-api-972.5/lib/ib/errors.rb:43:in error': Reading IB::Messages::Incoming::TickOption: NoMethodError: undefined method `<=' for nil:NilClass --> Instruction: vega (IB::TransmissionError)

@topofocus
Copy link
Member

Hi,
thanks for exploring this.

Question? Why returned read_float nil?
Does this indicate a read-error? Then it should raise a IB::TransmissionError!
If the tws may return nil on this field, I prefer to extend read_float to accept nil-values, ie. create a method read_float_or_nil.

@metrix78
Copy link
Collaborator Author

metrix78 commented Jul 20, 2022

Does this indicate a read-error? Then it should raise a IB::TransmissionError!

These are valid option contracts from TWS that are causing the library to crash.

I prefer to extend read_float to accept nil-values, ie. create a method read_float_or_nil.

I can do that, but it looks like empty values are returned for every location that uses decimal_limit. See below:

Uses of decimal_limit_1:

rg decimal_limit_1
support.rb
41: def read_decimal_limit_1

messages/incoming/ticks.rb
121: %i[implied_volatility decimal_limit_1], # -1 and below
123: %i[option_price decimal_limit_1], # -1 -"-
124: %i[pv_dividend decimal_limit_1], # -1 -"-
128: %i[under_price decimal_limit_1]) do

Uses of decimal_limit_2:

rg decimal_limit_2
support.rb
50: def read_decimal_limit_2

messages/incoming/ticks.rb
122: %i[delta decimal_limit_2], # -2 and below
125: %i[gamma decimal_limit_2], # -2 -"-
126: %i[vega decimal_limit_2], # -2 -"-
127: %i[theta decimal_limit_2], # -2 -"-

Example message parsed into a hash:
{:class_name=>"TickOption", :class_name_full=>"IB::Messages::Incoming::TickOption", :type=>:delayed_bid_option, :ticker_id=>18, :tick_type=>80, :the_data=>{:tick_type=>80, :implied_volatility=>nil, :delta=>nil, :option_price=>nil, :pv_dividend=>0.0, :gamma=>nil, :vega=>nil, :theta=>nil, :under_price=>7.234678745269775}, :symbol=>"INTT", :expiry=>"20221216", :strike=>10.0, :right=>:call, :greek=>nil, :time=>1658298775}

Every call to decimal_limit_1 or decimal_limit_2 can be empty

@metrix78
Copy link
Collaborator Author

After re-reading your comment, I think I see what you're saying.

You would like read_float to return a valid integer other than blank if the data is valid?

In this case I would l think an empty string, or nil would be the best option. It wouldn't make sense to return a 0 for a greek.
My point of view is that nil is the correct value to respond with as we don't know what the value is.

@topofocus
Copy link
Member

topofocus commented Jul 20, 2022

if nil (or blank) is a valid data received from the tws, read_float is the wrong method to capture the input.
Then I see two options: use a different read_xyz method or use read_float and handle IB::TransmissionError in the calling method.
read_xyz are low-level methods to capture the datastream. We are dealing with uncertain WAN-data. On this level the flexibility of ruby is an disadvantage.

Can you write a small test to work on this feature? (or explain the error on detail, then I write it )
Could be a hidden runtime-error of ib-api.

@metrix78
Copy link
Collaborator Author

What interface do you need data for a test? Directly from the TCPSocket? or data formatted between a specific method call.
I'll see if I can find a way to capture a message from the TCP socket today or tomorrow.

I was fixing this bug for a bit of understanding on how the development process works on this project. I've found a bigger issue that will cause the application to crash when two messages are ready to read from the TCPSocket recvfrom method. I have a proof of concept to fix it, but it really needs some more work.

@topofocus
Copy link
Member

If you want, lets focus on the issues together.
Either by mail ([email protected]) or via signal +49 176 47279326.
I'm free this evening (european time).

@topofocus
Copy link
Member

There are a few in-situ message tests in spec/ib/messages. They may act as prototype.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants