-
-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add historical prices api endpoint #94
Changes from all commits
a8aa3d1
4af2815
becd9f6
ffb1a43
5736a44
64c8266
1b1a0be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
module IEX | ||
module Endpoints | ||
module HistoricalPrices | ||
def historical_prices(symbol, options = {}) | ||
if options[:range] == 'date' | ||
raise ArgumentError unless options[:date].present? | ||
raise ArgumentError unless options[:chartByDay].present? | ||
end | ||
|
||
options = options.dup | ||
# Historical prices IEX endpoint expects dates passed in a specific format - YYYYMMDD | ||
options[:date] = options[:date].strftime('%Y%m%d') if options[:date].is_a?(Date) | ||
|
||
path = "stock/#{symbol}/chart" | ||
path += "/#{options[:range]}" if options.key?(:range) | ||
path += "/#{options[:date]}" if options[:range] == 'date' | ||
|
||
# We only want options to include query params at this point, remove :range and :date | ||
options.delete(:range) | ||
options.delete(:date) | ||
|
||
(get(path, { token: publishable_token }.merge(options)) || []).map do |data| | ||
IEX::Resources::HistorialPrices.new(data) | ||
end | ||
rescue Faraday::ResourceNotFound => e | ||
raise IEX::Errors::SymbolNotFoundError.new(symbol, e.response[:body]) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module IEX | ||
module Resources | ||
class HistorialPrices < Resource | ||
property 'date' | ||
property 'open' | ||
property 'open_dollar', from: 'open', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'close' | ||
property 'close_dollar', from: 'close', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'high' | ||
property 'high_dollar', from: 'high', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'low' | ||
property 'low_dollar', from: 'low', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'volume' | ||
property 'u_open', from: 'uOpen' | ||
property 'u_open_dollar', from: 'uOpen', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'u_close', from: 'uClose' | ||
property 'u_close_dollar', from: 'uClose', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'u_low', from: 'uLow' | ||
property 'u_low_dollar', from: 'uLow', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'u_high', from: 'uHigh' | ||
property 'u_high_dollar', from: 'uHigh', with: ->(v) { to_dollar(amount: v, ignore_cents: false) } | ||
property 'u_volume', from: 'uVolume' | ||
property 'change' | ||
property 'change_percent', from: 'changePercent' | ||
property 'change_percent_s', from: 'changePercent', with: ->(v) { percentage_to_string(v) } | ||
property 'label' | ||
property 'change_over_time', from: 'changeOverTime' | ||
property 'change_over_time_s', from: 'changeOverTime', with: ->(v) { percentage_to_string(v) } | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,18 @@ def self.float_to_percentage(float_number) | |
].join | ||
end | ||
|
||
# Useful for values that are already a percent but we want to convert into a 2 decimal place string | ||
def self.percentage_to_string(float_percent) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is essentially a direct copy of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think copy paste is fine I wouldn't worry about it. |
||
return unless float_percent.is_a? Numeric | ||
return '+0.00%' if float_percent.zero? | ||
|
||
[ | ||
float_percent.positive? ? '+' : '', | ||
format('%.2f', float_percent), | ||
'%' | ||
].join | ||
end | ||
|
||
def self.to_dollar(amount:, ignore_cents: true) | ||
MoneyHelper.money_to_text(amount, 'USD', nil, no_cents: ignore_cents) | ||
end | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're modifying the hash passed in, so either
options = options.dup
, or use.except
or similar to get a copy without those keys. Let's make sure there are no other places where we did this, I may have missed that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see any downside to modifying it but happy to dup it if you prefer. This was the only place I did this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The downside is that code like this doesn't do what you'd expect it to do:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also use
options.key?(:range)
,nil
is a value and while it doesn't make sense you don't want the caller to rely on you clearing the option, this is more by conventionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup that's a downside. Thanks