ig_markets 0.13 → 0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d08c5bda8c3b5efc6a42dff92de064a76e42fa24
4
- data.tar.gz: defcb9eaeb04b87f3772911e66b849a22ab091e2
3
+ metadata.gz: 4a9c0f861710bf880c830d2826c3e4ece9c2ef35
4
+ data.tar.gz: 4c2f4dbd5d336489e2a343ac0015ff34c0910e2b
5
5
  SHA512:
6
- metadata.gz: 80efc7ada830d2c5758c0c58dd5f2e666c0c4f315bd196e1de8c25423b8a901be0ac4cac40ddc6f189ca8bedf3d48001caa925b149fa7afb62340f3e32e41a6b
7
- data.tar.gz: 4eace6c040b07b374f878c9a621a8e090781758b345da829a841f0b8868c406b3f15b6e27f8166627fae33efebed7a4282e4b0367afce45492477c2e965fd861
6
+ metadata.gz: fa7dc0e4c01816d95e5b6dfec934c3a52e66b9b82ed27f5b777c19a89fa7bda5915b8f9bdba02ae6a3b8b42c251622ffa91c2c1a41e6c032ca4ae7300b611ca8
7
+ data.tar.gz: 9ca3b4fe730001d4ed3d8900ec5483e3a10e386e9b772f4057e0696b9c3f8019889318faf6abda047735046dade967bcaf537a1a157b95e90e5eb751928feb23
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # IG Markets Changelog
2
2
 
3
- ### 0.13Unreleased
3
+ ### 0.14July 2, 2016
4
+
5
+ - Added `delete-all` subcommand to `ig_markets orders`
6
+ - Added a `#reload` method that reloads a model's attributes in-place to `IGMarkets::Account`,
7
+ `IGMarkets::ClientSentiment`, `IGMarkets::Market`, `IGMarkets::Position` and `IGMarkets::WorkingOrder`
8
+
9
+ ### 0.13 — June 22, 2016
4
10
 
5
11
  - Added `ig_markets performance` command that summarizes an account's dealing performance over a specified period
6
12
  - Added `ig_markets markets` command which prints the current state of all the passed EPICs
data/README.md CHANGED
@@ -76,6 +76,7 @@ commands and their subcommands is:
76
76
  - `ig_markets orders create ...`
77
77
  - `ig_markets orders update DEAL-ID ...`
78
78
  - `ig_markets orders delete DEAL-ID`
79
+ - `ig_markets orders delete-all`
79
80
  - `ig_markets performance --days N [...]`
80
81
  - `ig_markets positions [list] [...]`
81
82
  - `ig_markets positions create ...`
@@ -173,45 +174,48 @@ ig.deal_confirmation 'deal_reference'
173
174
  # Positions
174
175
  ig.positions.all
175
176
  ig.positions.create currency_code: 'USD', direction: :buy, epic: 'CS.D.EURUSD.CFD.IP', size: 2
176
- ig.positions['deal_id']
177
- ig.positions['deal_id'].profit_loss
178
- ig.positions['deal_id'].update limit_level: 1.2, stop_level: 1.1
179
- ig.positions['deal_id'].close
177
+ position = ig.positions['deal_id']
178
+ position.profit_loss
179
+ position.update limit_level: 1.2, stop_level: 1.1
180
+ position.reload
181
+ position.close
180
182
 
181
183
  # Sprint market positions
182
184
  ig.sprint_market_positions.all
183
- ig.sprint_market_positions['deal_id']
184
185
  ig.sprint_market_positions.create direction: :buy, epic: 'FM.D.EURUSD24.EURUSD24.IP',
185
186
  expiry_period: :twenty_minutes, size: 100
187
+ sprint_market_position = ig.sprint_market_positions['deal_id']
186
188
 
187
189
  # Working orders
188
190
  ig.working_orders.all
189
191
  ig.working_orders.create currency_code: 'USD', direction: :buy, epic: 'CS.D.EURUSD.CFD.IP',
190
192
  level: 0.99, size: 1, type: :limit
191
- ig.working_orders['deal_id']
192
- ig.working_orders['deal_id'].update level: 1.25, limit_distance: 50, stop_distance: 50
193
- ig.working_orders['deal_id'].delete
193
+ working_order = ig.working_orders['deal_id']
194
+ working_order.update level: 1.25, limit_distance: 50, stop_distance: 50
195
+ working_order.reload
196
+ working_order.delete
194
197
 
195
198
  # Markets
196
199
  ig.markets.hierarchy
197
200
  ig.markets.search 'EURUSD'
198
201
  ig.markets.find 'CS.D.EURUSD.CFD.IP', 'IX.D.DOW.IFD.IP'
199
- ig.markets['CS.D.EURUSD.CFD.IP'].historical_prices resolution: :hour, number: 48
200
- ig.markets['CS.D.EURUSD.CFD.IP'].historical_prices resolution: :second, from: Time.now - 120,
201
- to: Time.now - 60
202
+ market = ig.markets['CS.D.EURUSD.CFD.IP']
203
+ market.historical_prices resolution: :hour, number: 48
204
+ market.historical_prices resolution: :second, from: Time.now - 120, to: Time.now - 60
202
205
 
203
206
  # Watchlists
204
207
  ig.watchlists.all
205
208
  ig.watchlists.create 'New Watchlist', 'CS.D.EURUSD.CFD.IP', 'UA.D.AAPL.CASH.IP'
206
- ig.watchlists['watchlist_id']
207
- ig.watchlists['watchlist_id'].markets
208
- ig.watchlists['watchlist_id'].add_market 'CS.D.EURUSD.CFD.IP'
209
- ig.watchlists['watchlist_id'].remove_market 'CS.D.EURUSD.CFD.IP'
210
- ig.watchlists['watchlist_id'].delete
209
+ watchlist = ig.watchlists['watchlist_id']
210
+ watchlist.markets
211
+ watchlist.add_market 'CS.D.EURUSD.CFD.IP'
212
+ watchlist.remove_market 'CS.D.EURUSD.CFD.IP'
213
+ watchlist.delete
211
214
 
212
215
  # Client sentiment
213
- ig.client_sentiment['EURUSD']
214
- ig.client_sentiment['EURUSD'].related_sentiments
216
+ client_sentiment = ig.client_sentiment['EURUSD']
217
+ client_sentiment.related_sentiments
218
+ client_sentiment.reload
215
219
 
216
220
  # Miscellaneous
217
221
  ig.applications
data/lib/ig_markets.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'base64'
2
2
  require 'colorize'
3
3
  require 'date'
4
+ require 'json'
4
5
  require 'pry'
5
6
  require 'rest-client'
6
7
  require 'terminal-table'
@@ -19,5 +19,10 @@ module IGMarkets
19
19
  attribute :currency, String, regex: Regex::CURRENCY
20
20
  attribute :preferred, Boolean
21
21
  attribute :status, Symbol, allowed_values: [:disabled, :enabled, :suspended_from_dealing]
22
+
23
+ # Reloads this account's attributes by re-querying the IG Markets API.
24
+ def reload
25
+ self.attributes = @dealing_platform.account.all.detect { |a| a.account_id == account_id }.attributes
26
+ end
22
27
  end
23
28
  end
@@ -8,7 +8,7 @@ module IGMarkets
8
8
  class Action < Model
9
9
  attribute :action_type, Symbol, allowed_values: [:limit_order_amended, :limit_order_deleted,
10
10
  :limit_order_filled, :limit_order_opened, :limit_order_rolled,
11
- :position_closed, :position_deleted, :position_opended,
11
+ :position_closed, :position_deleted, :position_opened,
12
12
  :position_partially_closed, :position_rolled,
13
13
  :stop_limit_amended, :stop_order_amended, :stop_order_deleted,
14
14
  :stop_order_filled, :stop_order_opened, :stop_order_rolled,
@@ -74,6 +74,18 @@ module IGMarkets
74
74
  end
75
75
  end
76
76
 
77
+ desc 'delete-all', 'Deletes all working orders'
78
+
79
+ def delete_all
80
+ Main.begin_session(options) do |dealing_platform|
81
+ dealing_platform.working_orders.all.each do |working_order|
82
+ deal_reference = working_order.delete
83
+
84
+ Main.report_deal_confirmation deal_reference
85
+ end
86
+ end
87
+ end
88
+
77
89
  private
78
90
 
79
91
  ATTRIBUTES = [:currency_code, :direction, :epic, :expiry, :force_open, :good_till_date, :guaranteed_stop, :level,
@@ -66,11 +66,13 @@ module IGMarkets
66
66
  end
67
67
 
68
68
  def table_title(watchlist)
69
- title = "#{watchlist.name} (id: #{watchlist.id}"
70
- title << ', editable' if watchlist.editable
71
- title << ', deleteable' if watchlist.deleteable
72
- title << ', default' if watchlist.default_system_watchlist
73
- title << ')'
69
+ details = ["id: #{watchlist.id}"]
70
+
71
+ details << :default if watchlist.default_system_watchlist
72
+ details << :editable if watchlist.editable
73
+ details << :deleteable if watchlist.deleteable
74
+
75
+ "#{watchlist.name} (#{details.join ', '})"
74
76
  end
75
77
  end
76
78
  end
@@ -27,9 +27,6 @@ module IGMarkets
27
27
  types = details.actions.map(&:action_type).uniq
28
28
  types.delete :unknown
29
29
 
30
- # Fix a typo in one of the values
31
- types.map! { |v| v == :position_opended ? :position_opened : v }
32
-
33
30
  types.map { |v| format_cell_value v }.join ', '
34
31
  end
35
32
  end
@@ -6,6 +6,11 @@ module IGMarkets
6
6
  attribute :market_id
7
7
  attribute :short_position_percentage, Float
8
8
 
9
+ # Reloads this client sentiment's attributes by re-querying the IG Markets API.
10
+ def reload
11
+ self.attributes = @dealing_platform.client_sentiment[market_id].attributes
12
+ end
13
+
9
14
  # Returns client sentiments for markets that are related to this one.
10
15
  #
11
16
  # @return [Array<ClientSentiment>]
@@ -69,10 +69,8 @@ module IGMarkets
69
69
  # the position creation.
70
70
  def create(attributes)
71
71
  model = PositionCreateAttributes.new attributes
72
- model.validate
73
72
 
74
- payload = PayloadFormatter.format model
75
- payload[:expiry] ||= '-'
73
+ payload = PayloadFormatter.format model, expiry: '-'
76
74
 
77
75
  @dealing_platform.session.post('positions/otc', payload, API_V2).fetch(:deal_reference)
78
76
  end
@@ -101,8 +99,17 @@ module IGMarkets
101
99
 
102
100
  def initialize(attributes = {})
103
101
  super
104
-
105
102
  set_defaults
103
+ validate
104
+ end
105
+
106
+ private
107
+
108
+ def set_defaults
109
+ self.force_open = false if force_open.nil?
110
+ self.guaranteed_stop = false if guaranteed_stop.nil?
111
+ self.order_type ||= :market
112
+ self.time_in_force = :execute_and_eliminate if order_type == :market
106
113
  end
107
114
 
108
115
  # Runs a series of validations on this model's attributes to check whether it is ready to be sent to the IG
@@ -115,15 +122,6 @@ module IGMarkets
115
122
  validate_guaranteed_stop_constraints
116
123
  end
117
124
 
118
- private
119
-
120
- def set_defaults
121
- self.force_open = false if force_open.nil?
122
- self.guaranteed_stop = false if guaranteed_stop.nil?
123
- self.order_type ||= :market
124
- self.time_in_force = :execute_and_eliminate if order_type == :market
125
- end
126
-
127
125
  # Checks that all required attributes for position creation are present.
128
126
  def validate_required_attributes
129
127
  required = [:currency_code, :direction, :epic, :force_open, :guaranteed_stop, :order_type, :size,
@@ -63,11 +63,8 @@ module IGMarkets
63
63
  # the working order creation.
64
64
  def create(attributes)
65
65
  model = WorkingOrderCreateAttributes.new attributes
66
- model.validate
67
66
 
68
- payload = PayloadFormatter.format model
69
-
70
- payload[:expiry] ||= '-'
67
+ payload = PayloadFormatter.format model, expiry: '-'
71
68
 
72
69
  @dealing_platform.session.post('workingorders/otc', payload, API_V2).fetch :deal_reference
73
70
  end
@@ -92,8 +89,16 @@ module IGMarkets
92
89
 
93
90
  def initialize(attributes)
94
91
  super
95
-
96
92
  set_defaults
93
+ validate
94
+ end
95
+
96
+ private
97
+
98
+ def set_defaults
99
+ self.force_open = false if force_open.nil?
100
+ self.guaranteed_stop = false if guaranteed_stop.nil?
101
+ self.time_in_force = good_till_date ? :good_till_date : :good_till_cancelled
97
102
  end
98
103
 
99
104
  # Runs a series of validations on this model's attributes to check whether it is ready to be sent to the IG
@@ -110,14 +115,6 @@ module IGMarkets
110
115
 
111
116
  raise ArgumentError, 'Do not specify both stop_distance and stop_level options' if stop_distance && stop_level
112
117
  end
113
-
114
- private
115
-
116
- def set_defaults
117
- self.force_open = false if force_open.nil?
118
- self.guaranteed_stop = false if guaranteed_stop.nil?
119
- self.time_in_force = good_till_date ? :good_till_date : :good_till_cancelled
120
- end
121
118
  end
122
119
 
123
120
  private_constant :WorkingOrderCreateAttributes
@@ -43,6 +43,11 @@ module IGMarkets
43
43
  attribute :instrument, Instrument
44
44
  attribute :snapshot, Snapshot
45
45
 
46
+ # Reloads this market's attributes by re-querying the IG Markets API.
47
+ def reload
48
+ self.attributes = @dealing_platform.markets[instrument.epic].attributes
49
+ end
50
+
46
51
  # Returns historical prices for this market at a given resolution, either the most recent prices by specifying the
47
52
  # `:number` option, or those from a date range by specifying the `:from` and `:to` options.
48
53
  #
@@ -51,6 +51,15 @@ module IGMarkets
51
51
  "#<#{self.class.name} #{formatted_attributes.join ', '}>"
52
52
  end
53
53
 
54
+ # Mass assigns the passed attributes to this model.
55
+ #
56
+ # @param [Hash] new_attributes The attributes to assign on this model.
57
+ def attributes=(new_attributes)
58
+ new_attributes.each do |name, value|
59
+ send "#{name}=", value
60
+ end
61
+ end
62
+
54
63
  private
55
64
 
56
65
  # Returns the {#inspect} string for the given value.
@@ -9,10 +9,11 @@ module IGMarkets
9
9
  # available `:format` option.
10
10
  #
11
11
  # @param [Model] model The model instance to convert attributes for.
12
+ # @param [Hash] defaults The default attribute values to return, can be overridden by values set on `model`.
12
13
  #
13
14
  # @return [Hash] The resulting attributes hash.
14
- def format(model)
15
- model.class.defined_attributes.each_with_object({}) do |(name, options), formatted|
15
+ def format(model, defaults = {})
16
+ model.class.defined_attributes.each_with_object(defaults.dup) do |(name, options), formatted|
16
17
  value = model.send name
17
18
 
18
19
  next if value.nil?
@@ -59,6 +59,11 @@ module IGMarkets
59
59
  price_delta * size * contract_size
60
60
  end
61
61
 
62
+ # Reloads this position's attributes by re-querying the IG Markets API.
63
+ def reload
64
+ self.attributes = @dealing_platform.positions[deal_id].attributes
65
+ end
66
+
62
67
  # Closes this position. If called with no options then this position will be fully closed at current market prices,
63
68
  # partial closes and greater control over the close conditions can be achieved by using the relevant options.
64
69
  #
@@ -1,4 +1,4 @@
1
1
  module IGMarkets
2
2
  # The version of this gem.
3
- VERSION = '0.13'.freeze
3
+ VERSION = '0.14'.freeze
4
4
  end
@@ -21,6 +21,11 @@ module IGMarkets
21
21
 
22
22
  deprecated_attribute :created_date, :good_till_date_iso
23
23
 
24
+ # Reloads this working order's attributes by re-querying the IG Markets API.
25
+ def reload
26
+ self.attributes = @dealing_platform.working_orders[deal_id].attributes
27
+ end
28
+
24
29
  # Deletes this working order.
25
30
  #
26
31
  # @return [String] The deal reference of the deletion operation. Use {DealingPlatform#deal_confirmation} to check
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ig_markets
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.13'
4
+ version: '0.14'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Viney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-22 00:00:00.000000000 Z
11
+ date: 2016-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: '0.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.7'
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pry
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.10'
33
+ version: 0.10.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.10'
40
+ version: 0.10.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rest-client
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.8'
47
+ version: '2.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.8'
54
+ version: '2.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: terminal-table
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.5'
61
+ version: '1.6'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.5'
68
+ version: '1.6'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: thor
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +80,34 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.19'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: codeclimate-test-reporter
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0.5'
103
+ version: '0.6'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0.5'
110
+ version: '0.6'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: factory_girl
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -142,42 +156,42 @@ dependencies:
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '3.4'
159
+ version: '3.5'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '3.4'
166
+ version: '3.5'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rspec-mocks
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - "~>"
158
172
  - !ruby/object:Gem::Version
159
- version: '3.4'
173
+ version: '3.5'
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - "~>"
165
179
  - !ruby/object:Gem::Version
166
- version: '3.4'
180
+ version: '3.5'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: rubocop
169
183
  requirement: !ruby/object:Gem::Requirement
170
184
  requirements:
171
185
  - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: '0.40'
187
+ version: '0.41'
174
188
  type: :development
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
- version: '0.40'
194
+ version: '0.41'
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: yard
183
197
  requirement: !ruby/object:Gem::Requirement