ig_markets 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -4
  3. data/README.md +70 -17
  4. data/lib/ig_markets.rb +27 -15
  5. data/lib/ig_markets/{account_activity.rb → activity.rb} +1 -1
  6. data/lib/ig_markets/cli/{account_command.rb → commands/account_command.rb} +5 -4
  7. data/lib/ig_markets/cli/commands/activities_command.rb +37 -0
  8. data/lib/ig_markets/cli/commands/confirmation_command.rb +14 -0
  9. data/lib/ig_markets/cli/{orders_command.rb → commands/orders_command.rb} +16 -21
  10. data/lib/ig_markets/cli/{positions_command.rb → commands/positions_command.rb} +31 -19
  11. data/lib/ig_markets/cli/commands/search_command.rb +18 -0
  12. data/lib/ig_markets/cli/commands/sentiment_command.rb +19 -0
  13. data/lib/ig_markets/cli/{sprints_command.rb → commands/sprints_command.rb} +10 -8
  14. data/lib/ig_markets/cli/commands/transactions_command.rb +61 -0
  15. data/lib/ig_markets/cli/{watchlists_command.rb → commands/watchlists_command.rb} +16 -12
  16. data/lib/ig_markets/cli/main.rb +65 -15
  17. data/lib/ig_markets/cli/tables/accounts_table.rb +30 -0
  18. data/lib/ig_markets/cli/tables/activities_table.rb +29 -0
  19. data/lib/ig_markets/cli/tables/client_sentiments_table.rb +31 -0
  20. data/lib/ig_markets/cli/tables/market_overviews_table.rb +47 -0
  21. data/lib/ig_markets/cli/tables/positions_table.rb +83 -0
  22. data/lib/ig_markets/cli/tables/sprint_market_positions_table.rb +55 -0
  23. data/lib/ig_markets/cli/tables/table.rb +103 -0
  24. data/lib/ig_markets/cli/tables/transactions_table.rb +41 -0
  25. data/lib/ig_markets/cli/tables/working_orders_table.rb +27 -0
  26. data/lib/ig_markets/dealing_platform/account_methods.rb +8 -8
  27. data/lib/ig_markets/dealing_platform/client_sentiment_methods.rb +4 -0
  28. data/lib/ig_markets/dealing_platform/market_methods.rb +1 -1
  29. data/lib/ig_markets/format.rb +20 -7
  30. data/lib/ig_markets/market_overview.rb +1 -1
  31. data/lib/ig_markets/model.rb +10 -1
  32. data/lib/ig_markets/model/typecasters.rb +1 -1
  33. data/lib/ig_markets/position.rb +12 -11
  34. data/lib/ig_markets/request_printer.rb +56 -0
  35. data/lib/ig_markets/response_parser.rb +11 -0
  36. data/lib/ig_markets/session.rb +7 -8
  37. data/lib/ig_markets/{account_transaction.rb → transaction.rb} +4 -17
  38. data/lib/ig_markets/version.rb +1 -1
  39. metadata +54 -16
  40. data/lib/ig_markets/cli/activities_command.rb +0 -31
  41. data/lib/ig_markets/cli/confirmation_command.rb +0 -16
  42. data/lib/ig_markets/cli/output.rb +0 -115
  43. data/lib/ig_markets/cli/search_command.rb +0 -16
  44. data/lib/ig_markets/cli/sentiment_command.rb +0 -24
  45. data/lib/ig_markets/cli/transactions_command.rb +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 724ac2b070ec1f942dc3d1be4417bb82486dd414
4
- data.tar.gz: f219d63e7c52e427e5813a6369abcfcea838c9c3
3
+ metadata.gz: ef481344a1515b0031301c4e70e17ce843f7f111
4
+ data.tar.gz: f2282b07a67e0dfba0fa8e7a8936d630777663e0
5
5
  SHA512:
6
- metadata.gz: 037f9fe742a849aa0c74a537bafbe276078e7a34d41fd30f5302e5ff9f025de88ba13842438cef017fddb3ed562f9bb4a317735c72e79b6e2679a9054965b9b5
7
- data.tar.gz: 89aa2c236ca20d253a5b5be311cbf9f0819c440fa77b2caa0d0c91380ae200287375b8ff60b52ebeca9b5eaa3e18c41374c9379aa61b26c52e5c2c27c7ccbf9e
6
+ metadata.gz: d3816a297817a2d1da84402f1a20689e2b2f271ae7bc1c76a623f19b45320674f7ca94ec39b703bbb3553f2eb364b6d08f10f3cdc1db0c615b4887859253dc28
7
+ data.tar.gz: 27b911f529724f105c3d443b41fc878f78c45815f6b9b1ce94569a6e88c17d85de48e34ed087e38307f638c05af61d90c9101b50a2db9056eb76d9c939ed2aaa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # IG Markets Changelog
2
2
 
3
+ ### 0.6 - Unreleased
4
+
5
+ -
6
+
7
+ ### 0.5 - April 23, 2016
8
+
9
+ - Ouptut from the command-line client is now formatted using ASCII tables and contains a lot more detail
10
+ - Added `--aggregate` option to `ig_markets positions list` to aggregate together positions with the same EPIC
11
+ - Added `--instrument` option to `ig_markets transactions` to filter by instrument name
12
+ - Added `--no-interest` option to `ig_markets transactions` to exclude interest transactions
13
+ - Added `--print-requests` option to the command-line client to see all the interactions with the IG Markets API
14
+ - Support removal of limits and stops using `ig_markets positions update` and `ig_markets orders update`
15
+ - Removed `--related` option from `ig_markets sentiment`, related sentiments are now always reported and are also
16
+ color-coded
17
+ - `IGMarkets::DealingPlatform::ClientSentimentMethods#[]` now raises an exception on unknown market IDs
18
+ - Added `IGMarkets::Position#close_level`
19
+ - Removed `IGMarkets::Position#formatted_size` and `IGMarkets::Transaction#formatted_transaction_type`
20
+
3
21
  ### 0.4 - April 18, 2016
4
22
 
5
23
  - Added `create`, `update` and `delete` subcommands to `ig_markets orders`
@@ -8,10 +26,11 @@
8
26
  - Added `create`, `add-markets`, `remove-markets` and `delete` subcommands to `ig_markets watchlists`
9
27
  - `ig_markets confirmation`, `ig_markets search` and `ig_markets sentiment` now take their mandatory argument directly
10
28
  - Added `--start-date` option to the `ig_markets activities` and `ig_markets transactions` commands
11
- - Removed the `:time_in_force` option from `IGMarkets::WorkingOrderMethods#create` and `IGMarkets::WorkingOrder#update`,
12
- just set `:good_till_date` if it is needed
13
- - `IGMarkets::AccountMethods#recent_activities` and `IGMarkets::AccountMethods#recent_transactions` now take a number of
14
- days rather than a number of seconds
29
+ - Removed the `:time_in_force` option from `IGMarkets::DealingPlatform::WorkingOrderMethods#create` and
30
+ `IGMarkets::WorkingOrder#update`, just set `:good_till_date` if it is needed
31
+ - `IGMarkets::DealingPlatform::AccountMethods#recent_activities` and
32
+ `IGMarkets::DealingPlatform::AccountMethods#recent_transactions` now take a number of days rather than a number of
33
+ seconds
15
34
  - Fixed errors working with a working order's `#good_till_date` attribute
16
35
  - Automatically reauthenticate if the client security token has expired
17
36
 
data/README.md CHANGED
@@ -28,52 +28,109 @@ An IG Markets production or demo trading account is needed in order to use this
28
28
 
29
29
  Licensed under the MIT license. You must read and agree to its terms to use this software.
30
30
 
31
- ## Usage — Command-Line Client
31
+ ## Installation
32
32
 
33
- ```sh
34
- $ gem install ig_markets
33
+ Install the latest version of the `ig_markets` gem with the following command:
35
34
 
36
- Usage: ig_markets COMMAND --username=USERNAME --password=PASSWORD --api-key=API-KEY [--demo]
35
+ ```
36
+ $ gem install ig_markets
37
37
  ```
38
38
 
39
- On startup `ig_markets` searches for files named `"./.ig_markets"` and then `"~/.ig_markets"`, and if they are present
40
- interprets their contents as command-line arguments. This can be used to avoid having to specify authentication details
41
- with every invocation. To do this create a file at `"./.ig_markets"` or `"~/.ig_markets"` with the following contents:
39
+ ## Usage Command-Line Client
40
+
41
+ The general form for invoking the command-line client is:
42
42
 
43
43
  ```
44
+ $ ig_markets COMMAND [SUBCOMMAND] --username=USERNAME --password=PASSWORD --api-key=API-KEY [--demo] [...]
45
+ ```
46
+
47
+ #### Config File
48
+
49
+ On startup `ig_markets` searches for config files named `"./.ig_markets"` and then `"~/.ig_markets"`, and if they are
50
+ present interprets their contents as command-line arguments. This can be used to avoid having to specify authentication
51
+ details with every invocation.
52
+
53
+ To do this create a config file at `"./.ig_markets"` or `"~/.ig_markets"` with the following contents:
54
+
55
+ ```shell
44
56
  --username=USERNAME
45
57
  --password=PASSWORD
46
58
  --api-key=API-KEY
47
59
  --demo # Include only if this is a demo account
48
60
  ```
49
61
 
50
- Run `ig_markets help` to list details on available commands. The full list of commands is:
62
+ The following examples assume the presence of a config file that contains valid authentication details.
63
+
64
+ #### Commands
65
+
66
+ Use `ig_markets help` to get details on the options accepted by the commands and subcommands. The list of available
67
+ commands and their subcommands is:
51
68
 
52
69
  - `ig_markets account`
53
70
  - `ig_markets activities --days=N [--start-date=YYYY-MM-DD]`
54
71
  - `ig_markets confirmation DEAL-REFERENCE`
72
+ - `ig_markets help [COMMAND]`
55
73
  - `ig_markets orders [list]`
56
74
  - `ig_markets orders create ...`
57
75
  - `ig_markets orders update DEAL-ID ...`
58
76
  - `ig_markets orders delete DEAL-ID`
59
- - `ig_markets positions`
77
+ - `ig_markets positions [list] [--aggregate]`
60
78
  - `ig_markets positions create ...`
61
79
  - `ig_markets positions update DEAL-ID ...`
62
- - `ig_markets positions close DEAL-ID ...`
80
+ - `ig_markets positions close DEAL-ID [...]`
63
81
  - `ig_markets search QUERY`
64
- - `ig_markets sentiment MARKET [--related]`
82
+ - `ig_markets sentiment MARKET`
65
83
  - `ig_markets sprints [list]`
66
84
  - `ig_markets sprints create ...`
67
- - `ig_markets transactions --days=N [--start-date=YYYY-MM-DD]`
85
+ - `ig_markets transactions --days=N [--start-date=YYYY-MM-DD] [--instrument=INSTRUMENT] [--no-interest]`
68
86
  - `ig_markets watchlists [list]`
69
87
  - `ig_markets watchlists create NAME [EPIC EPIC ...]`
70
88
  - `ig_markets watchlists add-markets WATCHLIST-ID [EPIC EPIC ...]`
71
89
  - `ig_markets watchlists remove-markets WATCHLIST-ID [EPIC EPIC ...]`
72
90
  - `ig_markets watchlists delete WATCHLIST-ID`
73
91
 
92
+ #### Examples
93
+
94
+ ```shell
95
+ # Print account details and balances
96
+ ig_markets account
97
+
98
+ # Print EUR/USD transactions from the last week, excluding interest transactions
99
+ ig_markets transactions --days=7 --instrument EUR/USD --no-interest
100
+
101
+ # Print current positions in aggregate
102
+ ig_markets positions --aggregate
103
+
104
+ # Create a EURUSD long position of size 2
105
+ ig_markets positions create --currency-code USD --direction buy --epic CS.D.EURUSD.CFD.IP --size 2
106
+
107
+ # Change the limit and stop levels for an existing position
108
+ ig_markets positions update DEAL-ID --limit-level 1.15 --stop-level 1.10
109
+
110
+ # Fully close a position
111
+ ig_markets positions close DEAL-ID
112
+
113
+ # Partially close a position (assuming its size is greater than 1)
114
+ ig_markets positions close DEAL-ID --size 1
115
+
116
+ # Create a EURUSD sprint market short position of size 100 that expires in 20 minutes
117
+ ig_markets sprints create --direction sell --epic FM.D.EURUSD24.EURUSD24.IP --expiry-period 20 --size 100
118
+
119
+ # Create a working order to buy 1 unit of EURUSD at the level 1.1
120
+ ig_markets orders create --currency-code USD --direction buy --epic CS.D.EURUSD.CFD.IP --level 1.1 --size 1 --type limit
121
+ ```
122
+
74
123
  ## Usage — Library
75
124
 
125
+ #### Documentation
126
+
127
+ API documentation is available [here](http://www.rubydoc.info/github/rviney/ig_markets/master).
128
+
129
+ #### Examples
130
+
76
131
  ```ruby
132
+ require 'ig_markets'
133
+
77
134
  ig = IGMarkets::DealingPlatform.new
78
135
 
79
136
  # Session
@@ -101,7 +158,7 @@ ig.positions['deal_id'].close
101
158
  # Sprint market positions
102
159
  ig.sprint_market_positions.all
103
160
  ig.sprint_market_positions.create direction: :buy, epic: 'FM.D.EURUSD24.EURUSD24.IP',
104
- expiry_period: :one_minute, size: 100
161
+ expiry_period: :twenty_minutes, size: 100
105
162
 
106
163
  # Working orders
107
164
  ig.working_orders.all
@@ -135,10 +192,6 @@ ig.client_sentiment['EURUSD'].related_sentiments
135
192
  ig.applications
136
193
  ```
137
194
 
138
- ## Documentation
139
-
140
- API documentation is available [here](http://www.rubydoc.info/github/rviney/ig_markets/master).
141
-
142
195
  ## Contributors
143
196
 
144
197
  Gem created by Richard Viney. All contributions welcome.
data/lib/ig_markets.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'base64'
2
+ require 'colorize'
2
3
  require 'date'
3
4
  require 'rest-client'
5
+ require 'terminal-table'
4
6
  require 'thor'
5
7
 
6
8
  require 'ig_markets/boolean'
@@ -9,23 +11,9 @@ require 'ig_markets/model/typecasters'
9
11
  require 'ig_markets/regex'
10
12
 
11
13
  require 'ig_markets/account'
12
- require 'ig_markets/account_activity'
13
- require 'ig_markets/account_transaction'
14
+ require 'ig_markets/activity'
14
15
  require 'ig_markets/api_versions'
15
16
  require 'ig_markets/application'
16
- require 'ig_markets/cli/orders_command'
17
- require 'ig_markets/cli/positions_command'
18
- require 'ig_markets/cli/sprints_command'
19
- require 'ig_markets/cli/watchlists_command'
20
- require 'ig_markets/cli/main'
21
- require 'ig_markets/cli/account_command'
22
- require 'ig_markets/cli/activities_command'
23
- require 'ig_markets/cli/config_file'
24
- require 'ig_markets/cli/confirmation_command'
25
- require 'ig_markets/cli/output'
26
- require 'ig_markets/cli/search_command'
27
- require 'ig_markets/cli/sentiment_command'
28
- require 'ig_markets/cli/transactions_command'
29
17
  require 'ig_markets/client_sentiment'
30
18
  require 'ig_markets/deal_confirmation'
31
19
  require 'ig_markets/dealing_platform'
@@ -46,13 +34,37 @@ require 'ig_markets/password_encryptor'
46
34
  require 'ig_markets/payload_formatter'
47
35
  require 'ig_markets/position'
48
36
  require 'ig_markets/request_failed_error'
37
+ require 'ig_markets/request_printer'
49
38
  require 'ig_markets/response_parser'
50
39
  require 'ig_markets/session'
51
40
  require 'ig_markets/sprint_market_position'
41
+ require 'ig_markets/transaction'
52
42
  require 'ig_markets/version'
53
43
  require 'ig_markets/watchlist'
54
44
  require 'ig_markets/working_order'
55
45
 
46
+ require 'ig_markets/cli/commands/orders_command'
47
+ require 'ig_markets/cli/commands/positions_command'
48
+ require 'ig_markets/cli/commands/sprints_command'
49
+ require 'ig_markets/cli/commands/watchlists_command'
50
+ require 'ig_markets/cli/main'
51
+ require 'ig_markets/cli/config_file'
52
+ require 'ig_markets/cli/commands/account_command'
53
+ require 'ig_markets/cli/commands/activities_command'
54
+ require 'ig_markets/cli/commands/confirmation_command'
55
+ require 'ig_markets/cli/commands/search_command'
56
+ require 'ig_markets/cli/commands/sentiment_command'
57
+ require 'ig_markets/cli/commands/transactions_command'
58
+ require 'ig_markets/cli/tables/table'
59
+ require 'ig_markets/cli/tables/accounts_table'
60
+ require 'ig_markets/cli/tables/activities_table'
61
+ require 'ig_markets/cli/tables/client_sentiments_table'
62
+ require 'ig_markets/cli/tables/market_overviews_table'
63
+ require 'ig_markets/cli/tables/working_orders_table'
64
+ require 'ig_markets/cli/tables/positions_table'
65
+ require 'ig_markets/cli/tables/sprint_market_positions_table'
66
+ require 'ig_markets/cli/tables/transactions_table'
67
+
56
68
  # This module contains all the code for the IG Markets gem. See `README.md` and the {DealingPlatform} class to get
57
69
  # started with using this gem.
58
70
  module IGMarkets
@@ -2,7 +2,7 @@ module IGMarkets
2
2
  # Contains details on a single activity that occurred on an IG Markets account. Returned by
3
3
  # {DealingPlatform::AccountMethods#activities_in_date_range} and
4
4
  # {DealingPlatform::AccountMethods#recent_activities}.
5
- class AccountActivity < Model
5
+ class Activity < Model
6
6
  attribute :action_status, Symbol, allowed_values: [:accept, :reject, :manual, :not_set]
7
7
  attribute :activity
8
8
  attribute :activity_history_id
@@ -6,10 +6,11 @@ module IGMarkets
6
6
 
7
7
  def account
8
8
  self.class.begin_session(options) do |dealing_platform|
9
- dealing_platform.account.all.each do |account|
10
- Output.print_account account
11
- Output.print_account_balance account
12
- end
9
+ accounts = dealing_platform.account.all
10
+
11
+ table = AccountsTable.new accounts
12
+
13
+ puts table
13
14
  end
14
15
  end
15
16
  end
@@ -0,0 +1,37 @@
1
+ module IGMarkets
2
+ module CLI
3
+ # Implements the `ig_markets activities` command.
4
+ class Main
5
+ desc 'activities', 'Prints account activities'
6
+
7
+ option :days, type: :numeric, required: true, desc: 'The number of days to print account activities for'
8
+ option :start_date, desc: 'The start date to print account activities from, format: yyyy-mm-dd'
9
+
10
+ def activities
11
+ self.class.begin_session(options) do |_dealing_platform|
12
+ activities = gather_account_history(:activities).sort_by(&:date)
13
+
14
+ table = ActivitiesTable.new activities
15
+
16
+ puts table
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def gather_account_history(type)
23
+ days = options[:days]
24
+ start_date = options[:start_date]
25
+
26
+ if start_date
27
+ start_date = Date.strptime start_date, '%F'
28
+ end_date = start_date + days.to_i
29
+
30
+ Main.dealing_platform.account.send "#{type}_in_date_range", start_date, end_date
31
+ else
32
+ Main.dealing_platform.account.send "recent_#{type}", days
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,14 @@
1
+ module IGMarkets
2
+ module CLI
3
+ # Implements the `ig_markets confirmation` command.
4
+ class Main < Thor
5
+ desc 'confirmation DEAL-REFERENCE', 'Prints the deal confirmation for the specified deal reference'
6
+
7
+ def confirmation(deal_reference)
8
+ self.class.begin_session(options) do |_dealing_platform|
9
+ Main.report_deal_confirmation deal_reference
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -6,9 +6,11 @@ module IGMarkets
6
6
 
7
7
  def list
8
8
  Main.begin_session(options) do |dealing_platform|
9
- dealing_platform.working_orders.all.each do |order|
10
- Output.print_working_order order
11
- end
9
+ working_orders = dealing_platform.working_orders.all
10
+
11
+ table = WorkingOrdersTable.new working_orders
12
+
13
+ puts table
12
14
  end
13
15
  end
14
16
 
@@ -36,32 +38,28 @@ module IGMarkets
36
38
  Main.begin_session(options) do |dealing_platform|
37
39
  deal_reference = dealing_platform.working_orders.create working_order_attributes
38
40
 
39
- puts "Deal reference: #{deal_reference}"
40
-
41
- Output.print_deal_confirmation dealing_platform.deal_confirmation(deal_reference)
41
+ Main.report_deal_confirmation deal_reference
42
42
  end
43
43
  end
44
44
 
45
- desc 'update <DEAL-ID>', 'Updates an existing working order'
45
+ desc 'update DEAL-ID', 'Updates an existing working order'
46
46
 
47
47
  option :good_till_date, desc: 'The date that the order will live till, if not specified then the order will ' \
48
48
  'remain until it is deleted, format: yyyy-mm-ddThh:mm(+|-)zz:zz'
49
49
  option :level, type: :numeric, desc: 'The level at which the order will be triggered'
50
- option :limit_distance, type: :numeric, desc: 'The distance away in pips to place the limit'
51
- option :stop_distance, type: :numeric, desc: 'The distance away in pips to place the stop'
50
+ option :limit_distance, desc: 'The distance away in pips to place the limit'
51
+ option :stop_distance, desc: 'The distance away in pips to place the stop'
52
52
  option :type, desc: 'The order type, either \'limit\' or \'stop\''
53
53
 
54
54
  def update(deal_id)
55
55
  Main.begin_session(options) do |dealing_platform|
56
56
  deal_reference = dealing_platform.working_orders[deal_id].update working_order_attributes
57
57
 
58
- puts "Deal reference: #{deal_reference}"
59
-
60
- Output.print_deal_confirmation dealing_platform.deal_confirmation(deal_reference)
58
+ Main.report_deal_confirmation deal_reference
61
59
  end
62
60
  end
63
61
 
64
- desc 'delete <DEAL-ID>', 'Deletes the working order with the specified deal ID'
62
+ desc 'delete DEAL-ID', 'Deletes the working order with the specified deal ID'
65
63
 
66
64
  def delete(deal_id)
67
65
  Main.begin_session(options) do |dealing_platform|
@@ -70,21 +68,18 @@ module IGMarkets
70
68
  raise 'No working order with the specified deal ID' unless working_order
71
69
 
72
70
  deal_reference = working_order.delete
73
- puts "Deal reference: #{deal_reference}"
74
71
 
75
- Output.print_deal_confirmation dealing_platform.deal_confirmation(deal_reference)
72
+ Main.report_deal_confirmation deal_reference
76
73
  end
77
74
  end
78
75
 
79
76
  private
80
77
 
78
+ ATTRIBUTES = [:currency_code, :direction, :epic, :expiry, :force_open, :good_till_date, :guaranteed_stop, :level,
79
+ :limit_distance, :size, :stop_distance, :type].freeze
80
+
81
81
  def working_order_attributes
82
- attributes = options.each_with_object({}) do |(key, value), new_hash|
83
- if [:currency_code, :direction, :epic, :expiry, :force_open, :good_till_date, :guaranteed_stop, :level,
84
- :limit_distance, :size, :stop_distance, :type].include? key.to_sym
85
- new_hash[key.to_sym] = value
86
- end
87
- end
82
+ attributes = Main.filter_options options, ATTRIBUTES
88
83
 
89
84
  Main.parse_date_time attributes, :expiry, Date, '%F', 'yyyy-mm-dd'
90
85
  Main.parse_date_time attributes, :good_till_date, Time, '%FT%R%z', 'yyyy-mm-ddThh:mm(+|-)zz:zz'
@@ -2,13 +2,21 @@ module IGMarkets
2
2
  module CLI
3
3
  # Implements the `ig_markets positions` command.
4
4
  class Positions < Thor
5
- desc 'list', 'Prints open positions'
5
+ desc 'list', 'Prints open non-binary positions'
6
+
7
+ option :aggregate, type: :boolean, desc: 'Whether to aggregate separate positions in the same market'
6
8
 
7
9
  def list
8
10
  Main.begin_session(options) do |dealing_platform|
9
- dealing_platform.positions.all.each do |position|
10
- Output.print_position position
11
+ positions = dealing_platform.positions.all.reject do |position|
12
+ position.market.instrument_type == :binary
11
13
  end
14
+
15
+ positions_table = PositionsTable.new positions, aggregate: options[:aggregate]
16
+
17
+ puts positions_table
18
+
19
+ print_position_totals positions
12
20
  end
13
21
  end
14
22
 
@@ -42,16 +50,14 @@ module IGMarkets
42
50
  Main.begin_session(options) do |dealing_platform|
43
51
  deal_reference = dealing_platform.positions.create position_attributes
44
52
 
45
- puts "Deal reference: #{deal_reference}"
46
-
47
- Output.print_deal_confirmation dealing_platform.deal_confirmation(deal_reference)
53
+ Main.report_deal_confirmation deal_reference
48
54
  end
49
55
  end
50
56
 
51
- desc 'update <DEAL-ID>', 'Updates attributes of an existing position'
57
+ desc 'update DEAL-ID', 'Updates attributes of an existing position'
52
58
 
53
- option :limit_level, type: :numeric, desc: 'The limit level'
54
- option :stop_level, type: :numeric, desc: 'The stop level'
59
+ option :limit_level, desc: 'The limit level'
60
+ option :stop_level, desc: 'The stop level'
55
61
  option :trailing_stop, type: :boolean, desc: 'Whether to use a trailing stop, defaults to false'
56
62
  option :trailing_stop_distance, type: :numeric, desc: 'The distance away in pips to place the trailing stop'
57
63
  option :trailing_stop_increment, type: :numeric, desc: 'The increment step in pips for the trailing stop'
@@ -62,7 +68,7 @@ module IGMarkets
62
68
  end
63
69
  end
64
70
 
65
- desc 'close <DEAL-ID>', 'Closes or partially closes a position'
71
+ desc 'close DEAL-ID', 'Closes or partially closes a position'
66
72
 
67
73
  option :level, type: :numeric, desc: 'Required if and only if --order-type is \'limit\' or \'quote\''
68
74
  option :order_type, default: 'market', desc: 'The order type, must be \'limit\', \'market\' or \'quote\''
@@ -79,14 +85,12 @@ module IGMarkets
79
85
 
80
86
  private
81
87
 
82
- def position_attributes
83
- attributes = options.each_with_object({}) do |(key, value), new_hash|
84
- next unless [:currency_code, :direction, :epic, :expiry, :force_open, :guaranteed_stop, :level,
85
- :limit_distance, :limit_level, :order_type, :quote_id, :size, :stop_distance, :stop_level,
86
- :time_in_force, :trailing_stop, :trailing_stop_increment].include? key.to_sym
88
+ ATTRIBUTES = [:currency_code, :direction, :epic, :expiry, :force_open, :guaranteed_stop, :level, :limit_distance,
89
+ :limit_level, :order_type, :quote_id, :size, :stop_distance, :stop_level, :time_in_force,
90
+ :trailing_stop, :trailing_stop_increment].freeze
87
91
 
88
- new_hash[key.to_sym] = value
89
- end
92
+ def position_attributes
93
+ attributes = Main.filter_options options, ATTRIBUTES
90
94
 
91
95
  Main.parse_date_time attributes, :expiry, Date, '%F', 'yyyy-mm-dd'
92
96
 
@@ -101,10 +105,18 @@ module IGMarkets
101
105
 
102
106
  deal_reference = yield position
103
107
 
104
- puts "Deal reference: #{deal_reference}"
108
+ Main.report_deal_confirmation deal_reference
109
+ end
110
+ end
111
+
112
+ def print_position_totals(positions)
113
+ currency_totals = positions.group_by(&:currency).map do |currency, subset|
114
+ total = subset.map(&:profit_loss).reduce(:+)
105
115
 
106
- Output.print_deal_confirmation dealing_platform.deal_confirmation(deal_reference)
116
+ Format.currency(total, currency).colorize(total < 0 ? :red : :green)
107
117
  end
118
+
119
+ puts "\nTotal profit/loss: #{currency_totals.join ', '}"
108
120
  end
109
121
  end
110
122
  end