interactive_brokers_2_tasty_works 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5da3529ee36a231a2ae0f886d9fffca70210ee0f8c6c4e1253942fefaa77a2d
4
- data.tar.gz: 98f28bcc63d0bc1ea929d610cc59c130e2d5b4a87023cad08a9b6c3ca73223e7
3
+ metadata.gz: 863983279975a5eb786885e48bb92933181e179f6c1d99d7a5858a0c72ead21e
4
+ data.tar.gz: e656aa6e2c917ef034c839553f03d137a7ac37bd9d633bbf8ea86f28873ae5b7
5
5
  SHA512:
6
- metadata.gz: 23d68aea06ed3f7a252101294e72b8a7566723b819430c5a28a98c1a093b90f2bbadfc5224878ca3509e618b4b4181220e0ce0c93a95311bb08cd2e159828e6f
7
- data.tar.gz: d2ebf3afeff29dc2e9b0300b61bc756674bb1740d407539ad9a8d5ef824b4debb122a0e41f91d1fe7d2749ce347b5d9b3d1173ee5de6abcb6ab4042accd4e3d3
6
+ metadata.gz: 4457b86322469c760021ab2046b7b2aa0ece5e51c279af331aae43e21ad6aecc6e463ab2049295896b30fdbdcf7a16b48ff3aea34b2f969de02d3ef98533bee7
7
+ data.tar.gz: 19dc89f4ffd60a37ca565eda0b23f860a785b5d62e28f4b53bd90478402c8ab5e5befd92255334b91dca70214fac03fce96dcb3019d79d04deffea9949fa1ec4
data/Gemfile.lock CHANGED
@@ -1,23 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- interactive_brokers_2_tasty_works (0.2.0)
4
+ interactive_brokers_2_tasty_works (0.3.0)
5
5
  activesupport
6
6
  xmlhasher
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (5.2.1.1)
11
+ activesupport (5.2.2)
12
12
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
13
  i18n (>= 0.7, < 2)
14
14
  minitest (~> 5.1)
15
15
  tzinfo (~> 1.1)
16
16
  byebug (10.0.2)
17
- concurrent-ruby (1.1.3)
17
+ concurrent-ruby (1.1.4)
18
18
  diff-lcs (1.3)
19
19
  escape_utils (1.2.1)
20
- i18n (1.1.1)
20
+ i18n (1.3.0)
21
21
  concurrent-ruby (~> 1.0)
22
22
  minitest (5.11.3)
23
23
  ox (2.10.0)
data/README.md CHANGED
@@ -5,7 +5,7 @@ This library converts the output of an Interactive Brokers Execution Flex Query
5
5
  ### Flex Query Parameters in Interactive Brokers
6
6
 
7
7
  - Leave all defaults
8
- - Set time period to LAST 365 DAYS
8
+ - Set time period to LAST 365 DAYS (or whatever you want, really)
9
9
  - In Sections, select Trades
10
10
  + Select Executions
11
11
  + Select All
@@ -26,13 +26,19 @@ Or install it yourself as:
26
26
 
27
27
  $ gem install interactive_brokers_2_tasty_works
28
28
 
29
- ## Command Line Usage
29
+ ## Usage
30
30
 
31
- `ib2tw /path/to/input.xml /path/to/output.csv`
31
+ `InteractiveBrokers2TastyWorks.new(input_path: '~/trades.xml').save_as("/tmp/trades.csv")`
32
32
 
33
- ## Programatic Usage
33
+ ### Adding additional fields to the output (non standard output format)
34
34
 
35
- `InteractiveBrokers2TastyWorks.new(input_path: '~/trades.xml').save_as("/tmp/trades.csv")`
35
+ ```
36
+ InteractiveBrokers2TastyWorks.new(input_path: '~/trades.xml', add_output: ['ibExecID', 'ibOrderID'])
37
+
38
+ # or to specify a different header for the additional fields
39
+
40
+ InteractiveBrokers2TastyWorks.new(input_path: '~/trades.xml', add_output: { ibExecID: 'IB Execution ID', ibOrderID: 'IB Order ID' })
41
+ ```
36
42
 
37
43
  ## Development
38
44
 
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
21
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
22
  end
23
-
24
- spec.executables = ["ib2tw"]
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 1.16"
@@ -19,10 +19,11 @@ class InteractiveBrokers2TastyWorks
19
19
  'Average Price', 'Commissions', 'Fees', 'Multiplier', 'Underlying Symbol', 'Expiration Date',
20
20
  'Strike Price', 'Call or Put']
21
21
 
22
- def initialize(data_hash: nil, input_path: nil, file_format: :xml)
22
+ def initialize(data_hash: nil, input_path: nil, file_format: :xml, add_output: nil)
23
23
  @data_hash = data_hash
24
24
  @input_path = input_path
25
25
  @file_format = file_format
26
+ @add_output = add_output
26
27
 
27
28
  raise ArgumenrError.new("Must specify `data_hash` or `input_path`.") if data_hash.empty? && input_path.empty?
28
29
 
@@ -31,8 +32,6 @@ class InteractiveBrokers2TastyWorks
31
32
  file_format = file_format.to_s.to_sym unless file_format.is_a?(Symbol)
32
33
  raise ArgumentError.new("Unknown file format: #{file_format}") unless %i(xml json).include?(file_format)
33
34
  end
34
-
35
- Time.zone ||= Time.now.getlocal.zone
36
35
  end
37
36
 
38
37
  def save_as(output_path)
@@ -48,7 +47,8 @@ class InteractiveBrokers2TastyWorks
48
47
  private
49
48
 
50
49
  def convert!
51
- output = [OUTPUT_HEADER]
50
+ output = [add_output_headers ? (OUTPUT_HEADER + add_output_headers) : OUTPUT_HEADER]
51
+ # require 'byebug';byebug
52
52
 
53
53
  trades = if data_hash[:FlexQueryResponse].is_a?(Array)
54
54
  data_hash[:FlexQueryResponse][1][:FlexStatements][1][:FlexStatement][1][:Trades][:Trade]
@@ -77,8 +77,9 @@ class InteractiveBrokers2TastyWorks
77
77
  trade[:strike],
78
78
  Utils.put_or_call(trade)
79
79
  ]
80
- end
81
80
 
81
+ output.last.concat(add_output_values(trade)) if add_output_values(trade)
82
+ end
82
83
  output
83
84
  end
84
85
 
@@ -96,6 +97,34 @@ class InteractiveBrokers2TastyWorks
96
97
  end
97
98
  end
98
99
 
100
+ def add_output_values(trade)
101
+ return nil unless @add_output.present?
102
+
103
+ add_output_fields.map { |f| Utils.indifferent_fetch(trade, f) }
104
+ # output = []
105
+ # add_output_fields.each do |f|
106
+ # output << trade[f]
107
+ # end
108
+
109
+ # output
110
+ end
111
+
112
+ def add_output_fields
113
+ if @add_output.is_a?(Hash)
114
+ @add_output.keys
115
+ elsif @add_output.is_a?(Array)
116
+ @add_output
117
+ end
118
+ end
119
+
120
+ def add_output_headers
121
+ if @add_output.is_a?(Hash)
122
+ @add_output.values
123
+ elsif @add_output.is_a?(Array)
124
+ @add_output
125
+ end
126
+ end
127
+
99
128
  module Utils
100
129
  class << self
101
130
  def build_date_time_str(trade)
@@ -165,6 +194,12 @@ class InteractiveBrokers2TastyWorks
165
194
  return nil unless trade[:assetCategory] == 'OPT'
166
195
  trade[:putCall] == 'P' ? 'PUT' : 'CALL'
167
196
  end
197
+
198
+ def indifferent_fetch(h, key)
199
+ h.fetch(key)
200
+ rescue KeyError
201
+ h[key.is_a?(String) ? key.to_sym : key.to_s]
202
+ end
168
203
  end
169
204
  end
170
205
  end
@@ -1,3 +1,3 @@
1
1
  class InteractiveBrokers2TastyWorks
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interactive_brokers_2_tasty_works
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Mercier
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-29 00:00:00.000000000 Z
11
+ date: 2018-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -97,8 +97,7 @@ dependencies:
97
97
  description: Interactive Brokers to Tasty Works trade statement converter
98
98
  email:
99
99
  - foss@carlmercier.com
100
- executables:
101
- - ib2tw
100
+ executables: []
102
101
  extensions: []
103
102
  extra_rdoc_files: []
104
103
  files:
@@ -112,7 +111,6 @@ files:
112
111
  - README.md
113
112
  - Rakefile
114
113
  - bin/console
115
- - bin/ib2tw
116
114
  - bin/setup
117
115
  - interactive_brokers_2_tasty_works.gemspec
118
116
  - lib/interactive_brokers_2_tasty_works.rb
data/bin/ib2tw DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/interactive_brokers_2_tasty_works'
4
-
5
- if ARGV[0].nil? || ARGV[1].nil? || ARGV[0].include?('--help') || ARGV[0].include?('-?')
6
- puts "\nUsage: ./ib2tw /path/to/input.xml /path/to/output.csv\n\n"
7
- exit 1
8
- end
9
-
10
- input_file = File.expand_path(ARGV[0])
11
- output_file = File.expand_path(ARGV[1])
12
-
13
- unless File.exists?(input_file)
14
- puts "\nFile not found: #{input_file}\n\n"
15
- exit 1
16
- end
17
-
18
- puts "\n"
19
- puts "Input: #{input_file}"
20
- puts "Output: #{output_file}\n"
21
- puts "Converting..."
22
-
23
- InteractiveBrokers2TastyWorks.new(input_path: input_file).save_as(output_file)
24
-
25
- puts "Done!"