Class: IGMarkets::Position

Inherits:
Model
  • Object
show all
Defined in:
lib/ig_markets/position.rb

Overview

Contains details on a trading position. Returned by DealingPlatform::PositionMethods#all and DealingPlatform::PositionMethods#[].

Instance Attribute Summary

Attributes inherited from Model

#attributes

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Model

#==, allowed_values, attribute, attribute_type, attribute_value_allowed?, defined_attribute_names, deprecated_attribute, #initialize, #initialize_copy, #inspect, #to_h, valid_attribute?

Constructor Details

This class inherits a constructor from IGMarkets::Model

Class Method Details

.validate_order_type_constraints(attributes) ⇒ Object

Validates the internal consistency of the ‘:order_type`, `:quote_id` and `:level` attributes.

Parameters:

  • attributes (Hash)

    The attributes hash to validate.

Raises:

  • (ArgumentError)


132
133
134
135
136
137
138
139
140
# File 'lib/ig_markets/position.rb', line 132

def self.validate_order_type_constraints(attributes)
  if (attributes[:order_type] == :quote) == attributes[:quote_id].nil?
    raise ArgumentError, 'set quote_id if and only if order_type is :quote'
  end

  return unless %i[limit quote].include?(attributes[:order_type]) == attributes[:level].nil?

  raise ArgumentError, 'set level if and only if order_type is :limit or :quote'
end

Instance Method Details

#close(options = {}) ⇒ String

Closes this position. If called with no options then this position will be fully closed at current market prices, partial closes and greater control over the close conditions can be achieved by using the relevant options.

Parameters:

  • options (Hash) (defaults to: {})

    The options for the position close.

Options Hash (options):

  • :level (Float)

    Required if and only if ‘:order_type` is `:limit` or `:quote`.

  • :order_type (:limit, :market, :quote)

    The order type. ‘:market` indicates to fill the order at current market level(s). `:limit` indicates to fill at the price specified by `:level` (or a more favorable one). `:quote` is only permitted following agreement with IG Markets. Defaults to `:market`.

  • :quote_id (String)

    The Lightstreamer quote ID. Required when ‘:order_type` is `:quote`.

  • :size (Float)

    The size of the position to close. Defaults to #size which will close the entire position, or alternatively specify a smaller value to partially close this position.

  • :time_in_force (:execute_and_eliminate, :fill_or_kill)

    The order fill strategy. ‘:execute_and_eliminate` will fill this order as much as possible within the constraints set by `:order_type`, `:level` and `:quote_id`. `:fill_or_kill` will try to fill this entire order within the constraints, however if this is not possible then the order will not be filled at all. If `:order_type` is `:market` (the default) then `:time_in_force` will be automatically set to `:execute_and_eliminate`.

Returns:



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ig_markets/position.rb', line 90

def close(options = {})
  options[:deal_id] = deal_id
  options[:direction] = { buy: :sell, sell: :buy }.fetch(direction)
  options[:size] ||= size

  model = PositionCloseAttributes.build options
  model.validate

  body = RequestBodyFormatter.format model

  @dealing_platform.session.delete('positions/otc', body).fetch :deal_reference
end

#close_levelFloat

Returns the level at which this position would close at given the current market price as stored in #market.

Returns:

  • (Float)


32
33
34
# File 'lib/ig_markets/position.rb', line 32

def close_level
  { buy: market.bid, sell: market.offer }.fetch direction
end

#contract_sizeFloat

The contract_size attribute.

Returns:

  • (Float)


5
# File 'lib/ig_markets/position.rb', line 5

attribute :contract_size, Float

#controlled_riskBoolean

The controlled_risk attribute.

Returns:



6
# File 'lib/ig_markets/position.rb', line 6

attribute :controlled_risk, Boolean

#created_date_utcTime

The created_date_utc attribute.

Returns:

  • (Time)


7
# File 'lib/ig_markets/position.rb', line 7

attribute :created_date_utc, Time, format: '%FT%T'

#currencyString

The currency attribute.

Returns:

  • (String)


8
# File 'lib/ig_markets/position.rb', line 8

attribute :currency, String, regex: Regex::CURRENCY

#deal_idObject

The deal_id attribute.

Returns:



9
# File 'lib/ig_markets/position.rb', line 9

attribute :deal_id

#deal_referenceObject

The deal_reference attribute.

Returns:



10
# File 'lib/ig_markets/position.rb', line 10

attribute :deal_reference

#directionSymbol

The direction attribute.

Returns:

  • (Symbol)


11
# File 'lib/ig_markets/position.rb', line 11

attribute :direction, Symbol, allowed_values: %i[buy sell]

#levelFloat

The level attribute.

Returns:

  • (Float)


12
# File 'lib/ig_markets/position.rb', line 12

attribute :level, Float

#limit_levelFloat

The limit_level attribute.

Returns:

  • (Float)


13
# File 'lib/ig_markets/position.rb', line 13

attribute :limit_level, Float

#limited_risk_premiumLimitedRiskPremium

The limited_risk_premium attribute.

Returns:



14
# File 'lib/ig_markets/position.rb', line 14

attribute :limited_risk_premium, LimitedRiskPremium

#marketMarketOverview

The market attribute.

Returns:



20
# File 'lib/ig_markets/position.rb', line 20

attribute :market, MarketOverview

#price_deltaFloat

Returns the favorable difference in the price between #level and the current market price as stored in #market. If #direction is ‘:buy` and the market has since risen then this method will return a positive value, but if #direction is `:sell` and the market has since risen then this method will return a negative value.

Returns:

  • (Float)


41
42
43
44
45
46
47
# File 'lib/ig_markets/position.rb', line 41

def price_delta
  if direction == :buy
    close_level - level
  elsif direction == :sell
    level - close_level
  end
end

#profit_lossFloat

Returns this position’s current profit or loss, denominated in its #currency, and based on the current market state as stored in #market. For binary instruments this returns the payout amount.

Returns:

  • (Float)


58
59
60
61
62
# File 'lib/ig_markets/position.rb', line 58

def profit_loss
  return size / level if market.instrument_type == :binary

  price_delta * size * contract_size
end

#profitable?Boolean

Returns whether this position is currently profitable based on the current market state as stored in #market.

Returns:



50
51
52
# File 'lib/ig_markets/position.rb', line 50

def profitable?
  price_delta > 0.0
end

#reloadObject

Reloads this position’s attributes by re-querying the IG Markets API.



65
66
67
# File 'lib/ig_markets/position.rb', line 65

def reload
  self.attributes = @dealing_platform.positions[deal_id].attributes
end

#sizeFloat

The size attribute.

Returns:

  • (Float)


15
# File 'lib/ig_markets/position.rb', line 15

attribute :size, Float

#stop_levelFloat

The stop_level attribute.

Returns:

  • (Float)


16
# File 'lib/ig_markets/position.rb', line 16

attribute :stop_level, Float

#trailing_stepFloat

The trailing_step attribute.

Returns:

  • (Float)


17
# File 'lib/ig_markets/position.rb', line 17

attribute :trailing_step, Float

#trailing_stop?Boolean

Returns whether this position has a trailing stop.

Returns:



25
26
27
# File 'lib/ig_markets/position.rb', line 25

def trailing_stop?
  !trailing_step.nil? && !trailing_stop_distance.nil?
end

#trailing_stop_distanceInteger

The trailing_stop_distance attribute.

Returns:

  • (Integer)


18
# File 'lib/ig_markets/position.rb', line 18

attribute :trailing_stop_distance, Integer

#update(new_attributes) ⇒ String

Updates this position. No attributes are mandatory, and any attributes not specified will be kept at their current value.

Parameters:

  • new_attributes (Hash)

    The attributes of this position to update.

Options Hash (new_attributes):

  • :limit_level (Float)

    The new limit level for this position.

  • :stop_level (Float)

    The new stop level for this position.

  • :trailing_stop (Boolean)

    Whether to use a trailing stop for this position.

  • :trailing_stop_distance (Integer)

    The distance away in pips to place the trailing stop.

  • :trailing_stop_increment (Integer)

    The step increment to use for the trailing stop.

Returns:



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/ig_markets/position.rb', line 115

def update(new_attributes)
  new_attributes = { limit_level: limit_level, stop_level: stop_level, trailing_stop: trailing_stop?,
                     trailing_stop_distance: trailing_stop_distance, trailing_stop_increment: trailing_step }
                   .merge new_attributes

  unless new_attributes[:trailing_stop]
    new_attributes[:trailing_stop_distance] = new_attributes[:trailing_stop_increment] = nil
  end

  body = RequestBodyFormatter.format PositionUpdateAttributes.new(new_attributes)

  @dealing_platform.session.put("positions/otc/#{deal_id}", body, API_V2).fetch(:deal_reference)
end