Class: IGMarkets::CLI::Main

Inherits:
Thor
  • Object
show all
Defined in:
lib/ig_markets/cli/main.rb,
lib/ig_markets/cli/commands/prices_command.rb,
lib/ig_markets/cli/commands/search_command.rb,
lib/ig_markets/cli/commands/account_command.rb,
lib/ig_markets/cli/commands/console_command.rb,
lib/ig_markets/cli/commands/markets_command.rb,
lib/ig_markets/cli/commands/self_test_command.rb,
lib/ig_markets/cli/commands/sentiment_command.rb,
lib/ig_markets/cli/commands/activities_command.rb,
lib/ig_markets/cli/commands/performance_command.rb,
lib/ig_markets/cli/commands/confirmation_command.rb,
lib/ig_markets/cli/commands/transactions_command.rb

Overview

Implements the ‘ig_markets transactions` command.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.begin_session(options) ⇒ Object

Signs in to IG Markets and yields back a DealingPlatform instance, with common error handling if exceptions occur. This method is used by all of the commands in order to authenticate.

Parameters:

  • options (Thor::CoreExt::HashWithIndifferentAccess)

    The Thor options hash.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ig_markets/cli/main.rb', line 67

def begin_session(options)
  platform = options[:demo] ? :demo : :live

  @dealing_platform ||= DealingPlatform.new
  @dealing_platform.session.log_sinks = [$stdout] if options[:verbose]

  @dealing_platform. options[:username], options[:password], options[:api_key], platform

  yield @dealing_platform
rescue IGMarketsError => e
  warn_and_exit e
end

.bootstrap(argv) ⇒ Object

This is the initial entry point for the execution of the command-line client. It is responsible for reading any config files, implementing the –version/-v options, and then invoking the main application.

Parameters:

  • argv (Array<String>)

    The array of command-line arguments.



52
53
54
55
56
57
58
59
60
61
# File 'lib/ig_markets/cli/main.rb', line 52

def bootstrap(argv)
  config_file.prepend_profile_arguments_to_argv argv unless argv.first == 'help'

  if argv.index('--version') || argv.index('-v')
    puts VERSION
    exit
  end

  start argv
end

.filter_options(options, whitelist) ⇒ Hash

Takes a Thor options hash and filters out its keys in the specified whitelist. Thor has an unusual behavior when an option is specified without a value: its value is set to the option’s name. This method resets any such occurrences to ‘nil`.

Parameters:

  • options (Thor::CoreExt::HashWithIndifferentAccess)

    The Thor options.

  • whitelist (Array<Symbol>)

    The list of options allowed in the returned ‘Hash`.

Returns:

  • (Hash)


130
131
132
133
134
135
136
# File 'lib/ig_markets/cli/main.rb', line 130

def filter_options(options, whitelist)
  options.each_with_object({}) do |(key, value), new_hash|
    next unless whitelist.include? key.to_sym

    new_hash[key.to_sym] = value == key ? nil : value
  end
end

.parse_date_time(attributes, attribute, klass, format, display_format) ⇒ Object

Parses and validates a ‘Date` or `Time` option received as a command-line argument. Raises `ArgumentError` if it has been specified in an invalid format.

Parameters:

  • attributes (Hash)

    The attributes hash.

  • attribute (Symbol)

    The name of the date or time attribute to parse and validate.

  • klass (Date, Time)

    The class to validate with.

  • format (String)

    The ‘strptime` format string for the attribute.

  • display_format (String)

    The human-readable version of ‘format` to put into the raised exception if there is a problem parsing the attribute.



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/ig_markets/cli/main.rb', line 108

def parse_date_time(attributes, attribute, klass, format, display_format)
  return unless attributes.key? attribute

  if ['', attribute.to_s].include? attributes[attribute].to_s
    attributes[attribute] = nil
  else
    begin
      attributes[attribute] = klass.strptime attributes[attribute], format
    rescue ArgumentError
      raise ArgumentError, %(invalid #{attribute}, use format "#{display_format}")
    end
  end
end

.report_deal_confirmation(deal_reference) ⇒ Object

Requests and displays the deal confirmation for the passed deal reference. If the request for the deal confirmation returns a ‘deal not found’ error then the request is attempted again after a two second pause. This is done because sometimes there is a delay in the processing of the deal by IG Markets. A maximum of five attempts wil be made before failing outright.

Parameters:

  • deal_reference (String)

    The deal reference.



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ig_markets/cli/main.rb', line 86

def report_deal_confirmation(deal_reference)
  puts "Deal reference: #{deal_reference}"

  5.times do |index|
    return print_deal_confirmation @dealing_platform.deal_confirmation(deal_reference)
  rescue Errors::DealNotFoundError
    raise if index == 4

    puts 'Deal not found, retrying ...'
    sleep 2
  end
end

Instance Method Details

#accountObject



7
8
9
10
11
12
13
14
15
# File 'lib/ig_markets/cli/commands/account_command.rb', line 7

def 
  self.class.begin_session(options) do |dealing_platform|
    accounts = dealing_platform..all

    table = Tables::AccountsTable.new accounts

    puts table
  end
end

#activitiesObject



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/ig_markets/cli/commands/activities_command.rb', line 13

def activities
  self.class.begin_session(options) do |dealing_platform|
    @epic_regex = Regexp.new options.fetch('epic', ''), Regexp::IGNORECASE

    activities = gather_activities dealing_platform

    table = Tables::ActivitiesTable.new activities

    puts table
  end
end

#confirmation(deal_reference) ⇒ Object



7
8
9
10
11
# File 'lib/ig_markets/cli/commands/confirmation_command.rb', line 7

def confirmation(deal_reference)
  self.class.begin_session(options) do |_dealing_platform|
    Main.report_deal_confirmation deal_reference
  end
end

#consoleObject



7
8
9
10
11
12
13
# File 'lib/ig_markets/cli/commands/console_command.rb', line 7

def console
  self.class.begin_session(options) do |dealing_platform|
    ig = dealing_platform

    pry binding # rubocop:disable Lint/Debugger
  end
end

#markets(*epics) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/ig_markets/cli/commands/markets_command.rb', line 7

def markets(*epics)
  self.class.begin_session(options) do |dealing_platform|
    markets = dealing_platform.markets.find(*epics)

    table = Tables::MarketsTable.new markets

    puts table
  end
end

#performanceObject



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ig_markets/cli/commands/performance_command.rb', line 11

def performance
  self.class.begin_session(options) do |dealing_platform|
    performances = gather_performances dealing_platform
    lookup_instrument_names performances, dealing_platform

    table = Tables::PerformancesTable.new performances

    puts table

    print_summary performances if performances.any?
  end
end

#pricesObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/ig_markets/cli/commands/prices_command.rb', line 17

def prices
  self.class.begin_session(options) do |dealing_platform|
    result = historical_price_result dealing_platform
    allowance = result..allowance

    table = Tables::HistoricalPriceResultSnapshotsTable.new result.prices, title: "Prices for #{options[:epic]}"

    puts <<~MSG
      #{table}

      Allowance: #{allowance.total_allowance}
      Remaining: #{allowance.remaining_allowance}
    MSG
  end
end

#search(query) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/ig_markets/cli/commands/search_command.rb', line 10

def search(query)
  self.class.begin_session(options) do |dealing_platform|
    market_overviews = gather_market_overviews dealing_platform, query

    table = Tables::MarketOverviewsTable.new market_overviews

    puts table
  end
end

#self_testObject



7
8
9
10
11
12
13
14
15
16
# File 'lib/ig_markets/cli/commands/self_test_command.rb', line 7

def self_test
  self.class.begin_session(options) do |dealing_platform|
    raise 'The self-test command must be run on a demo account' unless dealing_platform.session.platform == :demo

    @dealing_platform = dealing_platform
    run_self_test

    dealing_platform.sign_out
  end
end

#sentiment(market) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/ig_markets/cli/commands/sentiment_command.rb', line 7

def sentiment(market)
  self.class.begin_session(options) do |dealing_platform|
    client_sentiment = dealing_platform.client_sentiment[market]
    client_sentiments = [client_sentiment, :separator, client_sentiment.related_sentiments]

    table = Tables::ClientSentimentsTable.new client_sentiments, title: "Client sentiment for '#{market}'"

    puts table
  end
end

#transactionsObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ig_markets/cli/commands/transactions_command.rb', line 15

def transactions
  self.class.begin_session(options) do |dealing_platform|
    @instrument_regex = Regexp.new options.fetch('instrument', ''), Regexp::IGNORECASE

    transactions = gather_transactions dealing_platform

    table = Tables::TransactionsTable.new transactions

    puts table

    if transactions.any?
      puts ''
      print_transaction_totals transactions
    end
  end
end