lib/ib/eod.rb in ib-extensions-1.3 vs lib/ib/eod.rb in ib-extensions-1.3.1

- old
+ new

@@ -53,11 +53,11 @@ (whole_weeks * 5) + extra_days end end # Receive EOD-Data and store the data in the `:bars`-property of IB::Contract # - # contract.eod duration: {String or Integer}, start: {Date}, to: {Date} what: {see below} + # contract.eod duration: {String or Integer}, start: {Date}, to: {Date}, what: {see below}, polars: {true|false} # # # # The Enddate has to be specified (as Date Object), `:to`, default: Date.today # @@ -73,12 +73,12 @@ # :historical_volatility, :option_implied_volatility, # :option_volume, :option_open_interest # # Polars DataFrames # ----------------- - # The response is stored as PolarsDataframe - # for further processing: https://github.com/ankane/polars-ruby + # If »polars: true« is specified the response is stored as PolarsDataframe. + # For further processing: https://github.com/ankane/polars-ruby # https://pola-rs.github.io/polars/py-polars/html/index.html # # Error-handling # -------------- # * Basically all Errors simply lead to log-entries: @@ -100,11 +100,11 @@ # Thus, parallel requests of a single asset with different time-frames will fail # # Examples # -------- # - # puts Stock.new( symbol: :iwm).eod( start: Date.new(2019,10,9), duration: 3) + # puts Stock.new( symbol: :iwm).eod( start: Date.new(2019,10,9), duration: 3, polars: true) # shape: (3, 8) # ┌────────────┬────────┬────────┬────────┬────────┬────────┬─────────┬────────┐ # │ time ┆ open ┆ high ┆ low ┆ close ┆ volume ┆ wap ┆ trades │ # │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ # │ date ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ i64 ┆ f64 ┆ i64 │ @@ -112,11 +112,11 @@ # │ 2019-10-08 ┆ 148.62 ┆ 149.37 ┆ 146.11 ┆ 146.45 ┆ 156625 ┆ 146.831 ┆ 88252 │ # │ 2019-10-09 ┆ 147.18 ┆ 148.0 ┆ 145.38 ┆ 145.85 ┆ 94337 ┆ 147.201 ┆ 51294 │ # │ 2019-10-10 ┆ 146.9 ┆ 148.74 ┆ 146.87 ┆ 148.24 ┆ 134549 ┆ 147.792 ┆ 71084 │ # └────────────┴────────┴────────┴────────┴────────┴────────┴─────────┴────────┘ # - # puts Stock.new( symbol: :iwm).eod( start: Date.new(2021,10,9), duration: '3W') + # puts Stock.new( symbol: :iwm).eod( start: Date.new(2021,10,9), duration: '3W', polars: true) # shape: (3, 8) # ┌────────────┬────────┬────────┬────────┬────────┬─────────┬─────────┬────────┐ # │ time ┆ open ┆ high ┆ low ┆ close ┆ volume ┆ wap ┆ trades │ # │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ # │ date ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ i64 ┆ f64 ┆ i64 │ @@ -124,11 +124,11 @@ # │ 2021-10-01 ┆ 223.99 ┆ 227.68 ┆ 216.12 ┆ 222.8 ┆ 1295495 ┆ 222.226 ┆ 792711 │ # │ 2021-10-08 ┆ 221.4 ┆ 224.95 ┆ 216.76 ┆ 221.65 ┆ 1044233 ┆ 220.855 ┆ 621984 │ # │ 2021-10-15 ┆ 220.69 ┆ 228.41 ┆ 218.94 ┆ 225.05 ┆ 768065 ┆ 223.626 ┆ 437817 │ # └────────────┴────────┴────────┴────────┴────────┴─────────┴─────────┴────────┘ # - # puts Stock.new( symbol: :iwm).eod( start: Date.new(2022,10,1), duration: '3M') + # puts Stock.new( symbol: :iwm).eod( start: Date.new(2022,10,1), duration: '3M', polars: true) # shape: (3, 8) # ┌────────────┬────────┬────────┬────────┬────────┬─────────┬─────────┬─────────┐ # │ time ┆ open ┆ high ┆ low ┆ close ┆ volume ┆ wap ┆ trades │ # │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ # │ date ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ i64 ┆ f64 ┆ i64 │ @@ -136,11 +136,11 @@ # │ 2022-09-30 ┆ 181.17 ┆ 191.37 ┆ 162.77 ┆ 165.16 ┆ 4298969 ┆ 175.37 ┆ 2202407 │ # │ 2022-10-31 ┆ 165.5 ┆ 184.24 ┆ 162.5 ┆ 183.5 ┆ 4740014 ┆ 173.369 ┆ 2474286 │ # │ 2022-11-30 ┆ 184.51 ┆ 189.56 ┆ 174.11 ┆ 188.19 ┆ 3793861 ┆ 182.594 ┆ 1945674 │ # └────────────┴────────┴────────┴────────┴────────┴─────────┴─────────┴─────────┘ # - # puts Stock.new( symbol: :iwm).eod( start: Date.new(2020,1,1), duration: '3M', what: :option_implied_vol + # puts Stock.new( symbol: :iwm).eod( start: Date.new(2020,1,1), duration: '3M', what: :option_implied_vol, polars: true # atility ) # shape: (3, 8) # ┌────────────┬──────────┬──────────┬──────────┬──────────┬────────┬──────────┬────────┐ # │ time ┆ open ┆ high ┆ low ┆ close ┆ volume ┆ wap ┆ trades │ # │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ @@ -149,11 +149,11 @@ # │ 2019-12-31 ┆ 0.134933 ┆ 0.177794 ┆ 0.115884 ┆ 0.138108 ┆ 0 ┆ 0.178318 ┆ 0 │ # │ 2020-01-31 ┆ 0.139696 ┆ 0.190494 ┆ 0.120646 ┆ 0.185732 ┆ 0 ┆ 0.19097 ┆ 0 │ # │ 2020-02-28 ┆ 0.185732 ┆ 0.436549 ┆ 0.134933 ┆ 0.39845 ┆ 0 ┆ 0.435866 ┆ 0 │ # └────────────┴──────────┴──────────┴──────────┴──────────┴────────┴──────────┴────────┘ # - def eod start: nil, to: nil, duration: nil , what: :trades + def eod start: nil, to: nil, duration: nil , what: :trades, polars: false # error "EOD:: Start-Date (parameter: to) must be a Date-Object" unless to.is_a? Date normalize_duration = ->(d) do if d.is_a?(Integer) || !["D","M","W","Y"].include?( d[-1].upcase ) d.to_i.to_s + "D" @@ -164,28 +164,28 @@ get_end_date = -> do d = normalize_duration.call(duration) case d[-1] when "D" - start + d.to_i - 1 + start + d.to_i - 1 when 'W' Date.commercial( start.year, start.cweek + d.to_i - 1, 1) when 'M' Date.new( start.year, start.month + d.to_i - 1 , start.day ) end end if to.nil? - # case eod start= Date.new ... + # case eod start= Date.new ... to = if start.present? && duration.nil? - # case eod start= Date.new + # case eod start= Date.new duration = BuisinesDays.business_days_between(start, to).to_s + "D" Date.today # assign to var: to elsif start.present? && duration.present? # case eod start= Date.new , duration: 'nN' get_end_date.call # assign to var: to - elsif duration.present? + elsif duration.present? # case start is not present, we are collecting until the present day Date.today # assign to var: to else duration = "1D" Date.today @@ -200,11 +200,11 @@ else :day1 end - get_bars(to.to_time.to_ib , normalize_duration[duration], barsize, what) + get_bars(to.to_time.to_ib , normalize_duration[duration], barsize, what, polars) end # def # creates (or overwrites) the specified file (or symbol.csv) and saves bar-data def to_csv file: "#{symbol}.csv" @@ -221,19 +221,23 @@ CSV.foreach( file, headers: true, header_converters: :symbol) do |row| self.bars << IB::Bar.new( **row.to_h ) end end - def get_bars(end_date_time, duration, bar_size, what_to_show) + def get_bars(end_date_time, duration, bar_size, what_to_show, polars) tws = IB::Connection.current received = Queue.new r = nil # the hole response is transmitted at once! a = tws.subscribe(IB::Messages::Incoming::HistoricalData) do |msg| if msg.request_id == con_id - # msg.results.each { |entry| puts " #{entry}" } - self.bars = Polars::DataFrame.new msg.results.map( &:invariant_attributes ) + self.bars = if polars + # msg.results.each { |entry| puts " #{entry}" } + Polars::DataFrame.new msg.results.map( &:invariant_attributes ) + else + msg.results + end end received.push Time.now end b = tws.subscribe( IB::Messages::Incoming::Alert) do |msg| if [321,162,200].include? msg.code