Class: Quant::Series

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/quant/series.rb

Overview

Ticks belong to the first series they’re associated with always. There are no provisions for series merging their ticks to one series! Indicators will be computed against the parent series of a list of ticks, so we can safely work with subsets of a series and indicators will compute just once.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(symbol:, interval:) ⇒ Series

Returns a new instance of Series.



57
58
59
60
61
# File 'lib/quant/series.rb', line 57

def initialize(symbol:, interval:)
  @symbol = symbol
  @interval = Interval[interval]
  @ticks = []
end

Instance Attribute Details

#intervalObject (readonly)

Returns the value of attribute interval.



55
56
57
# File 'lib/quant/series.rb', line 55

def interval
  @interval
end

#symbolObject (readonly)

Returns the value of attribute symbol.



55
56
57
# File 'lib/quant/series.rb', line 55

def symbol
  @symbol
end

#ticksObject (readonly)

Returns the value of attribute ticks.



55
56
57
# File 'lib/quant/series.rb', line 55

def ticks
  @ticks
end

Class Method Details

.from_file(filename:, symbol:, interval:, serializer_class: nil) ⇒ Object

Loads a series of ticks when each line is a parsible JSON string that represents a tick. A Ticks::TickSerializer may be passed to convert the parsed JSON to Ticks::Tick object.

Parameters:

  • filename (String)

    The filename to load the ticks from.

  • symbol (String)

    The symbol of the series.

  • interval (String)

    The interval of the series.

  • serializer_class (Class) (defaults to: nil)

    Ticks::TickSerializer class to use for the conversion.



18
19
20
21
22
23
# File 'lib/quant/series.rb', line 18

def self.from_file(filename:, symbol:, interval:, serializer_class: nil)
  raise "File #{filename} does not exist" unless File.exist?(filename)

  ticks = File.read(filename).split("\n").map{ |line| Oj.load(line) }
  from_hash symbol: symbol, interval: interval, hash: ticks, serializer_class: serializer_class
end

.from_hash(symbol:, interval:, hash:, serializer_class: nil) ⇒ Object

Loads a series of ticks where the hash must be cast to an array of Ticks::Tick objects.

Parameters:

  • symbol (String)

    The symbol of the series.

  • interval (String)

    The interval of the series.

  • hash (Array<Hash>)

    The array of hashes to convert to Ticks::Tick objects.

  • serializer_class (Class) (defaults to: nil)

    Ticks::TickSerializer class to use for the conversion.



41
42
43
44
# File 'lib/quant/series.rb', line 41

def self.from_hash(symbol:, interval:, hash:, serializer_class: nil)
  ticks = hash.map { |tick_hash| Quant::Ticks::OHLC.from(tick_hash, serializer_class: serializer_class) }
  from_ticks symbol: symbol, interval: interval, ticks: ticks
end

.from_json(symbol:, interval:, json:, serializer_class: nil) ⇒ Object

Loads a series of ticks when the JSON string represents an array of ticks. A Ticks::TickSerializer may be passed to convert the parsed JSON to Ticks::Tick object.

Parameters:

  • symbol (String)

    The symbol of the series.

  • interval (String)

    The interval of the series.

  • json (String)

    The JSON string to parse into ticks.

  • serializer_class (Class) (defaults to: nil)

    Ticks::TickSerializer class to use for the conversion.



31
32
33
34
# File 'lib/quant/series.rb', line 31

def self.from_json(symbol:, interval:, json:, serializer_class: nil)
  ticks = Oj.load(json)
  from_hash symbol: symbol, interval: interval, hash: ticks, serializer_class: serializer_class
end

.from_ticks(symbol:, interval:, ticks:) ⇒ Object

Loads a series of ticks where the array represents an array of Ticks::Tick objects.



47
48
49
50
51
52
53
# File 'lib/quant/series.rb', line 47

def self.from_ticks(symbol:, interval:, ticks:)
  ticks = ticks.sort_by(&:close_timestamp)

  new(symbol: symbol, interval: interval).tap do |series|
    ticks.each { |tick| series << tick }
  end
end

Instance Method Details

#<<(tick) ⇒ Object



104
105
106
107
108
109
# File 'lib/quant/series.rb', line 104

def <<(tick)
  tick = Ticks::Spot.new(price: tick) if tick.is_a?(Numeric)
  indicators << tick unless tick.series?
  @ticks << tick.assign_series(self)
  self
end

#==(other) ⇒ Object



92
93
94
# File 'lib/quant/series.rb', line 92

def ==(other)
  [symbol, interval, ticks] == [other.symbol, other.interval, other.ticks]
end

#dupObject



96
97
98
# File 'lib/quant/series.rb', line 96

def dup
  self.class.from_ticks(symbol: symbol, interval: interval, ticks: ticks)
end

#highestObject



84
85
86
# File 'lib/quant/series.rb', line 84

def highest
  ticks.max_by(&:high_price)
end

#indicatorsObject



111
112
113
# File 'lib/quant/series.rb', line 111

def indicators
  @indicators ||= IndicatorsSources.new(series: self)
end

#inspectObject



100
101
102
# File 'lib/quant/series.rb', line 100

def inspect
  "#<#{self.class.name} symbol=#{symbol} interval=#{interval} ticks=#{ticks.size}>"
end

#limit(period) ⇒ Object



70
71
72
73
74
75
# File 'lib/quant/series.rb', line 70

def limit(period)
  selected_ticks = ticks.select{ |tick| period.cover?(tick.close_timestamp) }
  return self if selected_ticks.size == ticks.size

  self.class.from_ticks(symbol: symbol, interval: interval, ticks: selected_ticks)
end

#limit_iterations(start_iteration, stop_iteration) ⇒ Object



63
64
65
66
67
68
# File 'lib/quant/series.rb', line 63

def limit_iterations(start_iteration, stop_iteration)
  selected_ticks = ticks[start_iteration..stop_iteration]
  return self if selected_ticks.size == ticks.size

  self.class.from_ticks(symbol: symbol, interval: interval, ticks: selected_ticks)
end

#lowestObject



88
89
90
# File 'lib/quant/series.rb', line 88

def lowest
  ticks.min_by(&:low_price)
end

#to_hObject



115
116
117
118
119
# File 'lib/quant/series.rb', line 115

def to_h
  { "symbol" => symbol,
    "interval" => interval,
    "ticks" => ticks.map(&:to_h) }
end

#to_json(*args) ⇒ Object



121
122
123
# File 'lib/quant/series.rb', line 121

def to_json(*args)
  Oj.dump(to_h, *args)
end