ig_markets 0.14 → 0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +1 -0
- data/lib/ig_markets/cli/commands/self_test_command.rb +142 -0
- data/lib/ig_markets/market_hierarchy_result.rb +14 -0
- data/lib/ig_markets/session.rb +18 -11
- data/lib/ig_markets/version.rb +1 -1
- data/lib/ig_markets.rb +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4205e8e7a404222272416344c5f21e912de43256
|
4
|
+
data.tar.gz: 55595208ec8a08d8941d68387c6c61e19c436d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 230f8eb850b639d3a6fa479cd42101ecd89c901382951adaa5a69d064029623a30c042cbe9bc44ee16d11b0e1cf50c034dc99e0aa43f3081063b27cda4a797ec
|
7
|
+
data.tar.gz: 20991fd83b740be9a1bcc36ce2c112a7a63b2070adc9cf736617a130350b9810abe33663214b1b45889b3e53bda3741cc37f633068f1284cab30a09088d36d9b
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
# IG Markets Changelog
|
2
2
|
|
3
|
+
### 0.15 — July 11, 2016
|
4
|
+
|
5
|
+
- Added `ig_markets self-test` command that can be run under a demo account in order to test the library against the
|
6
|
+
live IG Markets API
|
7
|
+
- If the API key or account's traffic allowance is exceeded then `IGMarkets::Session` now automatically retries the
|
8
|
+
request after a five second pause
|
9
|
+
- Added `IGMarkets::MarketHierarchyResult::HierarchyNode#markets` and
|
10
|
+
`IGMarkets::MarketHierarchyResult::HierarchyNode#nodes` methods
|
11
|
+
|
3
12
|
### 0.14 — July 2, 2016
|
4
13
|
|
5
14
|
- Added `delete-all` subcommand to `ig_markets orders`
|
6
15
|
- Added a `#reload` method that reloads a model's attributes in-place to `IGMarkets::Account`,
|
7
16
|
`IGMarkets::ClientSentiment`, `IGMarkets::Market`, `IGMarkets::Position` and `IGMarkets::WorkingOrder`
|
17
|
+
- Support mass assignment of attributes on models
|
18
|
+
- Fixed a compatibility issue with recent IG API changes
|
8
19
|
|
9
20
|
### 0.13 — June 22, 2016
|
10
21
|
|
data/README.md
CHANGED
@@ -85,6 +85,7 @@ commands and their subcommands is:
|
|
85
85
|
- `ig_markets positions close-all [...]`
|
86
86
|
- `ig_markets prices --epic EPIC --resolution RESOLUTION ...`
|
87
87
|
- `ig_markets search QUERY [--type TYPE]`
|
88
|
+
- `ig_markets self-test`
|
88
89
|
- `ig_markets sentiment MARKET`
|
89
90
|
- `ig_markets sprints [list]`
|
90
91
|
- `ig_markets sprints create ...`
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module IGMarkets
|
2
|
+
module CLI
|
3
|
+
# Implements the `ig_markets self-test` command.
|
4
|
+
class Main < Thor
|
5
|
+
desc 'self-test', 'Runs a self-test of this application against the live IG Markets API (demo accounts only)'
|
6
|
+
|
7
|
+
def self_test
|
8
|
+
self.class.begin_session(options) do |dealing_platform|
|
9
|
+
raise 'Error: self-tests must be run on a demo account' unless dealing_platform.session.platform == :demo
|
10
|
+
|
11
|
+
run_self_test dealing_platform
|
12
|
+
|
13
|
+
dealing_platform.sign_out
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def run_self_test(dealing_platform)
|
20
|
+
test_markets dealing_platform
|
21
|
+
test_positions dealing_platform
|
22
|
+
test_sprint_market_positions dealing_platform
|
23
|
+
test_working_orders dealing_platform
|
24
|
+
test_watchlists dealing_platform
|
25
|
+
test_client_sentiment dealing_platform
|
26
|
+
test_account_methods dealing_platform
|
27
|
+
test_applications dealing_platform
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_markets(dealing_platform)
|
31
|
+
dealing_platform.markets.hierarchy '264134' # ID of the main 'Forex' node
|
32
|
+
dealing_platform.markets.search 'EURUSD'
|
33
|
+
@eur_usd = dealing_platform.markets['CS.D.EURUSD.CFD.IP']
|
34
|
+
@eur_usd_sprint = dealing_platform.markets['FM.D.EURUSD24.EURUSD24.IP']
|
35
|
+
@eur_usd.historical_prices resolution: :hour, number: 1
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_positions(dealing_platform)
|
39
|
+
test_position_create dealing_platform
|
40
|
+
test_position_update
|
41
|
+
test_position_close dealing_platform
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_position_create(dealing_platform)
|
45
|
+
deal_reference = dealing_platform.positions.create currency_code: 'USD', direction: :buy,
|
46
|
+
epic: 'CS.D.EURUSD.CFD.IP', size: 2
|
47
|
+
|
48
|
+
@position = dealing_platform.positions[dealing_platform.deal_confirmation(deal_reference).deal_id]
|
49
|
+
|
50
|
+
raise 'Error: failed creating position' unless @position
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_position_update
|
54
|
+
stop_level = @position.level - 0.01
|
55
|
+
|
56
|
+
@position.update stop_level: stop_level
|
57
|
+
@position.reload
|
58
|
+
|
59
|
+
update_worked = (@position.stop_level - stop_level).abs < 0.001
|
60
|
+
|
61
|
+
raise 'Error: failed updating position' unless update_worked
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_position_close(dealing_platform)
|
65
|
+
@position.close
|
66
|
+
|
67
|
+
raise 'Error: failed closing position' if dealing_platform.positions[@position.deal_id]
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_sprint_market_positions(dealing_platform)
|
71
|
+
deal_reference = dealing_platform.sprint_market_positions.create direction: :buy,
|
72
|
+
epic: 'FM.D.EURUSD24.EURUSD24.IP',
|
73
|
+
expiry_period: :twenty_minutes, size: 100
|
74
|
+
|
75
|
+
deal_confirmation = dealing_platform.deal_confirmation deal_reference
|
76
|
+
|
77
|
+
sprint_market_position = dealing_platform.sprint_market_positions[deal_confirmation.deal_id]
|
78
|
+
|
79
|
+
raise 'Error: failed creating sprint market position' unless sprint_market_position
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_working_orders(dealing_platform)
|
83
|
+
test_working_order_create dealing_platform
|
84
|
+
test_working_order_update dealing_platform
|
85
|
+
test_working_order_delete dealing_platform
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_working_order_create(dealing_platform)
|
89
|
+
deal_reference = dealing_platform.working_orders.create currency_code: 'USD', direction: :buy,
|
90
|
+
epic: 'CS.D.EURUSD.CFD.IP', type: :limit,
|
91
|
+
level: @eur_usd.snapshot.bid - 0.1, size: 1
|
92
|
+
|
93
|
+
@working_order = dealing_platform.working_orders[dealing_platform.deal_confirmation(deal_reference).deal_id]
|
94
|
+
|
95
|
+
raise 'Error: failed creating working order' unless @working_order
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_working_order_update(dealing_platform)
|
99
|
+
new_level = @eur_usd.snapshot.bid - 1
|
100
|
+
|
101
|
+
@working_order.update level: new_level
|
102
|
+
@working_order.reload
|
103
|
+
|
104
|
+
update_worked = (new_level - dealing_platform.working_orders[@working_order.deal_id].order_level).abs < 0.01
|
105
|
+
|
106
|
+
raise 'Error: failed updating working order' unless update_worked
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_working_order_delete(dealing_platform)
|
110
|
+
@working_order.delete
|
111
|
+
|
112
|
+
raise 'Error: failed deleting working order' if dealing_platform.working_orders[@working_order.deal_id]
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_watchlists(dealing_platform)
|
116
|
+
watchlist = dealing_platform.watchlists.create SecureRandom.hex, 'UA.D.AAPL.CASH.IP'
|
117
|
+
watchlist = dealing_platform.watchlists[watchlist.id]
|
118
|
+
watchlist.markets
|
119
|
+
watchlist.add_market 'CS.D.EURUSD.CFD.IP'
|
120
|
+
watchlist.remove_market 'CS.D.EURUSD.CFD.IP'
|
121
|
+
watchlist.delete
|
122
|
+
|
123
|
+
raise 'Error: failed deleting watchlist' if dealing_platform.watchlists[watchlist.id]
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_account_methods(dealing_platform)
|
127
|
+
dealing_platform.account.all
|
128
|
+
dealing_platform.account.activities from: Date.today - 14
|
129
|
+
dealing_platform.account.transactions from: Date.today - 14
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_client_sentiment(dealing_platform)
|
133
|
+
client_sentiment = dealing_platform.client_sentiment['EURUSD']
|
134
|
+
client_sentiment.related_sentiments
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_applications(dealing_platform)
|
138
|
+
dealing_platform.applications
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -5,6 +5,20 @@ module IGMarkets
|
|
5
5
|
class HierarchyNode < Model
|
6
6
|
attribute :id
|
7
7
|
attribute :name
|
8
|
+
|
9
|
+
# Returns an array of the markets under this node in the market hierarchy.
|
10
|
+
#
|
11
|
+
# @return [Array<MarketOverview>]
|
12
|
+
def markets
|
13
|
+
@dealing_platform.markets.hierarchy(id).markets
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns an array of the child nodes under this node in the market hierarchy.
|
17
|
+
#
|
18
|
+
# @return [Array<HierarchyNode>]
|
19
|
+
def nodes
|
20
|
+
@nodes ||= @dealing_platform.markets.hierarchy(id).nodes
|
21
|
+
end
|
8
22
|
end
|
9
23
|
|
10
24
|
attribute :markets, MarketOverview
|
data/lib/ig_markets/session.rb
CHANGED
@@ -101,10 +101,7 @@ module IGMarkets
|
|
101
101
|
|
102
102
|
private
|
103
103
|
|
104
|
-
HOST_URLS = {
|
105
|
-
demo: 'https://demo-api.ig.com/gateway/deal/',
|
106
|
-
live: 'https://api.ig.com/gateway/deal/'
|
107
|
-
}.freeze
|
104
|
+
HOST_URLS = { demo: 'https://demo-api.ig.com/gateway/deal/', live: 'https://api.ig.com/gateway/deal/' }.freeze
|
108
105
|
|
109
106
|
def validate_authentication
|
110
107
|
%i(username password api_key).each do |attribute|
|
@@ -163,24 +160,34 @@ module IGMarkets
|
|
163
160
|
rescue RestClient::Exception => exception
|
164
161
|
raise RequestFailedError, exception.message unless exception.response
|
165
162
|
|
166
|
-
return exception.response unless
|
163
|
+
return exception.response unless should_retry_request? exception.response, options
|
167
164
|
|
168
|
-
sign_in
|
169
165
|
execute_request options.merge(retry: true)
|
170
166
|
rescue SocketError => socket_error
|
171
167
|
raise RequestFailedError, socket_error
|
172
168
|
end
|
173
169
|
|
174
|
-
def
|
175
|
-
ResponseParser.parse_json(response.body)[:error_code]
|
170
|
+
def should_retry_request?(response, options)
|
171
|
+
error_code = ResponseParser.parse_json(response.body)[:error_code]
|
172
|
+
|
173
|
+
if error_code == 'error.security.client-token-invalid' && !options[:retry]
|
174
|
+
sign_in
|
175
|
+
return true
|
176
|
+
end
|
177
|
+
|
178
|
+
if error_code =~ /^error\.public-api\.exceeded-(api-key|account)-allowance/
|
179
|
+
sleep 5
|
180
|
+
return true
|
181
|
+
end
|
182
|
+
|
183
|
+
false
|
176
184
|
end
|
177
185
|
|
178
186
|
def process_response(response)
|
179
187
|
result = ResponseParser.parse_json response.body
|
188
|
+
http_code = response.code
|
180
189
|
|
181
|
-
|
182
|
-
raise RequestFailedError.new(result[:error_code], response.code)
|
183
|
-
end
|
190
|
+
raise RequestFailedError.new(result[:error_code], http_code) unless http_code >= 200 && http_code < 300
|
184
191
|
|
185
192
|
result
|
186
193
|
end
|
data/lib/ig_markets/version.rb
CHANGED
data/lib/ig_markets.rb
CHANGED
@@ -4,6 +4,7 @@ require 'date'
|
|
4
4
|
require 'json'
|
5
5
|
require 'pry'
|
6
6
|
require 'rest-client'
|
7
|
+
require 'securerandom'
|
7
8
|
require 'terminal-table'
|
8
9
|
require 'thor'
|
9
10
|
|
@@ -60,6 +61,7 @@ require 'ig_markets/cli/commands/markets_command'
|
|
60
61
|
require 'ig_markets/cli/commands/performance_command'
|
61
62
|
require 'ig_markets/cli/commands/prices_command'
|
62
63
|
require 'ig_markets/cli/commands/search_command'
|
64
|
+
require 'ig_markets/cli/commands/self_test_command'
|
63
65
|
require 'ig_markets/cli/commands/sentiment_command'
|
64
66
|
require 'ig_markets/cli/commands/transactions_command'
|
65
67
|
require 'ig_markets/cli/tables/table'
|
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.
|
4
|
+
version: '0.15'
|
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-07-
|
11
|
+
date: 2016-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -233,6 +233,7 @@ files:
|
|
233
233
|
- lib/ig_markets/cli/commands/positions_command.rb
|
234
234
|
- lib/ig_markets/cli/commands/prices_command.rb
|
235
235
|
- lib/ig_markets/cli/commands/search_command.rb
|
236
|
+
- lib/ig_markets/cli/commands/self_test_command.rb
|
236
237
|
- lib/ig_markets/cli/commands/sentiment_command.rb
|
237
238
|
- lib/ig_markets/cli/commands/sprints_command.rb
|
238
239
|
- lib/ig_markets/cli/commands/transactions_command.rb
|