ig_markets 0.14 → 0.15
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 +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
|