Class: Quant::Interval
- Inherits:
-
Object
- Object
- Quant::Interval
- Defined in:
- lib/quant/interval.rb
Overview
Quant::Interval abstracts away the concept of ticks (candles, bars, etc.) and their duration and offers some basic utilities for working with multiple timeframes. Intervals are used in Tick and Series classes to define the duration of the ticks.
When the Interval is unknown, it is set to ‘na’ (not available) and the duration is set to 0. The shorthand for this is Interval.na. and Interval[:na]. and Interval[nil].
Interval are instantiated in multple ways to support a wide variety of use-cases. Here’s an example:
Quant::Interval.new("1d") # => #<Quant::Interval @interval="1d"> (daily interval)
Quant::Interval.new(:daily) # => #<Quant::Interval @interval="1d">
Quant::Interval[:daily] # => #<Quant::Interval @interval="1d">
Quant::Interval.from_resolution(60) # => #<Quant::Interval @interval="1h">
Quant::Interval.from_resolution("1D") # => #<Quant::Interval @interval="1d">
Quant::Interval.from_resolution("D") # => #<Quant::Interval @interval="1d">
Intervals have a number of useful methods:
interval = Quant::Interval.new("1d") # => #<Quant::Interval @interval="1d"> (daily interval)
interval.nil? # => false
interval.duration # => 86400
interval.ticks_per_minute # => 0.0006944444444444445
interval.half_life # => 43200.0
interval.next_interval # => #<Quant::Interval @interval="1w"> (weekly interval)
When you don’t wish to specify an interval or it is unknown, you can use the na interval:
interval = Quant::Interval.na # => #<Quant::Interval @interval="na">
interval.nil? # => true
interval.duration # => 0
Constant Summary collapse
- MAPPINGS =
{ na: { interval: "na", distance: 0 }, second: { interval: "1s", distance: 1 }, two_seconds: { interval: "2s", distance: 2 }, three_seconds: { interval: "3s", distance: 3 }, five_seconds: { interval: "5s", distance: 5 }, ten_seconds: { interval: "10s", distance: 10 }, fifteen_seconds: { interval: "15s", distance: 15 }, thirty_seconds: { interval: "30s", distance: 30 }, minute: { interval: "1m", distance: 60 }, one_minute: { interval: "1m", distance: 60 }, three_minutes: { interval: "3m", distance: 60 * 3 }, five_minutes: { interval: "5m", distance: 60 * 5 }, fifteen_minutes: { interval: "15", distance: 60 * 15 }, thirty_minutes: { interval: "30", distance: 60 * 30 }, hour: { interval: "1h", distance: 60 * 60 }, two_hours: { interval: "2h", distance: 60 * 60 * 2 }, four_hours: { interval: "4h", distance: 60 * 60 * 4 }, eight_hours: { interval: "8h", distance: 60 * 60 * 8 }, twelve_hours: { interval: "12h", distance: 60 * 60 * 12 }, daily: { interval: "1d", distance: 60 * 60 * 24 }, weekly: { interval: "1w", distance: 60 * 60 * 24 * 7 }, monthly: { interval: "1M", distance: 60 * 60 * 24 * 30 }, }.freeze
- INTERVAL_DISTANCE =
MAPPINGS.values.map { |v| [v[:interval], v[:distance]] }.to_h.freeze
- RESOLUTIONS =
{ "1" => :one_minute, "3" => :three_minutes, "5" => :five_minutes, "15" => :fifteen_minutes, "30" => :thirty_minutes, "60" => :hour, "240" => :four_hours, "D" => :daily, "1D" => :daily, }.freeze
Instance Attribute Summary collapse
-
#interval ⇒ Object
readonly
Returns the value of attribute interval.
Class Method Summary collapse
-
.[](value) ⇒ Object
Instantiates an Interval from a string or symbol.
- .all_resolutions ⇒ Object
- .ensure_valid_resolution!(resolution) ⇒ Object
-
.from_mappings(value) ⇒ Object
Looks up the given mapping (i.e. :daily) and returns the Interval for that mapping.
-
.from_resolution(resolution) ⇒ Object
Instantiates an Interval from a resolution.
- .valid_intervals ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #duration ⇒ Object (also: #seconds)
- #half_life ⇒ Object
-
#initialize(interval) ⇒ Interval
constructor
A new instance of Interval.
-
#next_interval ⇒ Object
Returns the Interval for the next higher timeframe.
- #nil? ⇒ Boolean
- #ticks_per_minute ⇒ Object
-
#ticks_to(timestamp) ⇒ Object
NOTE: if timestamp doesn’t cover a full interval, it will be rounded up to 1.
- #timestamp_for(ticks:, timestamp: Quant.current_time) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(interval) ⇒ Interval
Returns a new instance of Interval.
150 151 152 153 154 |
# File 'lib/quant/interval.rb', line 150 def initialize(interval) ensure_valid_interval!(interval) @interval = (interval || "na").to_s end |
Instance Attribute Details
#interval ⇒ Object (readonly)
Returns the value of attribute interval.
148 149 150 |
# File 'lib/quant/interval.rb', line 148 def interval @interval end |
Class Method Details
.[](value) ⇒ Object
Instantiates an Interval from a string or symbol. If the value is already an Interval, it is returned as-is.
134 135 136 137 138 |
# File 'lib/quant/interval.rb', line 134 def self.[](value) return value if value.is_a? Interval from_mappings(value) || Interval.new(value) end |
.all_resolutions ⇒ Object
119 120 121 |
# File 'lib/quant/interval.rb', line 119 def self.all_resolutions RESOLUTIONS.keys end |
.ensure_valid_resolution!(resolution) ⇒ Object
209 210 211 212 213 |
# File 'lib/quant/interval.rb', line 209 def self.ensure_valid_resolution!(resolution) return if RESOLUTIONS.keys.include? resolution raise InvalidResolution, "resolution (#{resolution}) not a valid resolution. Should be one of: (#{RESOLUTIONS.keys.join(", ")})" end |
.from_mappings(value) ⇒ Object
Looks up the given mapping (i.e. :daily) and returns the Interval for that mapping.
141 142 143 144 145 146 |
# File 'lib/quant/interval.rb', line 141 def self.from_mappings(value) mapping = MAPPINGS[value&.to_sym] return unless mapping Interval.new(mapping[:interval]) end |
.from_resolution(resolution) ⇒ Object
Instantiates an Interval from a resolution. For example, TradingView uses resolutions like “1”, “3”, “5”, “15”, “30”, “60”, “240”, “D”, “1D” to represent the duration of a candlestick. from_resolution translates resolutions to the appropriate Interval.
126 127 128 129 130 |
# File 'lib/quant/interval.rb', line 126 def self.from_resolution(resolution) ensure_valid_resolution!(resolution) Interval.new(MAPPINGS[RESOLUTIONS[resolution]][:interval]) end |
.valid_intervals ⇒ Object
196 197 198 |
# File 'lib/quant/interval.rb', line 196 def self.valid_intervals INTERVAL_DISTANCE.keys end |
Instance Method Details
#==(other) ⇒ Object
169 170 171 172 173 174 175 176 177 |
# File 'lib/quant/interval.rb', line 169 def ==(other) if other.is_a? String interval.to_s == other elsif other.is_a? Symbol interval == MAPPINGS[other]&.fetch(:interval, nil) else interval == other&.interval end end |
#duration ⇒ Object Also known as: seconds
164 165 166 |
# File 'lib/quant/interval.rb', line 164 def duration INTERVAL_DISTANCE[interval] end |
#half_life ⇒ Object
183 184 185 186 187 |
# File 'lib/quant/interval.rb', line 183 def half_life raise "bad interval #{interval}" if duration.nil? duration / 2.0 end |
#next_interval ⇒ Object
Returns the Interval for the next higher timeframe. For example, hourly -> daily -> weekly -> monthly
191 192 193 194 |
# File 'lib/quant/interval.rb', line 191 def next_interval intervals = INTERVAL_DISTANCE.keys Interval.new intervals[intervals.index(interval) + 1] || intervals[-1] end |
#nil? ⇒ Boolean
156 157 158 |
# File 'lib/quant/interval.rb', line 156 def nil? interval == "na" end |
#ticks_per_minute ⇒ Object
179 180 181 |
# File 'lib/quant/interval.rb', line 179 def ticks_per_minute 60.0 / seconds end |
#ticks_to(timestamp) ⇒ Object
NOTE: if timestamp doesn’t cover a full interval, it will be rounded up to 1
201 202 203 |
# File 'lib/quant/interval.rb', line 201 def ticks_to() (( - Quant.current_time) / duration).round(2).ceil end |
#timestamp_for(ticks:, timestamp: Quant.current_time) ⇒ Object
205 206 207 |
# File 'lib/quant/interval.rb', line 205 def (ticks:, timestamp: Quant.current_time) + (ticks * duration) end |
#to_s ⇒ Object
160 161 162 |
# File 'lib/quant/interval.rb', line 160 def to_s interval end |