ig_markets 0.1

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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +15 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +2 -0
  6. data/.travis.yml +10 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +2 -0
  9. data/LICENSE.md +25 -0
  10. data/README.md +134 -0
  11. data/ig_markets.gemspec +28 -0
  12. data/lib/ig_markets.rb +42 -0
  13. data/lib/ig_markets/account.rb +23 -0
  14. data/lib/ig_markets/account_activity.rb +24 -0
  15. data/lib/ig_markets/account_transaction.rb +49 -0
  16. data/lib/ig_markets/api_versions.rb +10 -0
  17. data/lib/ig_markets/application.rb +22 -0
  18. data/lib/ig_markets/boolean.rb +5 -0
  19. data/lib/ig_markets/client_sentiment.rb +16 -0
  20. data/lib/ig_markets/deal_confirmation.rb +41 -0
  21. data/lib/ig_markets/dealing_platform.rb +105 -0
  22. data/lib/ig_markets/dealing_platform/account_methods.rb +92 -0
  23. data/lib/ig_markets/dealing_platform/client_sentiment_methods.rb +26 -0
  24. data/lib/ig_markets/dealing_platform/market_methods.rb +59 -0
  25. data/lib/ig_markets/dealing_platform/position_methods.rb +164 -0
  26. data/lib/ig_markets/dealing_platform/sprint_market_position_methods.rb +46 -0
  27. data/lib/ig_markets/dealing_platform/watchlist_methods.rb +42 -0
  28. data/lib/ig_markets/dealing_platform/working_order_methods.rb +115 -0
  29. data/lib/ig_markets/historical_price_result.rb +33 -0
  30. data/lib/ig_markets/instrument.rb +89 -0
  31. data/lib/ig_markets/market.rb +99 -0
  32. data/lib/ig_markets/market_hierarchy_result.rb +13 -0
  33. data/lib/ig_markets/market_overview.rb +24 -0
  34. data/lib/ig_markets/model.rb +185 -0
  35. data/lib/ig_markets/password_encryptor.rb +31 -0
  36. data/lib/ig_markets/payload_formatter.rb +38 -0
  37. data/lib/ig_markets/position.rb +191 -0
  38. data/lib/ig_markets/regex.rb +10 -0
  39. data/lib/ig_markets/request_failed_error.rb +21 -0
  40. data/lib/ig_markets/response_parser.rb +35 -0
  41. data/lib/ig_markets/session.rb +186 -0
  42. data/lib/ig_markets/sprint_market_position.rb +17 -0
  43. data/lib/ig_markets/version.rb +4 -0
  44. data/lib/ig_markets/watchlist.rb +37 -0
  45. data/lib/ig_markets/working_order.rb +68 -0
  46. data/spec/factories/ig_markets/account.rb +14 -0
  47. data/spec/factories/ig_markets/account_activity.rb +21 -0
  48. data/spec/factories/ig_markets/account_balance.rb +8 -0
  49. data/spec/factories/ig_markets/account_transaction.rb +15 -0
  50. data/spec/factories/ig_markets/application.rb +21 -0
  51. data/spec/factories/ig_markets/client_sentiment.rb +7 -0
  52. data/spec/factories/ig_markets/deal_confirmation.rb +20 -0
  53. data/spec/factories/ig_markets/historical_price_result.rb +7 -0
  54. data/spec/factories/ig_markets/historical_price_result_data_allowance.rb +7 -0
  55. data/spec/factories/ig_markets/historical_price_result_price.rb +7 -0
  56. data/spec/factories/ig_markets/historical_price_result_snapshot.rb +10 -0
  57. data/spec/factories/ig_markets/instrument.rb +32 -0
  58. data/spec/factories/ig_markets/instrument_currency.rb +9 -0
  59. data/spec/factories/ig_markets/instrument_expiry_details.rb +6 -0
  60. data/spec/factories/ig_markets/instrument_margin_deposit_band.rb +8 -0
  61. data/spec/factories/ig_markets/instrument_opening_hours.rb +6 -0
  62. data/spec/factories/ig_markets/instrument_rollover_details.rb +6 -0
  63. data/spec/factories/ig_markets/instrument_slippage_factor.rb +6 -0
  64. data/spec/factories/ig_markets/market.rb +7 -0
  65. data/spec/factories/ig_markets/market_dealing_rules.rb +11 -0
  66. data/spec/factories/ig_markets/market_dealing_rules_rule_details.rb +6 -0
  67. data/spec/factories/ig_markets/market_hierarchy_result.rb +6 -0
  68. data/spec/factories/ig_markets/market_hierarchy_result_hierarchy_node.rb +6 -0
  69. data/spec/factories/ig_markets/market_overview.rb +22 -0
  70. data/spec/factories/ig_markets/market_snapshot.rb +17 -0
  71. data/spec/factories/ig_markets/position.rb +19 -0
  72. data/spec/factories/ig_markets/sprint_market_position.rb +16 -0
  73. data/spec/factories/ig_markets/watchlist.rb +9 -0
  74. data/spec/factories/ig_markets/working_order.rb +21 -0
  75. data/spec/ig_markets/account_transaction_spec.rb +30 -0
  76. data/spec/ig_markets/dealing_platform/account_methods_spec.rb +58 -0
  77. data/spec/ig_markets/dealing_platform/client_sentiment_methods_spec.rb +29 -0
  78. data/spec/ig_markets/dealing_platform/market_methods_spec.rb +80 -0
  79. data/spec/ig_markets/dealing_platform/position_methods_spec.rb +137 -0
  80. data/spec/ig_markets/dealing_platform/sprint_market_position_methods_spec.rb +39 -0
  81. data/spec/ig_markets/dealing_platform/watchlist_methods_spec.rb +89 -0
  82. data/spec/ig_markets/dealing_platform/working_order_methods_spec.rb +120 -0
  83. data/spec/ig_markets/dealing_platform_spec.rb +40 -0
  84. data/spec/ig_markets/model_spec.rb +127 -0
  85. data/spec/ig_markets/password_encryptor_spec.rb +23 -0
  86. data/spec/ig_markets/payload_formatter_spec.rb +19 -0
  87. data/spec/ig_markets/position_spec.rb +37 -0
  88. data/spec/ig_markets/response_parser_spec.rb +13 -0
  89. data/spec/ig_markets/session_spec.rb +134 -0
  90. data/spec/spec_helper.rb +14 -0
  91. data/spec/support/factory_girl.rb +7 -0
  92. data/spec/support/random_test_order.rb +3 -0
  93. metadata +261 -0
@@ -0,0 +1,46 @@
1
+ module IGMarkets
2
+ class DealingPlatform
3
+ # Provides methods for working with sprint market positions. Returned by {DealingPlatform#sprint_market_positions}.
4
+ class SprintMarketPositionMethods
5
+ # Initializes this helper class with the specified dealing platform.
6
+ #
7
+ # @param [DealingPlatform] dealing_platform The dealing platform.
8
+ def initialize(dealing_platform)
9
+ @dealing_platform = dealing_platform
10
+ end
11
+
12
+ # Returns all sprint market positions.
13
+ #
14
+ # @return [Array<SprintMarketPosition>]
15
+ def all
16
+ @dealing_platform.gather 'positions/sprintmarkets', :sprint_market_positions, SprintMarketPosition
17
+ end
18
+
19
+ # Creates a new sprint market position.
20
+ #
21
+ # @param [Hash] attributes The attributes for the new sprint market position.
22
+ # @option attributes [String] :epic The EPIC for the instrument to create a sprint market position for. Required.
23
+ # @option attributes [:buy, :sell] :direction The position direction. Required.
24
+ # @option attributes [:one_minute, :two_minutes, :five_minutes, :twenty_minutes, :sixty_minutes] :expiry_period
25
+ # The expiry period. Required.
26
+ # @option attributes [Float] :size The size of the sprint market position to create. Required.
27
+ #
28
+ # @return [String] The resulting deal reference, use {DealingPlatform#deal_confirmation} to check the result of
29
+ # the sprint market position creation.
30
+ def create(attributes)
31
+ payload = PayloadFormatter.format SprintMarketPositionCreateAttributes.new attributes
32
+
33
+ @dealing_platform.session.post('positions/sprintmarkets', payload, API_V1).fetch(:deal_reference)
34
+ end
35
+
36
+ # Internal model used by {#create}
37
+ class SprintMarketPositionCreateAttributes < Model
38
+ attribute :direction, Symbol, allowed_values: [:buy, :sell]
39
+ attribute :epic, String, regex: Regex::EPIC
40
+ attribute :expiry_period, Symbol, allowed_values: [
41
+ :one_minute, :two_minutes, :five_minutes, :twenty_minutes, :sixty_minutes]
42
+ attribute :size, Fixnum
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ module IGMarkets
2
+ class DealingPlatform
3
+ # Provides methods for working with watchlists. Returned by {DealingPlatform#watchlists}.
4
+ class WatchlistMethods
5
+ # Initializes this helper class with the specified dealing platform.
6
+ #
7
+ # @param [DealingPlatform] dealing_platform The dealing platform.
8
+ def initialize(dealing_platform)
9
+ @dealing_platform = dealing_platform
10
+ end
11
+
12
+ # Returns all watchlists.
13
+ #
14
+ # @return [Array<Watchlist>]
15
+ def all
16
+ @dealing_platform.gather 'watchlists', :watchlists, Watchlist
17
+ end
18
+
19
+ # Returns the watchlist that has the specified ID, or `nil` if there is no watchlist with that ID.
20
+ #
21
+ # @param [String] watchlist_id The ID of the watchlist to return.
22
+ #
23
+ # @return [Watchlist]
24
+ def [](watchlist_id)
25
+ all.detect do |watchlist|
26
+ watchlist.id == watchlist_id
27
+ end
28
+ end
29
+
30
+ # Creates and returns a new watchlist with a name and an initial set of markets.
31
+ #
32
+ # @return [Watchlist] The new watchlist.
33
+ def create(name, *epics)
34
+ result = @dealing_platform.session.post 'watchlists', { name: name, epics: epics.flatten }, API_V1
35
+
36
+ all.detect do |watchlist|
37
+ watchlist.id == result.fetch(:watchlist_id)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,115 @@
1
+ module IGMarkets
2
+ class DealingPlatform
3
+ # Provides methods for working with working orders. Returned by {DealingPlatform#working_orders}.
4
+ class WorkingOrderMethods
5
+ # Initializes this helper class with the specified dealing platform.
6
+ #
7
+ # @param [DealingPlatform] dealing_platform The dealing platform.
8
+ def initialize(dealing_platform)
9
+ @dealing_platform = dealing_platform
10
+ end
11
+
12
+ # Returns all working orders.
13
+ #
14
+ # @return [Array<WorkingOrder>]
15
+ def all
16
+ @dealing_platform.session.get('workingorders', API_V2).fetch(:working_orders).map do |attributes|
17
+ attributes = attributes.fetch(:working_order_data).merge(market: attributes.fetch(:market_data))
18
+
19
+ WorkingOrder.new(attributes).tap do |working_order|
20
+ working_order.instance_variable_set :@dealing_platform, @dealing_platform
21
+ end
22
+ end
23
+ end
24
+
25
+ # Returns the working order with the specified deal ID, or `nil` if there is no order with that deal ID.
26
+ #
27
+ # @param [String] deal_id The deal ID of the working order to return.
28
+ #
29
+ # @return [WorkingOrder]
30
+ def [](deal_id)
31
+ all.detect do |working_order|
32
+ working_order.deal_id == deal_id
33
+ end
34
+ end
35
+
36
+ # Creates a new working order with the specified attributes.
37
+ #
38
+ # @param [Hash] attributes The attributes for the new working order.
39
+ # @option attributes [String] :currency_code The 3 character currency code, must be one of the instrument's
40
+ # currencies (see {Instrument#currencies}). Required.
41
+ # @option attributes [:buy, :sell] :direction Order direction. Required.
42
+ # @option attributes [String] :epic The EPIC of the instrument for the order. Required.
43
+ # @option attributes [DateTime] :expiry The expiry date of the instrument (if applicable). Optional.
44
+ # @option attributes [Boolean] :force_open Whether a force open is required. Defaults to `false`.
45
+ # @option attributes [DateTime] :good_till_date The date that the working order will live till. Must be set if
46
+ # `:time_in_force` is `:good_till_date`.
47
+ # @option attributes [Boolean] :guaranteed_stop Whether a guaranteed stop is required. Defaults to `false`.
48
+ # @option attributes [Float] :level The level at which the order will be triggered.
49
+ # @option attributes [Float] :limit_distance The distance away in pips to place the limit. Optional.
50
+ # @option attributes [Float] :size The size of the working order. Required.
51
+ # @option attributes [Float] :stop_distance The distance away in pips to place the stop. Optional.
52
+ # @option attributes [:good_till_cancelled, :good_till_date] :time_in_force The lifespan of the working order.
53
+ # `:good_till_cancelled` means the working order will live until it is explicitly cancelled.
54
+ # `:good_till_date` means the working order will live until the date specified by
55
+ # `:good_till_date`. Defaults to `:good_till_cancelled`.
56
+ # @option attributes [:limit, :stop] :type `:limit` means the working order is intended to buy at a price lower
57
+ # than at present, or to sell at a price higher than at present, i.e. there is an expectation
58
+ # of a market reversal at the specified `:level`. `:stop` means the working order is intended
59
+ # to sell at a price lower than at present, or to buy at a price higher than at present, i.e.
60
+ # there is no expectation of a market reversal at the specified `:level`. Required.
61
+ #
62
+ # @return [String] The resulting deal reference, use {DealingPlatform#deal_confirmation} to check the result of
63
+ # the working order creation.
64
+ def create(attributes)
65
+ attributes[:force_open] ||= false
66
+ attributes[:guaranteed_stop] ||= false
67
+ attributes[:time_in_force] ||= :good_till_cancelled
68
+
69
+ model = build_working_order_model attributes
70
+
71
+ payload = PayloadFormatter.format model
72
+
73
+ payload[:expiry] ||= '-'
74
+
75
+ @dealing_platform.session.post('workingorders/otc', payload, API_V2).fetch(:deal_reference)
76
+ end
77
+
78
+ private
79
+
80
+ def build_working_order_model(attributes)
81
+ model = WorkingOrderCreateAttributes.new attributes
82
+
83
+ required = [:currency_code, :direction, :epic, :guaranteed_stop, :level, :size, :time_in_force, :type]
84
+ required.each do |attribute|
85
+ raise ArgumentError, "#{attribute} attribute must be set" if attributes[attribute].nil?
86
+ end
87
+
88
+ if model.time_in_force == :good_till_date && !model.good_till_date.is_a?(DateTime)
89
+ raise ArgumentError, 'good_till_date must be set when time_in_force is :good_till_date'
90
+ end
91
+
92
+ model
93
+ end
94
+
95
+ # Internal model used by {#create}.
96
+ class WorkingOrderCreateAttributes < Model
97
+ attribute :currency_code, String, regex: Regex::CURRENCY
98
+ attribute :direction, Symbol, allowed_values: [:buy, :sell]
99
+ attribute :epic, String, regex: Regex::EPIC
100
+ attribute :expiry, DateTime, format: '%d-%b-%y'
101
+ attribute :force_open, Boolean
102
+ attribute :good_till_date, DateTime, format: '%Y-%m-%d %H:%M:%S'
103
+ attribute :guaranteed_stop, Boolean
104
+ attribute :level, Float
105
+ attribute :limit_distance, Float
106
+ attribute :size, Fixnum
107
+ attribute :stop_distance, Float
108
+ attribute :time_in_force, Symbol, allowed_values: [:good_till_cancelled, :good_till_date]
109
+ attribute :type, Symbol, allowed_values: [:limit, :stop]
110
+ end
111
+
112
+ private_constant :WorkingOrderCreateAttributes
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,33 @@
1
+ module IGMarkets
2
+ # Contains details on a historical price query result. Returned by {Market#recent_prices} and
3
+ # {Market#prices_in_date_range}.
4
+ class HistoricalPriceResult < Model
5
+ # Contains details on the remaining allowance for looking up historical prices. Used by {#allowance}.
6
+ class DataAllowance < Model
7
+ attribute :allowance_expiry, Fixnum
8
+ attribute :remaining_allowance, Fixnum
9
+ attribute :total_allowance, Fixnum
10
+ end
11
+
12
+ # Contains details on a single historical price. Used by {Snapshot}.
13
+ class Price < Model
14
+ attribute :ask, Float
15
+ attribute :bid, Float
16
+ attribute :last_traded, Float
17
+ end
18
+
19
+ # Contains details on a single historical price snapshot. Used by {#prices}.
20
+ class Snapshot < Model
21
+ attribute :close_price, Price
22
+ attribute :high_price, Price
23
+ attribute :last_traded_volume, Float
24
+ attribute :low_price, Price
25
+ attribute :open_price, Price
26
+ attribute :snapshot_time, DateTime, format: '%Y/%m/%d %H:%M:%S'
27
+ end
28
+
29
+ attribute :allowance, DataAllowance
30
+ attribute :instrument_type, Symbol, allowed_values: Instrument.allowed_values(:type)
31
+ attribute :prices, Snapshot
32
+ end
33
+ end
@@ -0,0 +1,89 @@
1
+ module IGMarkets
2
+ # Contains details on a tradeable instrument. Returned by {Market#instrument}.
3
+ class Instrument < Model
4
+ # Contains details on a currency used by an instrument. Returned by {#currencies}.
5
+ class Currency < Model
6
+ attribute :base_exchange_rate, Float
7
+ attribute :code
8
+ attribute :exchange_rate, Float
9
+ attribute :is_default, Boolean
10
+ attribute :symbol
11
+ end
12
+
13
+ # Contains details on the expiry details of an instrument. Returned by {#expiry_details}.
14
+ class ExpiryDetails < Model
15
+ attribute :last_dealing_date, DateTime, format: '%Y/%m/%d %H:%M:%S'
16
+ attribute :settlement_info
17
+ end
18
+
19
+ # Contains details on the margin deposit requirements for an instrument at a certain price band. Returned by
20
+ # {#margin_deposit_bands}.
21
+ class MarginDepositBand < Model
22
+ attribute :currency, String, regex: Regex::CURRENCY
23
+ attribute :margin, Float
24
+ attribute :max, Float
25
+ attribute :min, Float
26
+ end
27
+
28
+ # Contains details on the opening hours for an instrument. Returned by {#opening_hours}.
29
+ class OpeningHours < Model
30
+ attribute :close_time
31
+ attribute :open_time
32
+
33
+ # (See {Model.from}).
34
+ def self.from(value)
35
+ # This check works around a vagary in the IG API where there is a seemingly unnecessary hash for the
36
+ # :opening_hours value that only has a single :market_times key which is what holds the actual data.
37
+ if value.is_a?(Hash) && value.keys == [:market_times]
38
+ super value[:market_times]
39
+ else
40
+ super
41
+ end
42
+ end
43
+ end
44
+
45
+ # Contains details on the rollover setup for an instrument. Returned by {#rollover_details}.
46
+ class RolloverDetails < Model
47
+ attribute :last_rollover_time
48
+ attribute :rollover_info
49
+ end
50
+
51
+ # Contains details on the slippage factor for an instrument. Returned by {#slippage_factor}.
52
+ class SlippageFactor < Model
53
+ attribute :unit
54
+ attribute :value, Float
55
+ end
56
+
57
+ attribute :chart_code
58
+ attribute :contract_size
59
+ attribute :controlled_risk_allowed, Boolean
60
+ attribute :country
61
+ attribute :currencies, Currency
62
+ attribute :epic, String, regex: Regex::EPIC
63
+ attribute :expiry, DateTime, nil_if: '-', format: '%d-%b-%y'
64
+ attribute :expiry_details, ExpiryDetails
65
+ attribute :force_open_allowed, Boolean
66
+ attribute :lot_size, Float
67
+ attribute :margin_deposit_bands, MarginDepositBand
68
+ attribute :margin_factor, Float
69
+ attribute :margin_factor_unit, Symbol, allowed_values: [:percentage, :points]
70
+ attribute :market_id
71
+ attribute :name
72
+ attribute :news_code
73
+ attribute :one_pip_means
74
+ attribute :opening_hours, OpeningHours
75
+ attribute :rollover_details, RolloverDetails
76
+ attribute :slippage_factor, SlippageFactor
77
+ attribute :special_info
78
+ attribute :sprint_markets_maximum_expiry_time, Float
79
+ attribute :sprint_markets_minimum_expiry_time, Float
80
+ attribute :stops_limits_allowed, Boolean
81
+ attribute :streaming_prices_available, Boolean
82
+ attribute :type, Symbol, allowed_values: [
83
+ :binary, :bungee_capped, :bungee_commodities, :bungee_currencies, :bungee_indices, :commodities,
84
+ :currencies, :indices, :opt_commodities, :opt_currencies, :opt_indices, :opt_rates, :opt_shares,
85
+ :rates, :sectors, :shares, :sprint_market, :test_market, :unknown]
86
+ attribute :unit, Symbol, allowed_values: [:amount, :contracts, :shares]
87
+ attribute :value_of_one_pip
88
+ end
89
+ end
@@ -0,0 +1,99 @@
1
+ module IGMarkets
2
+ # Contains details on a market, which is a combination of an {#instrument}, a set of {#dealing_rules}, and a
3
+ # current {#snapshot} of the instrument's market. Returned by {DealingPlatform::MarketMethods#find} and
4
+ # {DealingPlatform::MarketMethods#[]}.
5
+ class Market < Model
6
+ # Contains details on the dealing rules for a market. Returned by {#dealing_rules}.
7
+ class DealingRules < Model
8
+ # Contains specfics for a single dealing rule.
9
+ class RuleDetails < Model
10
+ attribute :unit, Symbol, allowed_values: [:percentage, :points]
11
+ attribute :value, Float
12
+ end
13
+
14
+ attribute :market_order_preference, Symbol, allowed_values: [
15
+ :available_default_off, :available_default_on, :not_available]
16
+ attribute :max_stop_or_limit_distance, RuleDetails
17
+ attribute :min_controlled_risk_stop_distance, RuleDetails
18
+ attribute :min_deal_size, RuleDetails
19
+ attribute :min_normal_stop_or_limit_distance, RuleDetails
20
+ attribute :min_step_distance, RuleDetails
21
+ attribute :trailing_stops_preference, Symbol, allowed_values: [:available, :not_available]
22
+ end
23
+
24
+ # Contains details on a snapshot of a market. Returned by {#snapshot}.
25
+ class Snapshot < Model
26
+ attribute :bid, Float
27
+ attribute :binary_odds, Float
28
+ attribute :controlled_risk_extra_spread, Float
29
+ attribute :decimal_places_factor, Float
30
+ attribute :delay_time, Float
31
+ attribute :high, Float
32
+ attribute :low, Float
33
+ attribute :market_status, Symbol, allowed_values: [
34
+ :closed, :edits_only, :offline, :on_auction, :on_auction_no_edits, :suspended, :tradeable]
35
+ attribute :net_change, Float
36
+ attribute :offer, Float
37
+ attribute :percentage_change, Float
38
+ attribute :scaling_factor, Float
39
+ attribute :update_time
40
+ end
41
+
42
+ attribute :dealing_rules, DealingRules
43
+ attribute :instrument, Instrument
44
+ attribute :snapshot, Snapshot
45
+
46
+ # Returns recent historical prices for this market at a specified resolution.
47
+ #
48
+ # @param [:minute, :minute_2, :minute_3, :minute_5, :minute_10, :minute_15, :minute_30, :hour, :hour_2, :hour_3,
49
+ # :hour_4, :day, :week, :month] resolution The resolution of the historical prices to return.
50
+ # @param [Fixnum] num_points The number of historical prices to return.
51
+ #
52
+ # @return [HistoricalPriceResult]
53
+ def recent_prices(resolution, num_points)
54
+ validate_historical_price_resolution resolution
55
+
56
+ url = "prices/#{instrument.epic}/#{resolution.to_s.upcase}/#{num_points.to_i}"
57
+
58
+ HistoricalPriceResult.from @dealing_platform.session.get(url, API_V2)
59
+ end
60
+
61
+ # Returns historical prices for this market at a specified resolution over a specified time period.
62
+ #
63
+ # @param [:minute, :minute_2, :minute_3, :minute_5, :minute_10, :minute_15, :minute_30, :hour, :hour_2, :hour_3,
64
+ # :hour_4, :day, :week, :month] resolution The resolution of the historical prices to return.
65
+ # @param [DateTime] start_date_time The start of the desired time period.
66
+ # @param [DateTime] end_date_time The end of the desired time period.
67
+ #
68
+ # @return [HistoricalPriceResult]
69
+ def prices_in_date_range(resolution, start_date_time, end_date_time)
70
+ validate_historical_price_resolution resolution
71
+
72
+ start_date_time = format_date_time start_date_time
73
+ end_date_time = format_date_time end_date_time
74
+
75
+ url = "prices/#{instrument.epic}/#{resolution.to_s.upcase}/#{start_date_time}/#{end_date_time}"
76
+
77
+ HistoricalPriceResult.from @dealing_platform.session.get(url, API_V2)
78
+ end
79
+
80
+ private
81
+
82
+ # Validates whether the passed argument is a valid historical price resolution.
83
+ #
84
+ # @param [Symbol] resolution The candidate historical price resolution to validate.
85
+ def validate_historical_price_resolution(resolution)
86
+ resolutions = [:minute, :minute_2, :minute_3, :minute_5, :minute_10, :minute_15, :minute_30, :hour, :hour_2,
87
+ :hour_3, :hour_4, :day, :week, :month]
88
+
89
+ raise ArgumentError, 'resolution is invalid' unless resolutions.include? resolution
90
+ end
91
+
92
+ # Takes a `DateTime` and formats it for the historical prices API URLs.
93
+ #
94
+ # @param [DateTime] date_time The `DateTime` to format.
95
+ def format_date_time(date_time)
96
+ date_time.strftime '%Y-%m-%dT%H:%M:%S'
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ module IGMarkets
2
+ # Contains details on a market hierarchy query result. Returned by {DealingPlatform::MarketMethods#hierarchy}.
3
+ class MarketHierarchyResult < Model
4
+ # Contains details on a single node in the market hierarchy. Used by {#nodes}.
5
+ class HierarchyNode < Model
6
+ attribute :id
7
+ attribute :name
8
+ end
9
+
10
+ attribute :markets, MarketOverview
11
+ attribute :nodes, HierarchyNode
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module IGMarkets
2
+ # Contains an overview of a market's state. Returned by {Position#market} and {WorkingOrder#market}.
3
+ class MarketOverview < Model
4
+ attribute :bid, Float
5
+ attribute :delay_time, Float
6
+ attribute :epic, String, regex: Regex::EPIC
7
+ attribute :exchange_id
8
+ attribute :expiry
9
+ attribute :high, Float
10
+ attribute :instrument_name
11
+ attribute :instrument_type, Symbol, allowed_values: Instrument.allowed_values(:type)
12
+ attribute :lot_size, Float
13
+ attribute :low, Float
14
+ attribute :market_status, Symbol, allowed_values: Market::Snapshot.allowed_values(:market_status)
15
+ attribute :net_change, Float
16
+ attribute :offer, Float
17
+ attribute :otc_tradeable, Boolean
18
+ attribute :percentage_change, Float
19
+ attribute :scaling_factor, Float
20
+ attribute :streaming_prices_available, Boolean
21
+ attribute :update_time
22
+ attribute :update_time_utc
23
+ end
24
+ end