ig_markets 0.11 → 0.12
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 +14 -1
- data/README.md +10 -7
- data/lib/ig_markets/activity.rb +37 -13
- data/lib/ig_markets/cli/commands/activities_command.rb +1 -14
- data/lib/ig_markets/cli/commands/orders_command.rb +6 -2
- data/lib/ig_markets/cli/commands/positions_command.rb +1 -1
- data/lib/ig_markets/cli/commands/transactions_command.rb +1 -1
- data/lib/ig_markets/cli/main.rb +32 -2
- data/lib/ig_markets/cli/tables/activities_table.rb +12 -4
- data/lib/ig_markets/cli/tables/market_overviews_table.rb +2 -2
- data/lib/ig_markets/cli/tables/positions_table.rb +7 -1
- data/lib/ig_markets/client_account_summary.rb +4 -3
- data/lib/ig_markets/deal_confirmation.rb +22 -14
- data/lib/ig_markets/dealing_platform/account_methods.rb +13 -9
- data/lib/ig_markets/dealing_platform/sprint_market_position_methods.rb +2 -2
- data/lib/ig_markets/dealing_platform/working_order_methods.rb +42 -21
- data/lib/ig_markets/dealing_platform.rb +2 -0
- data/lib/ig_markets/instrument.rb +4 -4
- data/lib/ig_markets/market.rb +4 -4
- data/lib/ig_markets/model/typecasters.rb +18 -10
- data/lib/ig_markets/model.rb +20 -3
- data/lib/ig_markets/payload_formatter.rb +4 -4
- data/lib/ig_markets/position.rb +2 -2
- data/lib/ig_markets/transaction.rb +1 -1
- data/lib/ig_markets/version.rb +1 -1
- data/lib/ig_markets/working_order.rb +29 -6
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e50f2a597b16e6d091f0eff038350ec67847f60
|
4
|
+
data.tar.gz: 769b2056a2a1db136b05947fccbe42127ff54809
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 091827f393098b7b5b19df4686832ce96dd630038aee32ab15af550bfbdae5c4236bb238993198c9caae96273d02b83d8f34dd8d287dc4456b068e974969a3f0
|
7
|
+
data.tar.gz: 4ee120e6a912fdeef9ee98752c15559800ee3b406f168d1bb68524ee213b42a92afb7638dcf1675747bab6e6ed634f2a7030a41cb009b2235ff9ef5f090d17ad
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# IG Markets Changelog
|
2
2
|
|
3
|
+
### 0.12 - June 21, 2016
|
4
|
+
|
5
|
+
- Unrecognized attributes returned by the IG Markets API now trigger a warning rather than causing an error, this makes
|
6
|
+
the library able to handle new return values being added to existing APIs
|
7
|
+
- Upgraded to version 3 of the activities API, which significantly changes the structure of `IGMarkets::Activity`
|
8
|
+
- Accept "`DFB`" (daily funded bet) on instrument periods, it is silently converted to `nil`
|
9
|
+
- Correctly handle instrument periods that are formatted as `MMM-YY`
|
10
|
+
- Stops and limits can now be specified as levels rather than distances when creating and updating working orders
|
11
|
+
- Report profit/loss information when printing deal confirmations
|
12
|
+
- Renamed `--print-requests` option to `--verbose`
|
13
|
+
- The `--currency-code` option to `ig_markets positions create` and `ig_markets orders create` no longer defaults to
|
14
|
+
`USD` and must be specified explicitly
|
15
|
+
|
3
16
|
### 0.11 — May 23, 2016
|
4
17
|
|
5
18
|
- `IGMarkets::DealingPlatform::AccountMethods#activities` and `IGMarkets::DealingPlatform::AccountMethods#transactions`
|
@@ -7,7 +20,7 @@
|
|
7
20
|
of results returned by a single request at 500
|
8
21
|
- `IGMarkets::DealingPlatform::AccountMethods#activities` and `IGMarkets::DealingPlatform::AccountMethods#transactions`
|
9
22
|
no longer take a `:days` option, and their `:to` option defaults to today's date if it is omitted
|
10
|
-
- Accept "`DFB`" (
|
23
|
+
- Accept "`DFB`" (daily funded bet) on instrument expiries, it is silently converted to `nil`
|
11
24
|
- Instrument high and low is now shown in the `ig_markets positions list` command
|
12
25
|
|
13
26
|
### 0.10 — May 10, 2016
|
data/README.md
CHANGED
@@ -108,7 +108,7 @@ ig_markets search EURUSD --type currencies
|
|
108
108
|
ig_markets positions --aggregate
|
109
109
|
|
110
110
|
# Create a EURUSD long position of size 2
|
111
|
-
ig_markets positions create --direction buy --epic CS.D.EURUSD.CFD.IP --size 2
|
111
|
+
ig_markets positions create --direction buy --epic CS.D.EURUSD.CFD.IP --size 2 --currency-code USD
|
112
112
|
|
113
113
|
# Change the limit and stop levels for an existing position
|
114
114
|
ig_markets positions update DEAL-ID --limit-level 1.15 --stop-level 1.10
|
@@ -120,16 +120,18 @@ ig_markets positions close DEAL-ID
|
|
120
120
|
ig_markets positions close DEAL-ID --size 1
|
121
121
|
|
122
122
|
# Create a EURUSD sprint market short position of size 100 that expires in 20 minutes
|
123
|
-
ig_markets sprints create --direction sell --epic FM.D.EURUSD24.EURUSD24.IP --expiry-period 20
|
123
|
+
ig_markets sprints create --direction sell --epic FM.D.EURUSD24.EURUSD24.IP --expiry-period 20
|
124
|
+
--size 100
|
124
125
|
|
125
126
|
# Create a working order to buy 1 unit of EURUSD at the level 1.1
|
126
127
|
ig_markets orders create --direction buy --epic CS.D.EURUSD.CFD.IP --level 1.1 --size 1 --type limit
|
128
|
+
--currency-code USD
|
127
129
|
|
128
130
|
# Print daily prices for EURUSD from the last two weeks
|
129
131
|
ig_markets prices --epic CS.D.EURUSD.CFD.IP --resolution day --number 14
|
130
132
|
|
131
|
-
# Log in and
|
132
|
-
ig_markets console --
|
133
|
+
# Log in and open a Ruby console which can be used to query the IG API, printing all REST requests
|
134
|
+
ig_markets console --verbose
|
133
135
|
```
|
134
136
|
|
135
137
|
## Usage — Library
|
@@ -176,8 +178,8 @@ ig.sprint_market_positions.create direction: :buy, epic: 'FM.D.EURUSD24.EURUSD24
|
|
176
178
|
|
177
179
|
# Working orders
|
178
180
|
ig.working_orders.all
|
179
|
-
ig.working_orders.create currency_code: 'USD', direction: :buy, epic: 'CS.D.EURUSD.CFD.IP',
|
180
|
-
size: 1, type: :limit
|
181
|
+
ig.working_orders.create currency_code: 'USD', direction: :buy, epic: 'CS.D.EURUSD.CFD.IP',
|
182
|
+
level: 0.99, size: 1, type: :limit
|
181
183
|
ig.working_orders['deal_id']
|
182
184
|
ig.working_orders['deal_id'].update level: 1.25, limit_distance: 50, stop_distance: 50
|
183
185
|
ig.working_orders['deal_id'].delete
|
@@ -187,7 +189,8 @@ ig.markets.hierarchy
|
|
187
189
|
ig.markets.search 'EURUSD'
|
188
190
|
ig.markets['CS.D.EURUSD.CFD.IP']
|
189
191
|
ig.markets['CS.D.EURUSD.CFD.IP'].historical_prices resolution: :hour, number: 48
|
190
|
-
ig.markets['CS.D.EURUSD.CFD.IP'].historical_prices resolution: :second, from: Time.now - 120,
|
192
|
+
ig.markets['CS.D.EURUSD.CFD.IP'].historical_prices resolution: :second, from: Time.now - 120,
|
193
|
+
to: Time.now - 60
|
191
194
|
|
192
195
|
# Watchlists
|
193
196
|
ig.watchlists.all
|
data/lib/ig_markets/activity.rb
CHANGED
@@ -2,21 +2,45 @@ module IGMarkets
|
|
2
2
|
# Contains details on a single activity that occurred on an IG Markets account. Returned by
|
3
3
|
# {DealingPlatform::AccountMethods#activities}.
|
4
4
|
class Activity < Model
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# Contains additional details on an activity. Returned by {#details}.
|
6
|
+
class Details < Model
|
7
|
+
# Contains details on the actions that were performed by an activity. Returned by {#actions}.
|
8
|
+
class Action < Model
|
9
|
+
attribute :action_type, Symbol, allowed_values: [:limit_order_amended, :limit_order_deleted,
|
10
|
+
:limit_order_filled, :limit_order_opened, :limit_order_rolled,
|
11
|
+
:position_closed, :position_deleted, :position_opended,
|
12
|
+
:position_partially_closed, :position_rolled,
|
13
|
+
:stop_limit_amended, :stop_order_amended, :stop_order_deleted,
|
14
|
+
:stop_order_filled, :stop_order_opened, :stop_order_rolled,
|
15
|
+
:unknown, :working_order_deleted]
|
16
|
+
attribute :affected_deal_id
|
17
|
+
end
|
18
|
+
|
19
|
+
attribute :actions, Action
|
20
|
+
attribute :currency
|
21
|
+
attribute :deal_reference
|
22
|
+
attribute :direction, Symbol, allowed_values: [:buy, :sell]
|
23
|
+
attribute :good_till_date
|
24
|
+
attribute :guaranteed_stop, Boolean
|
25
|
+
attribute :level, Float, nil_if: 0
|
26
|
+
attribute :limit_distance, Fixnum
|
27
|
+
attribute :limit_level, Float, nil_if: 0
|
28
|
+
attribute :market_name
|
29
|
+
attribute :size
|
30
|
+
attribute :stop_distance, Fixnum
|
31
|
+
attribute :stop_level, Float, nil_if: 0
|
32
|
+
attribute :trailing_step, Float, nil_if: 0
|
33
|
+
attribute :trailing_stop_distance, Fixnum
|
34
|
+
end
|
35
|
+
|
36
|
+
attribute :channel, Symbol, allowed_values: [:dealer, :mobile, :public_fix_api, :public_web_api, :system, :web]
|
10
37
|
attribute :date, Time, format: '%FT%T'
|
11
38
|
attribute :deal_id
|
39
|
+
attribute :description
|
40
|
+
attribute :details, Details
|
12
41
|
attribute :epic, String, regex: Regex::EPIC
|
13
|
-
attribute :
|
14
|
-
attribute :
|
15
|
-
attribute :
|
16
|
-
attribute :period, String, nil_if: '-'
|
17
|
-
attribute :result
|
18
|
-
attribute :size
|
19
|
-
attribute :stop, String, nil_if: '-'
|
20
|
-
attribute :stop_type, String, nil_if: '-', allowed_values: %w(G N T(50))
|
42
|
+
attribute :period, Time, nil_if: %w(- DFB), format: ['%FT%T', '%b-%y']
|
43
|
+
attribute :status, Symbol, allowed_values: [:accepted, :rejected, :unknown]
|
44
|
+
attribute :type, Symbol, allowed_values: [:edit_stop_and_limit, :position, :system, :working_order]
|
21
45
|
end
|
22
46
|
end
|
@@ -24,7 +24,7 @@ module IGMarkets
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def gather_activities(dealing_platform)
|
27
|
-
result =
|
27
|
+
result = dealing_platform.account.activities(history_options).select do |activity|
|
28
28
|
activity_filter activity
|
29
29
|
end
|
30
30
|
|
@@ -45,19 +45,6 @@ module IGMarkets
|
|
45
45
|
'type' => :transaction_type
|
46
46
|
}.fetch options[:sort_by]
|
47
47
|
end
|
48
|
-
|
49
|
-
def gather_account_history(method_name, dealing_platform)
|
50
|
-
history_options = if options[:from]
|
51
|
-
from = Date.strptime options[:from], '%F'
|
52
|
-
to = from + options[:days]
|
53
|
-
|
54
|
-
{ from: from, to: to }
|
55
|
-
else
|
56
|
-
{ from: Date.today - options[:days] }
|
57
|
-
end
|
58
|
-
|
59
|
-
dealing_platform.account.send method_name, history_options
|
60
|
-
end
|
61
48
|
end
|
62
49
|
end
|
63
50
|
end
|
@@ -18,7 +18,7 @@ module IGMarkets
|
|
18
18
|
|
19
19
|
desc 'create', 'Creates a new working order'
|
20
20
|
|
21
|
-
option :currency_code,
|
21
|
+
option :currency_code, required: true, desc: 'The 3 character currency code, must be one of the instrument\'s ' \
|
22
22
|
'currencies'
|
23
23
|
option :direction, enum: %w(buy sell), required: true, desc: 'The trade direction'
|
24
24
|
option :epic, required: true, desc: 'The EPIC of the market to trade'
|
@@ -28,8 +28,10 @@ module IGMarkets
|
|
28
28
|
option :guaranteed_stop, type: :boolean, default: false, desc: 'Whether a guaranteed stop is required'
|
29
29
|
option :level, type: :numeric, required: true, desc: 'The level at which the order will be triggered'
|
30
30
|
option :limit_distance, type: :numeric, desc: 'The distance away in pips to place the limit'
|
31
|
+
option :limit_level, type: :numeric, desc: 'The level at which to place the limit'
|
31
32
|
option :size, type: :numeric, required: true, desc: 'The size of the order'
|
32
33
|
option :stop_distance, type: :numeric, desc: 'The distance away in pips to place the stop'
|
34
|
+
option :stop_level, type: :numeric, desc: 'The level at which to place the stop'
|
33
35
|
option :type, enum: %w(limit stop), required: true, desc: 'The order type'
|
34
36
|
|
35
37
|
def create
|
@@ -45,7 +47,9 @@ module IGMarkets
|
|
45
47
|
option :good_till_date, desc: 'The date that the order will live till, format: yyyy-mm-ddThh:mm(+|-)zz:zz'
|
46
48
|
option :level, type: :numeric, desc: 'The level at which the order will be triggered'
|
47
49
|
option :limit_distance, desc: 'The distance away in pips to place the limit'
|
50
|
+
option :limit_level, type: :numeric, desc: 'The level at which to place the limit'
|
48
51
|
option :stop_distance, desc: 'The distance away in pips to place the stop'
|
52
|
+
option :stop_level, type: :numeric, desc: 'The level at which to place the stop'
|
49
53
|
option :type, enum: %w(limit stop), desc: 'The order type'
|
50
54
|
|
51
55
|
def update(deal_id)
|
@@ -73,7 +77,7 @@ module IGMarkets
|
|
73
77
|
private
|
74
78
|
|
75
79
|
ATTRIBUTES = [:currency_code, :direction, :epic, :expiry, :force_open, :good_till_date, :guaranteed_stop, :level,
|
76
|
-
:limit_distance, :size, :stop_distance, :type].freeze
|
80
|
+
:limit_distance, :limit_level, :size, :stop_distance, :stop_level, :type].freeze
|
77
81
|
|
78
82
|
def working_order_attributes
|
79
83
|
attributes = Main.filter_options options, ATTRIBUTES
|
@@ -24,7 +24,7 @@ module IGMarkets
|
|
24
24
|
|
25
25
|
desc 'create', 'Creates a new position'
|
26
26
|
|
27
|
-
option :currency_code,
|
27
|
+
option :currency_code, required: true, desc: 'The 3 character currency code, must be one of the instrument\'s ' \
|
28
28
|
'currencies'
|
29
29
|
option :direction, required: true, enum: %w(buy sell), desc: 'The trade direction'
|
30
30
|
option :epic, required: true, desc: 'The EPIC of the market to trade'
|
@@ -31,7 +31,7 @@ module IGMarkets
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def gather_transactions(dealing_platform)
|
34
|
-
result =
|
34
|
+
result = dealing_platform.account.transactions(history_options).select do |transaction|
|
35
35
|
transaction_filter transaction
|
36
36
|
end
|
37
37
|
|
data/lib/ig_markets/cli/main.rb
CHANGED
@@ -7,7 +7,7 @@ module IGMarkets
|
|
7
7
|
class_option :password, required: true, desc: 'The password for the session'
|
8
8
|
class_option :api_key, required: true, desc: 'The API key for the session'
|
9
9
|
class_option :demo, type: :boolean, desc: 'Use the demo platform (default is production)'
|
10
|
-
class_option :
|
10
|
+
class_option :verbose, type: :boolean, desc: 'Whether to print the raw REST API requests and responses'
|
11
11
|
|
12
12
|
desc 'orders [SUBCOMAND=list ...]', 'Command for working with orders'
|
13
13
|
subcommand 'orders', Orders
|
@@ -21,6 +21,23 @@ module IGMarkets
|
|
21
21
|
desc 'watchlists [SUBCOMAND=list ...]', 'Command for working with watchlists'
|
22
22
|
subcommand 'watchlists', Watchlists
|
23
23
|
|
24
|
+
private
|
25
|
+
|
26
|
+
# Turns the `:days` and `:from` options into a hash with `:from` and `:to` keys that can be passed to
|
27
|
+
# {AccountMethods#activities} and {AccountMethods#transactions}.
|
28
|
+
#
|
29
|
+
# @return [Hash]
|
30
|
+
def history_options
|
31
|
+
if options[:from]
|
32
|
+
from = Date.strptime options[:from], '%F'
|
33
|
+
to = from + options[:days]
|
34
|
+
|
35
|
+
{ from: from, to: to }
|
36
|
+
else
|
37
|
+
{ from: Date.today - options[:days] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
24
41
|
class << self
|
25
42
|
# This is the initial entry point for the execution of the command-line client. It is responsible for reading
|
26
43
|
# any config files, implementing the --version/-v options, and then invoking the main application.
|
@@ -44,7 +61,7 @@ module IGMarkets
|
|
44
61
|
def begin_session(options)
|
45
62
|
platform = options[:demo] ? :demo : :production
|
46
63
|
|
47
|
-
RequestPrinter.enabled = true if options[:
|
64
|
+
RequestPrinter.enabled = true if options[:verbose]
|
48
65
|
|
49
66
|
@dealing_platform ||= DealingPlatform.new
|
50
67
|
@dealing_platform.sign_in options[:username], options[:password], options[:api_key], platform
|
@@ -143,8 +160,21 @@ Status: #{Format.symbol deal_confirmation.deal_status}
|
|
143
160
|
Result: #{Format.symbol deal_confirmation.status}
|
144
161
|
END
|
145
162
|
|
163
|
+
print_deal_confirmation_profit_loss deal_confirmation
|
164
|
+
|
146
165
|
puts "Reason: #{Format.symbol deal_confirmation.reason}" unless deal_confirmation.deal_status == :accepted
|
147
166
|
end
|
167
|
+
|
168
|
+
# Prints out the profit/loss for the passed deal confirmation if applicable.
|
169
|
+
#
|
170
|
+
# @param [DealConfirmation] deal_confirmation The deal confirmation to print out the profit/loss for.
|
171
|
+
def print_deal_confirmation_profit_loss(deal_confirmation)
|
172
|
+
return unless deal_confirmation.profit
|
173
|
+
|
174
|
+
profit = Format.currency deal_confirmation.profit, deal_confirmation.profit_currency
|
175
|
+
|
176
|
+
puts "Profit/loss: #{profit.colorize(deal_confirmation.profit < 0 ? :red : :green)}"
|
177
|
+
end
|
148
178
|
end
|
149
179
|
end
|
150
180
|
end
|
@@ -17,12 +17,20 @@ module IGMarkets
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def row(activity)
|
20
|
-
|
21
|
-
|
20
|
+
details = activity.details
|
21
|
+
|
22
|
+
[activity.date, activity.channel, activity.type, activity.status, activity.epic, details.market_name,
|
23
|
+
details.size, details.level, details.limit_level, details.stop_level, action_types(details)]
|
22
24
|
end
|
23
25
|
|
24
|
-
def
|
25
|
-
|
26
|
+
def action_types(details)
|
27
|
+
types = details.actions.map(&:action_type).uniq
|
28
|
+
types.delete :unknown
|
29
|
+
|
30
|
+
# Fix a typo in one of the values
|
31
|
+
types.map! { |v| v == :position_opended ? :position_opened : v }
|
32
|
+
|
33
|
+
types.map { |v| format_cell_value v }.join ', '
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -39,8 +39,8 @@ module IGMarkets
|
|
39
39
|
|
40
40
|
def market_status(market_overview)
|
41
41
|
{ closed: 'Closed', edits_only: 'Edits only', offline: 'Offline', on_auction: 'On auction',
|
42
|
-
on_auction_no_edits: 'On auction no edits', suspended: 'Suspended', tradeable: 'Tradeable'
|
43
|
-
|
42
|
+
on_auction_no_edits: 'On auction no edits', suspended: 'Suspended', tradeable: 'Tradeable' }
|
43
|
+
.fetch market_overview.market_status
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -84,7 +84,13 @@ module IGMarkets
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def combine_position_deal_ids(positions)
|
87
|
-
|
87
|
+
lines = []
|
88
|
+
|
89
|
+
positions.map(&:deal_id).each_slice(2) do |deal_ids|
|
90
|
+
lines << deal_ids.join(', ')
|
91
|
+
end
|
92
|
+
|
93
|
+
lines.join "\n"
|
88
94
|
end
|
89
95
|
end
|
90
96
|
end
|
@@ -20,9 +20,10 @@ module IGMarkets
|
|
20
20
|
attribute :account_info, Account::Balance
|
21
21
|
attribute :account_type, Symbol, allowed_values: [:cfd, :physical, :spreadbet]
|
22
22
|
attribute :accounts, AccountDetails
|
23
|
-
attribute :authentication_status, Symbol, allowed_values: [
|
24
|
-
|
25
|
-
|
23
|
+
attribute :authentication_status, Symbol, allowed_values: [:authenticated, :authenticated_missing_credentials,
|
24
|
+
:change_environment, :disabled_preferred_account,
|
25
|
+
:missing_preferred_account,
|
26
|
+
:rejected_invalid_client_version]
|
26
27
|
attribute :client_id
|
27
28
|
attribute :currency_iso_code, String, regex: Regex::CURRENCY
|
28
29
|
attribute :currency_symbol
|
@@ -18,20 +18,28 @@ module IGMarkets
|
|
18
18
|
attribute :level, Float
|
19
19
|
attribute :limit_distance, Fixnum
|
20
20
|
attribute :limit_level, Float
|
21
|
-
attribute :
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
attribute :profit, Float
|
22
|
+
attribute :profit_currency, String, regex: Regex::CURRENCY
|
23
|
+
attribute :reason, Symbol, allowed_values: [:account_not_enabled_to_trading, :attached_order_level_error,
|
24
|
+
:attached_order_trailing_stop_error, :cannot_change_stop_type,
|
25
|
+
:cannot_remove_stop, :closing_only_trades_accepted_on_this_market,
|
26
|
+
:conflicting_order, :cr_spacing, :duplicate_order_error,
|
27
|
+
:exchange_manual_override, :finance_repeat_dealing,
|
28
|
+
:force_open_on_same_market_different_currency, :general_error,
|
29
|
+
:good_till_date_in_the_past, :instrument_not_found, :insufficient_funds,
|
30
|
+
:level_tolerance_error, :manual_order_timeout, :market_closed,
|
31
|
+
:market_closed_with_edits, :market_closing, :market_not_borrowable,
|
32
|
+
:market_offline, :market_phone_only, :market_rolled,
|
33
|
+
:market_unavailable_to_client, :max_auto_size_exceeded,
|
34
|
+
:minimum_order_size_error, :move_away_only_limit, :move_away_only_stop,
|
35
|
+
:move_away_only_trigger_level, :opposing_direction_orders_not_allowed,
|
36
|
+
:opposing_positions_not_allowed, :order_locked, :order_not_found,
|
37
|
+
:over_normal_market_size, :partially_closed_position_not_deleted,
|
38
|
+
:position_not_available_to_close, :position_not_found,
|
39
|
+
:reject_spreadbet_order_on_cfd_account, :size_increment,
|
40
|
+
:sprint_market_expiry_after_market_close, :stop_or_limit_not_allowed,
|
41
|
+
:stop_required_error, :strike_level_tolerance, :success,
|
42
|
+
:trailing_stop_not_allowed, :unknown, :wrong_side_of_market]
|
35
43
|
attribute :size, Float
|
36
44
|
attribute :status, Symbol, allowed_values: [:amended, :closed, :deleted, :open, :partially_closed]
|
37
45
|
attribute :stop_distance, Fixnum
|
@@ -26,7 +26,10 @@ module IGMarkets
|
|
26
26
|
#
|
27
27
|
# @return [Array<Activity>]
|
28
28
|
def activities(options)
|
29
|
-
|
29
|
+
url_parameters = history_url_parameters options
|
30
|
+
url_parameters[:detailed] = true
|
31
|
+
|
32
|
+
history_request_complete url: 'history/activity', url_parameters: url_parameters, api_version: API_V3,
|
30
33
|
collection_name: :activities, model_class: Activity, date_attribute: :date
|
31
34
|
end
|
32
35
|
|
@@ -42,8 +45,9 @@ module IGMarkets
|
|
42
45
|
def transactions(options)
|
43
46
|
options[:type] ||= :all
|
44
47
|
|
45
|
-
history_request_complete url: 'history/transactions', url_parameters:
|
46
|
-
collection_name: :transactions, model_class: Transaction,
|
48
|
+
history_request_complete url: 'history/transactions', url_parameters: history_url_parameters(options),
|
49
|
+
api_version: API_V2, collection_name: :transactions, model_class: Transaction,
|
50
|
+
date_attribute: :date_utc
|
47
51
|
end
|
48
52
|
|
49
53
|
private
|
@@ -53,11 +57,11 @@ module IGMarkets
|
|
53
57
|
|
54
58
|
# Retrieves historical data for this account (either activities or transactions) in the specified date range. This
|
55
59
|
# methods sends a single GET request with the passed URL parameters and returns the response. The maximum number
|
56
|
-
# of items this method can return is capped at 500 {MAXIMUM_PAGE_SIZE}.
|
60
|
+
# of items this method can return is capped at 500 ({MAXIMUM_PAGE_SIZE}).
|
57
61
|
def history_request(options)
|
58
62
|
url = "#{options[:url]}?#{options[:url_parameters].map { |key, value| "#{key}=#{value.to_s.upcase}" }.join '&'}"
|
59
63
|
|
60
|
-
get_result = @dealing_platform.session.get url,
|
64
|
+
get_result = @dealing_platform.session.get url, options.fetch(:api_version)
|
61
65
|
|
62
66
|
@dealing_platform.instantiate_models options[:model_class], get_result.fetch(options[:collection_name])
|
63
67
|
end
|
@@ -80,12 +84,12 @@ module IGMarkets
|
|
80
84
|
models.uniq
|
81
85
|
end
|
82
86
|
|
83
|
-
# Parses and formats
|
84
|
-
def
|
87
|
+
# Parses and formats options shared by {#activities} and {#transactions} into a set of URL parameters.
|
88
|
+
def history_url_parameters(options)
|
85
89
|
options[:to] ||= Date.today + 1
|
86
90
|
|
87
|
-
options[:from] = options
|
88
|
-
options[:to] = options
|
91
|
+
options[:from] = options.fetch(:from).strftime('%F')
|
92
|
+
options[:to] = options.fetch(:to).strftime('%F')
|
89
93
|
|
90
94
|
options[:pageSize] = MAXIMUM_PAGE_SIZE
|
91
95
|
|
@@ -51,8 +51,8 @@ module IGMarkets
|
|
51
51
|
class SprintMarketPositionCreateAttributes < Model
|
52
52
|
attribute :direction, Symbol, allowed_values: [:buy, :sell]
|
53
53
|
attribute :epic, String, regex: Regex::EPIC
|
54
|
-
attribute :expiry_period, Symbol, allowed_values: [
|
55
|
-
|
54
|
+
attribute :expiry_period, Symbol, allowed_values: [:one_minute, :two_minutes, :five_minutes, :twenty_minutes,
|
55
|
+
:sixty_minutes]
|
56
56
|
attribute :size, Float
|
57
57
|
end
|
58
58
|
|
@@ -44,9 +44,15 @@ module IGMarkets
|
|
44
44
|
# the working order will remain until it is cancelled.
|
45
45
|
# @option attributes [Boolean] :guaranteed_stop Whether a guaranteed stop is required. Defaults to `false`.
|
46
46
|
# @option attributes [Float] :level The level at which the order will be triggered. Required.
|
47
|
-
# @option attributes [Fixnum] :limit_distance The distance away in pips to place the limit.
|
47
|
+
# @option attributes [Fixnum] :limit_distance The distance away in pips to place the limit. If this is set then
|
48
|
+
# the `:limit_level` option must be omitted. Optional.
|
49
|
+
# @option attributes [Float] :limit_level The level at which to place the limit. If this is set then the
|
50
|
+
# `:limit_distance` option must be omitted. Optional.
|
48
51
|
# @option attributes [Float] :size The size of the working order. Required.
|
49
|
-
# @option attributes [Fixnum] :stop_distance The distance away in pips to place the stop.
|
52
|
+
# @option attributes [Fixnum] :stop_distance The distance away in pips to place the stop. If this is set then the
|
53
|
+
# `:stop_level` option must be omitted. Optional.
|
54
|
+
# @option attributes [Float] :stop_level The level at which to place the stop. If this is set then the
|
55
|
+
# `:stop_distance` option must be omitted. Optional.
|
50
56
|
# @option attributes [:limit, :stop] :type `:limit` means the working order is intended to buy at a price lower
|
51
57
|
# than at present, or to sell at a price higher than at present, i.e. there is an expectation
|
52
58
|
# of a market reversal at the specified `:level`. `:stop` means the working order is intended
|
@@ -56,30 +62,14 @@ module IGMarkets
|
|
56
62
|
# @return [String] The resulting deal reference, use {DealingPlatform#deal_confirmation} to check the result of
|
57
63
|
# the working order creation.
|
58
64
|
def create(attributes)
|
59
|
-
|
60
|
-
|
61
|
-
attributes[:time_in_force] = attributes[:good_till_date] ? :good_till_date : :good_till_cancelled
|
62
|
-
|
63
|
-
model = build_working_order_model attributes
|
65
|
+
model = WorkingOrderCreateAttributes.new attributes
|
66
|
+
model.validate
|
64
67
|
|
65
68
|
payload = PayloadFormatter.format model
|
66
69
|
|
67
70
|
payload[:expiry] ||= '-'
|
68
71
|
|
69
|
-
@dealing_platform.session.post('workingorders/otc', payload, API_V2).fetch
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def build_working_order_model(attributes)
|
75
|
-
model = WorkingOrderCreateAttributes.new attributes
|
76
|
-
|
77
|
-
required = [:currency_code, :direction, :epic, :guaranteed_stop, :level, :size, :time_in_force, :type]
|
78
|
-
required.each do |attribute|
|
79
|
-
raise ArgumentError, "#{attribute} attribute must be set" if attributes[attribute].nil?
|
80
|
-
end
|
81
|
-
|
82
|
-
model
|
72
|
+
@dealing_platform.session.post('workingorders/otc', payload, API_V2).fetch :deal_reference
|
83
73
|
end
|
84
74
|
|
85
75
|
# Internal model used by {#create}.
|
@@ -93,10 +83,41 @@ module IGMarkets
|
|
93
83
|
attribute :guaranteed_stop, Boolean
|
94
84
|
attribute :level, Float
|
95
85
|
attribute :limit_distance, Fixnum
|
86
|
+
attribute :limit_level, Float
|
96
87
|
attribute :size, Float
|
97
88
|
attribute :stop_distance, Fixnum
|
89
|
+
attribute :stop_level, Float
|
98
90
|
attribute :time_in_force, Symbol, allowed_values: [:good_till_cancelled, :good_till_date]
|
99
91
|
attribute :type, Symbol, allowed_values: [:limit, :stop]
|
92
|
+
|
93
|
+
def initialize(attributes)
|
94
|
+
super
|
95
|
+
|
96
|
+
set_defaults
|
97
|
+
end
|
98
|
+
|
99
|
+
# Runs a series of validations on this model's attributes to check whether it is ready to be sent to the IG
|
100
|
+
# Markets API.
|
101
|
+
def validate
|
102
|
+
required = [:currency_code, :direction, :epic, :guaranteed_stop, :level, :size, :time_in_force, :type]
|
103
|
+
required.each do |attribute|
|
104
|
+
raise ArgumentError, "#{attribute} attribute must be set" if send(attribute).nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
if limit_distance && limit_level
|
108
|
+
raise ArgumentError, 'Do not specify both limit_distance and limit_level options'
|
109
|
+
end
|
110
|
+
|
111
|
+
raise ArgumentError, 'Do not specify both stop_distance and stop_level options' if stop_distance && stop_level
|
112
|
+
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
|
100
121
|
end
|
101
122
|
|
102
123
|
private_constant :WorkingOrderCreateAttributes
|
@@ -135,6 +135,8 @@ module IGMarkets
|
|
135
135
|
model.instance_variable_set :@dealing_platform, self
|
136
136
|
|
137
137
|
attributes.each do |attribute, value|
|
138
|
+
next unless model_class.valid_attribute? attribute
|
139
|
+
|
138
140
|
type = model_class.attribute_type attribute
|
139
141
|
value = instantiate_models(type, value) if type < Model
|
140
142
|
|
@@ -79,10 +79,10 @@ module IGMarkets
|
|
79
79
|
attribute :sprint_markets_minimum_expiry_time, Float
|
80
80
|
attribute :stops_limits_allowed, Boolean
|
81
81
|
attribute :streaming_prices_available, Boolean
|
82
|
-
attribute :type, Symbol, allowed_values: [
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
attribute :type, Symbol, allowed_values: [:binary, :bungee_capped, :bungee_commodities, :bungee_currencies,
|
83
|
+
:bungee_indices, :commodities, :currencies, :indices, :opt_commodities,
|
84
|
+
:opt_currencies, :opt_indices, :opt_rates, :opt_shares, :rates, :sectors,
|
85
|
+
:shares, :sprint_market, :test_market, :unknown]
|
86
86
|
attribute :unit, Symbol, allowed_values: [:amount, :contracts, :shares]
|
87
87
|
attribute :value_of_one_pip
|
88
88
|
end
|
data/lib/ig_markets/market.rb
CHANGED
@@ -11,8 +11,8 @@ module IGMarkets
|
|
11
11
|
attribute :value, Float
|
12
12
|
end
|
13
13
|
|
14
|
-
attribute :market_order_preference, Symbol, allowed_values: [
|
15
|
-
|
14
|
+
attribute :market_order_preference, Symbol, allowed_values: [:available_default_off, :available_default_on,
|
15
|
+
:not_available]
|
16
16
|
attribute :max_stop_or_limit_distance, RuleDetails
|
17
17
|
attribute :min_controlled_risk_stop_distance, RuleDetails
|
18
18
|
attribute :min_deal_size, RuleDetails
|
@@ -30,8 +30,8 @@ module IGMarkets
|
|
30
30
|
attribute :delay_time, Float
|
31
31
|
attribute :high, Float
|
32
32
|
attribute :low, Float
|
33
|
-
attribute :market_status, Symbol, allowed_values: [
|
34
|
-
|
33
|
+
attribute :market_status, Symbol, allowed_values: [:closed, :edits_only, :offline, :on_auction,
|
34
|
+
:on_auction_no_edits, :suspended, :tradeable]
|
35
35
|
attribute :net_change, Float
|
36
36
|
attribute :offer, Float
|
37
37
|
attribute :percentage_change, Float
|
@@ -53,7 +53,7 @@ module IGMarkets
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def typecaster_date(value, options, name)
|
56
|
-
raise ArgumentError, "#{self}##{name}: invalid
|
56
|
+
raise ArgumentError, "#{self}##{name}: invalid date format" unless options[:format].is_a? String
|
57
57
|
|
58
58
|
if value.is_a? String
|
59
59
|
begin
|
@@ -67,28 +67,36 @@ module IGMarkets
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def typecaster_time(value, options, name)
|
70
|
-
|
70
|
+
format = options[:format]
|
71
|
+
|
72
|
+
raise ArgumentError, "#{self}##{name}: invalid time format" unless [Array, String].include? format.class
|
71
73
|
|
72
74
|
if value.is_a?(String) || value.is_a?(Fixnum)
|
73
|
-
|
75
|
+
parse_formatted_time_value value.to_s, options, name
|
74
76
|
else
|
75
77
|
value
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
def
|
80
|
-
|
81
|
+
def parse_formatted_time_value(value, options, name)
|
82
|
+
Array(options[:format]).each do |format|
|
83
|
+
begin
|
84
|
+
return parse_time_using_format value, format
|
85
|
+
rescue ArgumentError
|
86
|
+
next
|
87
|
+
end
|
88
|
+
end
|
81
89
|
|
90
|
+
raise ArgumentError, "#{self}##{name}: failed parsing time: #{value}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse_time_using_format(value, format)
|
82
94
|
unless format == '%Q'
|
83
95
|
format += '%z'
|
84
96
|
value += '+0000'
|
85
97
|
end
|
86
98
|
|
87
|
-
|
88
|
-
Time.strptime value, format
|
89
|
-
rescue ArgumentError
|
90
|
-
raise ArgumentError, "#{self}##{name}: failed parsing time: #{value}"
|
91
|
-
end
|
99
|
+
Time.strptime value, format
|
92
100
|
end
|
93
101
|
end
|
94
102
|
end
|
data/lib/ig_markets/model.rb
CHANGED
@@ -68,7 +68,7 @@ module IGMarkets
|
|
68
68
|
# @return [Hash] A hash containing details of all attributes that have been defined on this model.
|
69
69
|
attr_accessor :defined_attributes
|
70
70
|
|
71
|
-
# @return [
|
71
|
+
# @return [Array] The names of the deprecated attributes on this model.
|
72
72
|
attr_accessor :deprecated_attributes
|
73
73
|
|
74
74
|
# Returns the names of all currently defined attributes for this model.
|
@@ -78,6 +78,23 @@ module IGMarkets
|
|
78
78
|
Hash(defined_attributes).keys
|
79
79
|
end
|
80
80
|
|
81
|
+
# Returns whether the passed value is a valid attribute name. If the passed attribute name is not recognized then
|
82
|
+
# an error will be printed to `stderr`. Only one warning will be printed for each unrecognized attribute.
|
83
|
+
#
|
84
|
+
# @param [Symbol] name The candidate attribute name.
|
85
|
+
#
|
86
|
+
# @return [Boolean]
|
87
|
+
def valid_attribute?(name)
|
88
|
+
return true if defined_attribute_names.include?(name) || Array(deprecated_attributes).include?(name)
|
89
|
+
|
90
|
+
unless Array(@reported_invalid_attributes).include? name
|
91
|
+
warn "ig_markets: unrecognized attribute #{self}##{name}"
|
92
|
+
(@reported_invalid_attributes ||= []) << name
|
93
|
+
end
|
94
|
+
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
81
98
|
# Returns the type of the specified attribute.
|
82
99
|
#
|
83
100
|
# @param [Symbol] attribute_name The name of the attribute to return the type for.
|
@@ -108,8 +125,8 @@ module IGMarkets
|
|
108
125
|
# @option options [Array] :nil_if Values that, when set on the attribute, should be converted to `nil`.
|
109
126
|
# @option options [Regexp] :regex When `type` is `String` only values matching this regex will be allowed.
|
110
127
|
# Optional.
|
111
|
-
# @option options [String] :format When `type` is `Date` or `Time` this specifies the format
|
112
|
-
# and `Fixnum` instances assigned to this attribute.
|
128
|
+
# @option options [String] :format When `type` is `Date` or `Time` this specifies the format or formats for
|
129
|
+
# parsing String and `Fixnum` instances assigned to this attribute.
|
113
130
|
#
|
114
131
|
# @macro [attach] attribute
|
115
132
|
# The $1 attribute.
|
@@ -4,9 +4,9 @@ module IGMarkets
|
|
4
4
|
module_function
|
5
5
|
|
6
6
|
# Takes a {Model} and returns its attributes in a hash ready to be passed as a payload to the IG Markets API.
|
7
|
-
# Attribute names will be converted
|
8
|
-
#
|
9
|
-
#
|
7
|
+
# Attribute names will be converted from snake case to camel case, `Symbol` attributes will be converted to strings
|
8
|
+
# and will be uppercased, and both `Date` and `Time` attributes will be converted to strings using their first
|
9
|
+
# available `:format` option.
|
10
10
|
#
|
11
11
|
# @param [Model] model The model instance to convert attributes for.
|
12
12
|
#
|
@@ -32,7 +32,7 @@ module IGMarkets
|
|
32
32
|
|
33
33
|
value = value.utc if options[:type] == Time
|
34
34
|
|
35
|
-
return value.strftime(options.fetch(:format)) if [Date, Time].include? options[:type]
|
35
|
+
return value.strftime(Array(options.fetch(:format)).first) if [Date, Time].include? options[:type]
|
36
36
|
|
37
37
|
value
|
38
38
|
end
|
data/lib/ig_markets/position.rb
CHANGED
@@ -107,8 +107,8 @@ module IGMarkets
|
|
107
107
|
# the result of the position update.
|
108
108
|
def update(new_attributes)
|
109
109
|
new_attributes = { limit_level: limit_level, stop_level: stop_level, trailing_stop: trailing_stop?,
|
110
|
-
trailing_stop_distance: trailing_stop_distance, trailing_stop_increment: trailing_step
|
111
|
-
|
110
|
+
trailing_stop_distance: trailing_stop_distance, trailing_stop_increment: trailing_step }
|
111
|
+
.merge new_attributes
|
112
112
|
|
113
113
|
unless new_attributes[:trailing_stop]
|
114
114
|
new_attributes[:trailing_stop_distance] = new_attributes[:trailing_stop_increment] = nil
|
@@ -8,7 +8,7 @@ module IGMarkets
|
|
8
8
|
attribute :date_utc, Time, format: '%FT%T'
|
9
9
|
attribute :instrument_name
|
10
10
|
attribute :open_level, String, nil_if: %w(- 0)
|
11
|
-
attribute :period, Time, nil_if:
|
11
|
+
attribute :period, Time, nil_if: %w(- DFB), format: ['%FT%T', '%b-%y']
|
12
12
|
attribute :profit_and_loss
|
13
13
|
attribute :reference
|
14
14
|
attribute :size, String, nil_if: '-'
|
data/lib/ig_markets/version.rb
CHANGED
@@ -37,21 +37,23 @@ module IGMarkets
|
|
37
37
|
# @option new_attributes [Time] :good_till_date
|
38
38
|
# @option new_attributes [Float] :level
|
39
39
|
# @option new_attributes [Fixnum] :limit_distance
|
40
|
+
# @option new_attributes [Float] :limit_level
|
40
41
|
# @option new_attributes [Fixnum] :stop_distance
|
42
|
+
# @option new_attributes [Float] :stop_level
|
41
43
|
# @option new_attributes [:limit, :stop] :type
|
42
44
|
#
|
43
45
|
# @return [String] The deal reference of the update operation. Use {DealingPlatform#deal_confirmation} to check
|
44
46
|
# the result of the working order update.
|
45
47
|
def update(new_attributes)
|
46
|
-
|
47
|
-
|
48
|
-
}.merge new_attributes
|
48
|
+
existing_attributes = { good_till_date: good_till_date, level: order_level, limit_distance: limit_distance,
|
49
|
+
stop_distance: stop_distance, time_in_force: time_in_force, type: order_type }
|
49
50
|
|
50
|
-
|
51
|
+
model = WorkingOrderUpdateAttributes.new existing_attributes, new_attributes
|
52
|
+
model.validate
|
51
53
|
|
52
|
-
payload = PayloadFormatter.format
|
54
|
+
payload = PayloadFormatter.format model
|
53
55
|
|
54
|
-
@dealing_platform.session.put("workingorders/otc/#{deal_id}", payload).fetch(:deal_reference)
|
56
|
+
@dealing_platform.session.put("workingorders/otc/#{deal_id}", payload, API_V2).fetch(:deal_reference)
|
55
57
|
end
|
56
58
|
|
57
59
|
# Internal model used by {#update}.
|
@@ -59,9 +61,30 @@ module IGMarkets
|
|
59
61
|
attribute :good_till_date, Time, format: '%Y/%m/%d %R:%S'
|
60
62
|
attribute :level, Float
|
61
63
|
attribute :limit_distance, Fixnum
|
64
|
+
attribute :limit_level, Float
|
62
65
|
attribute :stop_distance, Fixnum
|
66
|
+
attribute :stop_level, Float
|
63
67
|
attribute :time_in_force, Symbol, allowed_values: [:good_till_cancelled, :good_till_date]
|
64
68
|
attribute :type, Symbol, allowed_values: [:limit, :stop]
|
69
|
+
|
70
|
+
def initialize(existing_attributes, new_attributes)
|
71
|
+
existing_attributes.delete :limit_distance if new_attributes.key? :limit_level
|
72
|
+
existing_attributes.delete :stop_distance if new_attributes.key? :stop_level
|
73
|
+
|
74
|
+
super existing_attributes.merge(new_attributes)
|
75
|
+
|
76
|
+
self.time_in_force = good_till_date ? :good_till_date : :good_till_cancelled
|
77
|
+
end
|
78
|
+
|
79
|
+
# Runs a series of validations on this model's attributes to check whether it is ready to be sent to the IG
|
80
|
+
# Markets API.
|
81
|
+
def validate
|
82
|
+
if limit_distance && limit_level
|
83
|
+
raise ArgumentError, 'Do not specify both limit_distance and limit_level options'
|
84
|
+
end
|
85
|
+
|
86
|
+
raise ArgumentError, 'Do not specify both stop_distance and stop_level options' if stop_distance && stop_level
|
87
|
+
end
|
65
88
|
end
|
66
89
|
|
67
90
|
private_constant :WorkingOrderUpdateAttributes
|
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.12'
|
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-
|
11
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.5'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.5'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: factory_girl
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0.
|
173
|
+
version: '0.40'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0.
|
180
|
+
version: '0.40'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: yard
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|