Module: InteractiveBrokers2TastyWorks::Utils

Defined in:
lib/interactive_brokers_2_tasty_works.rb

Class Method Summary collapse

Class Method Details

.build_action(trade) ⇒ Object



141
142
143
# File 'lib/interactive_brokers_2_tasty_works.rb', line 141

def build_action(trade)
  "#{trade[:buySell]}_TO_#{trade[:openCloseIndicator] == 'O' ? 'OPEN' : 'CLOSE'}"
end

.build_commission(trade) ⇒ Object



196
197
198
199
# File 'lib/interactive_brokers_2_tasty_works.rb', line 196

def build_commission(trade)
  c = trade[:ibCommission]
  c.to_f == -0.0 ? '0' : c
end

.build_date(str) ⇒ Object



133
134
135
136
137
138
139
# File 'lib/interactive_brokers_2_tasty_works.rb', line 133

def build_date(str)
  return nil if str.to_s.strip == ''
  day = str[6..7]
  month = str[4..5]
  year = str[2..3]
  "#{month}/#{day}/#{year}"
end

.build_date_time_str(trade) ⇒ Object



122
123
124
125
126
127
128
129
130
131
# File 'lib/interactive_brokers_2_tasty_works.rb', line 122

def build_date_time_str(trade)
  d, t = trade[:tradeDate], trade[:tradeTime]
  year = d[0..3]
  month = d[4..5]
  day = d[6..7]
  hour = t[0..1]
  min = t[2..3]
  sec = t[4..5]
  Time.zone.local(year,month,day,hour,min,sec).strftime('%FT%T%z')
end

.build_description(trade) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/interactive_brokers_2_tasty_works.rb', line 154

def build_description(trade)
  case trade[:buySell]
  when 'SELL'; str = 'Sold'
  when 'BUY'; str = 'Bought'
  end

  str += " #{trade[:quantity].to_i.abs} "

  str += case (ac = trade[:assetCategory])
  when 'OPT'
    exp = build_date(trade[:expiry])
    "#{trade[:symbol]} #{exp} #{put_or_call(trade)} #{trade[:strike]} @ #{build_trade_price(trade)}"
  when 'STK'
    "#{trade[:symbol]} @ #{build_trade_price(trade)}"
  else
    raise ArgumentError.new("Unknown asset category: #{ac}")
  end

  str
end

.build_instrument_type(trade) ⇒ Object



145
146
147
148
149
150
151
152
# File 'lib/interactive_brokers_2_tasty_works.rb', line 145

def build_instrument_type(trade)
  case (ac = trade[:assetCategory])
  when 'OPT'; 'Equity Option'
  when 'STK'; 'Equity'
  else
    raise ArgumentError.new("Unknown asset category: #{ac}")
  end
end

.build_trade_price(trade) ⇒ Object



175
176
177
178
179
180
181
182
# File 'lib/interactive_brokers_2_tasty_works.rb', line 175

def build_trade_price(trade)
  if string_is_zero?(trade[:tradePrice]) && !string_is_zero?(build_value(trade))
    value = build_value(trade).to_f
    strip_zero_decimal (value / trade[:quantity].to_i / trade[:multiplier].to_i).abs
  else
    trade[:tradePrice]
  end
end

.build_value(trade) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
# File 'lib/interactive_brokers_2_tasty_works.rb', line 184

def build_value(trade)
  if !proceeds_is_zero?(trade)
    v = trade[:proceeds]
  elsif is_option_assignment_exercise_or_expiration(trade)
    v = strip_zero_decimal(trade[:mtmPnl].to_f * -1)
  else
    raise ArgumentError.new("Cannot parse trade: #{trade}")
  end

  (v.to_f == -0.0 ? 0 : v).to_s
end

.indifferent_fetch(h, key) ⇒ Object



223
224
225
226
227
# File 'lib/interactive_brokers_2_tasty_works.rb', line 223

def indifferent_fetch(h, key)
  h.fetch(key)
rescue KeyError
  h[key.is_a?(String) ? key.to_sym : key.to_s]
end

.is_option_assignment_exercise_or_expiration(trade) ⇒ Object



219
220
221
# File 'lib/interactive_brokers_2_tasty_works.rb', line 219

def is_option_assignment_exercise_or_expiration(trade)
   proceeds_is_zero?(trade) && trade[:transactionType] == "BookTrade" && trade[:notes] =~ /^A$|^Ex$|^Ep$/i
end

.proceeds_is_zero?(trade) ⇒ Boolean

Returns:

  • (Boolean)


211
212
213
# File 'lib/interactive_brokers_2_tasty_works.rb', line 211

def proceeds_is_zero?(trade)
  string_is_zero?(trade[:proceeds])
end

.put_or_call(trade) ⇒ Object



201
202
203
204
# File 'lib/interactive_brokers_2_tasty_works.rb', line 201

def put_or_call(trade)
  return nil unless trade[:assetCategory] == 'OPT'
  trade[:putCall] == 'P' ? 'PUT' : 'CALL'
end

.string_is_zero?(str) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
209
# File 'lib/interactive_brokers_2_tasty_works.rb', line 206

def string_is_zero?(str)
  str = str.to_s.strip
  str == '0' || str == '-0'
end

.strip_zero_decimal(val) ⇒ Object



215
216
217
# File 'lib/interactive_brokers_2_tasty_works.rb', line 215

def strip_zero_decimal(val)
  val.to_s.sub(/\.0$/, '')
end