iron_warbler 2.0.7 → 2.0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/iron_warbler/alerts.css +4 -0
- data/app/assets/stylesheets/iron_warbler/application.css +4 -0
- data/app/assets/stylesheets/iron_warbler/datapoints.css +0 -0
- data/app/assets/stylesheets/iron_warbler/main.css +13 -0
- data/app/controllers/iro/alerts_controller.rb +21 -29
- data/app/controllers/iro/application_controller.rb +1 -0
- data/app/controllers/iro/datapoints_controller.rb +36 -0
- data/app/controllers/iro/profiles_controller.rb +2 -2
- data/app/controllers/iro/stocks_controller.rb +56 -0
- data/app/mailers/iro/alert_mailer.rb +12 -0
- data/app/models/iro/alert.rb +8 -1
- data/app/models/iro/datapoint.rb +5 -0
- data/app/models/iro/option.rb +7 -0
- data/app/models/iro/price_item.rb +4 -0
- data/app/models/iro/profile.rb +1 -1
- data/app/models/iro/stock.rb +18 -0
- data/app/models/tda/api.rb +48 -0
- data/app/views/iro/alert_mailer/stock_alert.haml +6 -0
- data/app/views/iro/alerts/_form.haml +35 -0
- data/app/views/iro/alerts/index.haml +9 -0
- data/app/views/iro/stocks/_form.haml +15 -0
- data/app/views/iro/stocks/index.haml +9 -0
- data/app/views/layouts/iro/application.haml +2 -2
- data/config/routes.rb +6 -2
- data/db/migrate/20231219204329_create_dates.rb +13 -0
- data/db/migrate/20231219205644_create_datapoint.rb +15 -0
- data/db/migrate/20231220193201_create_stocks.rb +11 -0
- data/db/migrate/20231220194903_add_alert_status.rb +5 -0
- data/db/migrate/20231220223730_create_iro_price_item.rb +57 -0
- data/lib/iro/engine.rb +7 -0
- data/lib/iron_warbler.rb +1 -4
- data/lib/tasks/db_tasks.rake +27 -0
- data/lib/tasks/iro_tasks.rake +38 -4
- metadata +38 -7
- data/app/helpers/iro/alerts_helper.rb +0 -4
- data/app/helpers/iro/profiles_helper.rb +0 -4
- data/app/views/iro/alerts/_form.html.erb +0 -47
- data/app/views/iro/alerts/index.html.erb +0 -37
- data/lib/iron_warbler/engine.rb +0 -8
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d2c0f62e19708995e8502435c211bfbc6fb4ce16267e58e2bff259fc67612790
         | 
| 4 | 
            +
              data.tar.gz: 51983a25aa8b6f044afb8806c820d15b86e2043b00b12bd99e700f9be6d01e07
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 0b6b12ec94c7299df53fe2e2c8c4d462f4097a49942738b3be80882bdb223c69782b745fc30e3e8aacfcff573919b558945e99910372e00f28748735c8bfb864
         | 
| 7 | 
            +
              data.tar.gz: 4a5f5e6e01b647cec8bafbad03736858b8cc830f6defe1472ab7d6356b3e6ed01385ee668193332c17241fcf33ef20da793da9222970b082f2b9e0e123f38b7f
         | 
| 
            File without changes
         | 
| @@ -1,58 +1,50 @@ | |
| 1 | 
            -
            require_dependency "iro/application_controller"
         | 
| 2 1 |  | 
| 2 | 
            +
            class Iro::AlertsController < Iro::ApplicationController
         | 
| 3 3 |  | 
| 4 | 
            -
             | 
| 5 | 
            -
              before_action :set_alert, only: [:show, :edit, :update, :destroy]
         | 
| 6 | 
            -
             | 
| 7 | 
            -
              def index
         | 
| 8 | 
            -
                @alerts = Iro::Alert.all
         | 
| 9 | 
            -
              end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              def show
         | 
| 12 | 
            -
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def new
         | 
| 15 | 
            -
                @alert = Iro::Alert.new
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              def edit
         | 
| 19 | 
            -
              end
         | 
| 4 | 
            +
              before_action :set_lists
         | 
| 20 5 |  | 
| 21 6 | 
             
              def create
         | 
| 22 7 | 
             
                @alert = Iro::Alert.new(alert_params)
         | 
| 23 | 
            -
             | 
| 24 8 | 
             
                if @alert.save
         | 
| 25 | 
            -
                  redirect_to  | 
| 9 | 
            +
                  redirect_to action: :index, notice: 'Alert was successfully created.'
         | 
| 26 10 | 
             
                else
         | 
| 27 11 | 
             
                  render :new
         | 
| 28 12 | 
             
                end
         | 
| 29 13 | 
             
              end
         | 
| 30 14 |  | 
| 15 | 
            +
              def destroy
         | 
| 16 | 
            +
                @alert = Iro::Alert.find(params[:id])
         | 
| 17 | 
            +
                @alert.destroy
         | 
| 18 | 
            +
                redirect_to action: :index, notice: 'Alert was successfully destroyed.'
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def index
         | 
| 22 | 
            +
                @alerts = Iro::Alert.all
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 31 25 | 
             
              def update
         | 
| 26 | 
            +
                @alert = Iro::Alert.find(params[:id])
         | 
| 32 27 | 
             
                if @alert.update(alert_params)
         | 
| 33 | 
            -
                  redirect_to  | 
| 28 | 
            +
                  redirect_to action: :index, notice: 'Alert was successfully updated.'
         | 
| 34 29 | 
             
                else
         | 
| 35 30 | 
             
                  render :edit
         | 
| 36 31 | 
             
                end
         | 
| 37 32 | 
             
              end
         | 
| 38 33 |  | 
| 39 | 
            -
              def destroy
         | 
| 40 | 
            -
                @alert.destroy
         | 
| 41 | 
            -
                redirect_to alerts_url, notice: 'Alert was successfully destroyed.'
         | 
| 42 | 
            -
              end
         | 
| 43 | 
            -
             | 
| 44 34 | 
             
              ##
         | 
| 45 35 | 
             
              ## private
         | 
| 46 36 | 
             
              ##
         | 
| 47 37 | 
             
              private
         | 
| 48 38 |  | 
| 49 | 
            -
              def set_alert
         | 
| 50 | 
            -
                @alert = Iro::Alert.find(params[:id])
         | 
| 51 | 
            -
              end
         | 
| 52 | 
            -
             | 
| 53 39 | 
             
              def alert_params
         | 
| 54 40 | 
             
                params.require(:alert).permit(:class_name, :kind, :symbol, :direction, :strike, :profile_id)
         | 
| 55 41 | 
             
              end
         | 
| 56 42 |  | 
| 43 | 
            +
              def set_lists
         | 
| 44 | 
            +
                # @profiles_list = Wco::Profile.list
         | 
| 45 | 
            +
                @stocks_list = [[nil,nil]] + Iro::Stock.active.map { |s| [ s.ticker, s.ticker ] }
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
             | 
| 57 49 | 
             
            end
         | 
| 58 50 |  | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            # require_dependency "iro/application_controller"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Iro::DatapointsController < Iro::ApplicationController
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              ## params: d, k, v
         | 
| 7 | 
            +
              def create
         | 
| 8 | 
            +
                begin
         | 
| 9 | 
            +
                  Iro::Datapoint.create( k: params[:k], v: params[:v], created_at: params[:time] )
         | 
| 10 | 
            +
                  render json: { status: :ok }
         | 
| 11 | 
            +
                rescue ActiveRecord::NotNullViolation => exception
         | 
| 12 | 
            +
                  render json: { status: :unauthorized }, status: :unauthorized
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def index
         | 
| 17 | 
            +
                # from = '2023-12-20'
         | 
| 18 | 
            +
                # to = '2023-12-01'
         | 
| 19 | 
            +
                # points = Iro::Datapoint.where( k: params[:k] ).joins( :dates )
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                sql = "SELECT
         | 
| 22 | 
            +
                  dps.k, dps.v, d.date
         | 
| 23 | 
            +
                FROM
         | 
| 24 | 
            +
                  iro_datapoints as dps
         | 
| 25 | 
            +
                  RIGHT JOIN dates d ON d.date = dps.d WHERE d.date BETWEEN '2023-12-01' AND '2023-12-31'
         | 
| 26 | 
            +
                ORDER BY
         | 
| 27 | 
            +
                  d.date;"
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                outs = ActiveRecord::Base.connection.execute(sql)
         | 
| 30 | 
            +
                puts! outs, 'outs'
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                render json: outs
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            end
         | 
| @@ -1,7 +1,7 @@ | |
| 1 | 
            -
            require_dependency "iro/application_controller"
         | 
| 2 1 |  | 
| 2 | 
            +
            # require_dependency "iro/application_controller"
         | 
| 3 3 |  | 
| 4 | 
            -
            class Iro::ProfilesController < ApplicationController
         | 
| 4 | 
            +
            class Iro::ProfilesController < Iro::ApplicationController
         | 
| 5 5 | 
             
              before_action :set_profile, only: [:show, :edit, :update, :destroy]
         | 
| 6 6 |  | 
| 7 7 | 
             
              # GET /profiles
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            class Iro::StocksController < Iro::ApplicationController
         | 
| 3 | 
            +
              before_action :set_stock, only: [:show, :edit, :update, :destroy]
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def index
         | 
| 6 | 
            +
                @stocks = Iro::Stock.all
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def show
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def new
         | 
| 13 | 
            +
                @stock = Iro::Stock.new
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def edit
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def create
         | 
| 20 | 
            +
                @stock = Iro::Stock.new(stock_params)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                if @stock.save
         | 
| 23 | 
            +
                  redirect_to action: :index, notice: 'Stock was successfully created.'
         | 
| 24 | 
            +
                else
         | 
| 25 | 
            +
                  render :new
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def update
         | 
| 30 | 
            +
                if @stock.update(stock_params)
         | 
| 31 | 
            +
                  redirect_to @stock, notice: 'Stock was successfully updated.'
         | 
| 32 | 
            +
                else
         | 
| 33 | 
            +
                  render :edit
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              def destroy
         | 
| 38 | 
            +
                @stock.destroy
         | 
| 39 | 
            +
                redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              ##
         | 
| 43 | 
            +
              ## private
         | 
| 44 | 
            +
              ##
         | 
| 45 | 
            +
              private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              def set_stock
         | 
| 48 | 
            +
                @stock = Iro::Stock.find(params[:id])
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              def stock_params
         | 
| 52 | 
            +
                params.require(:stock).permit!
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            end
         | 
| 56 | 
            +
             | 
    
        data/app/models/iro/alert.rb
    CHANGED
    
    | @@ -1,4 +1,11 @@ | |
| 1 1 |  | 
| 2 | 
            -
            class Iro::Alert < ApplicationRecord
         | 
| 2 | 
            +
            class Iro::Alert < Iro::ApplicationRecord
         | 
| 3 3 | 
             
              self.table_name = 'iro_alerts'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              DIRECTION_ABOVE = 'ABOVE'
         | 
| 6 | 
            +
              DIRECTION_BELOW = 'BELOW'
         | 
| 7 | 
            +
              def self.directions_list
         | 
| 8 | 
            +
                [ nil, DIRECTION_ABOVE, DIRECTION_BELOW ]
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 4 11 | 
             
            end
         | 
    
        data/app/models/iro/profile.rb
    CHANGED
    
    
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            ##
         | 
| 3 | 
            +
            ## SQL
         | 
| 4 | 
            +
            ##
         | 
| 5 | 
            +
            class Iro::Stock < Iro::ApplicationRecord
         | 
| 6 | 
            +
              self.table_name = 'iro_stocks'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              STATUS_ACTIVE   = 'active'
         | 
| 9 | 
            +
              STATUS_INACTIVE = 'inactive'
         | 
| 10 | 
            +
              STATUSES        = [ 'active', 'inactive' ]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              validates :ticker, uniqueness: true, presence: true
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def self.active
         | 
| 15 | 
            +
                where( status: STATUS_ACTIVE )
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            require 'httparty'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Tda::Api
         | 
| 5 | 
            +
              include ::HTTParty
         | 
| 6 | 
            +
              base_uri 'https://api.tdameritrade.com'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              ## alias
         | 
| 9 | 
            +
              def self.get_quote which
         | 
| 10 | 
            +
                self.get_quotes( which )[0]
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              ## tickers = "GME"
         | 
| 14 | 
            +
              ## tickers = "NVDA,GME"
         | 
| 15 | 
            +
              def self.get_quotes tickers
         | 
| 16 | 
            +
                path = "/v1/marketdata/quotes"
         | 
| 17 | 
            +
                inns = self.get path, { query: { apikey: ::TD_AMERITRADE[:apiKey], symbol: tickers } }
         | 
| 18 | 
            +
                inns = inns.parsed_response
         | 
| 19 | 
            +
                inns.each do |k, v|
         | 
| 20 | 
            +
                  inns[k] = v.deep_symbolize_keys
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                outs = []
         | 
| 23 | 
            +
                inns.each do |symbol, obj|
         | 
| 24 | 
            +
                  outs.push ::Iro::PriceItem.create!({
         | 
| 25 | 
            +
                    putCall:        'STOCK',
         | 
| 26 | 
            +
                    symbol:          symbol,
         | 
| 27 | 
            +
                    ticker:          symbol,
         | 
| 28 | 
            +
                    bid:             obj[:bidPrice],
         | 
| 29 | 
            +
                    bidSize:         obj[:bidSize],
         | 
| 30 | 
            +
                    ask:             obj[:askPrice],
         | 
| 31 | 
            +
                    askSize:         obj[:askSize],
         | 
| 32 | 
            +
                    last:            obj[:lastPrice],
         | 
| 33 | 
            +
                    openPrice:       obj[:openPrice],
         | 
| 34 | 
            +
                    closePrice:      obj[:closePrice],
         | 
| 35 | 
            +
                    highPrice:       obj[:highPrice],
         | 
| 36 | 
            +
                    lowPrice:        obj[:lowPrice],
         | 
| 37 | 
            +
                    quoteTimeInLong: obj[:quoteTimeInLong],
         | 
| 38 | 
            +
                    timestamp:       Time.at( obj[:quoteTimeInLong]/1000 ),
         | 
| 39 | 
            +
                    totalVolume:     obj[:totalVolume],
         | 
| 40 | 
            +
                    mark:            obj[:mark],
         | 
| 41 | 
            +
                    exchangeName:    obj[:exchangeName],
         | 
| 42 | 
            +
                    volatility:      obj[:volatility],
         | 
| 43 | 
            +
                  })
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
                return outs
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            .iro-alerts--form.flex-row
         | 
| 3 | 
            +
              .w-min-50px
         | 
| 4 | 
            +
                - if !alert.new_record?
         | 
| 5 | 
            +
                  = button_to '[x]', alert_path( alert ), method: :delete, data: { confirm: 'Are you sure?' }
         | 
| 6 | 
            +
                - else
         | 
| 7 | 
            +
                   
         | 
| 8 | 
            +
              = form_for alert do |f|
         | 
| 9 | 
            +
                .flex-row
         | 
| 10 | 
            +
                  .field
         | 
| 11 | 
            +
                    - if alert.new_record?
         | 
| 12 | 
            +
                      %label New
         | 
| 13 | 
            +
                    - else
         | 
| 14 | 
            +
                      = f.select :status, options_for_select([ 'active', 'inactive' ], selected: alert.status )
         | 
| 15 | 
            +
                  -# .field
         | 
| 16 | 
            +
                  -#   %label Notify
         | 
| 17 | 
            +
                  -#   = f.select :profile_id, options_for_select( @profiles_list, selected: alert.profile_id )
         | 
| 18 | 
            +
                  .field
         | 
| 19 | 
            +
                    %label When
         | 
| 20 | 
            +
                    = f.select :class_name, options_for_select([ nil, 'Iro::Stock', 'Iro::Option' ])
         | 
| 21 | 
            +
                  -# .field
         | 
| 22 | 
            +
                  -#   = f.label :kind
         | 
| 23 | 
            +
                  -#   = f.text_field :kind
         | 
| 24 | 
            +
                  .field
         | 
| 25 | 
            +
                    = f.label :symbol
         | 
| 26 | 
            +
                    = f.select :symbol, options_for_select( @stocks_list, selected: alert.symbol )
         | 
| 27 | 
            +
                  .field
         | 
| 28 | 
            +
                    = f.label :direction
         | 
| 29 | 
            +
                    = f.select :direction, options_for_select([ :ABOVE, :BELOW ], selected: alert.direction)
         | 
| 30 | 
            +
                  .field
         | 
| 31 | 
            +
                    = f.label :strike
         | 
| 32 | 
            +
                    = f.text_field :strike
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  .actions
         | 
| 35 | 
            +
                    = f.submit
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            .iro-stocks--form
         | 
| 3 | 
            +
              = form_for stock do |f|
         | 
| 4 | 
            +
                .flex-row
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  .field
         | 
| 7 | 
            +
                    - if stock.new_record?
         | 
| 8 | 
            +
                      %label New
         | 
| 9 | 
            +
                    - else
         | 
| 10 | 
            +
                      = f.select :status, options_for_select([ Iro::Stock::STATUS_ACTIVE, Iro::Stock::STATUS_INACTIVE ], selected: stock.status)
         | 
| 11 | 
            +
                  .field
         | 
| 12 | 
            +
                    = f.label :ticker
         | 
| 13 | 
            +
                    = f.text_field :ticker
         | 
| 14 | 
            +
                  .actions
         | 
| 15 | 
            +
                    = f.submit
         | 
| @@ -11,8 +11,8 @@ | |
| 11 11 | 
             
                  %h5 Main Menu
         | 
| 12 12 | 
             
                  %ul
         | 
| 13 13 | 
             
                    %li= link_to 'Home - Dashboard', root_path
         | 
| 14 | 
            -
                    %li= link_to ' | 
| 15 | 
            -
                    %li= link_to ' | 
| 14 | 
            +
                    %li= link_to 'Stocks', stocks_path
         | 
| 15 | 
            +
                    -# %li= link_to 'Options', options_path
         | 
| 16 16 | 
             
                    %li Max Pain
         | 
| 17 17 | 
             
                    %li= link_to 'Alerts', alerts_path
         | 
| 18 18 | 
             
                = yield
         | 
    
        data/config/routes.rb
    CHANGED
    
    | @@ -1,10 +1,14 @@ | |
| 1 | 
            -
            IronWarbler::Engine.routes.draw do
         | 
| 2 1 |  | 
| 2 | 
            +
            Iro::Engine.routes.draw do
         | 
| 3 3 | 
             
              root to: '/iro/application#home'
         | 
| 4 4 |  | 
| 5 5 | 
             
              resources :alerts
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              post 'datapoints', to: '/iro/datapoints#create'
         | 
| 8 | 
            +
              get  'datapoints', to: '/iro/datapoints#index'
         | 
| 9 | 
            +
             | 
| 6 10 | 
             
              resources :option_watches
         | 
| 7 11 | 
             
              resources :profiles
         | 
| 8 | 
            -
              resources : | 
| 12 | 
            +
              resources :stocks
         | 
| 9 13 |  | 
| 10 14 | 
             
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            class CreateIroPriceItem < ActiveRecord::Migration[6.1]
         | 
| 2 | 
            +
              def change
         | 
| 3 | 
            +
                create_table :iro_price_items do |t|
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  t.string "putCall", index: true
         | 
| 6 | 
            +
                  t.string "symbol", index: true
         | 
| 7 | 
            +
                  t.string "description"
         | 
| 8 | 
            +
                  t.string "exchangeName"
         | 
| 9 | 
            +
                  t.string "bidAskSize"
         | 
| 10 | 
            +
                  t.string "expirationType"
         | 
| 11 | 
            +
                  t.float "bid"
         | 
| 12 | 
            +
                  t.float "ask"
         | 
| 13 | 
            +
                  t.float "last"
         | 
| 14 | 
            +
                  t.float "mark"
         | 
| 15 | 
            +
                  t.float "lastPrice"
         | 
| 16 | 
            +
                  t.float "highPrice"
         | 
| 17 | 
            +
                  t.float "lowPrice"
         | 
| 18 | 
            +
                  t.float "openPrice"
         | 
| 19 | 
            +
                  t.float "closePrice"
         | 
| 20 | 
            +
                  t.float "netChange"
         | 
| 21 | 
            +
                  t.float "volatility"
         | 
| 22 | 
            +
                  t.float "delta"
         | 
| 23 | 
            +
                  t.float "gamma"
         | 
| 24 | 
            +
                  t.float "theta"
         | 
| 25 | 
            +
                  t.float "vega"
         | 
| 26 | 
            +
                  t.float "rho"
         | 
| 27 | 
            +
                  t.float "timeValue"
         | 
| 28 | 
            +
                  t.float "theoreticalOptionValue"
         | 
| 29 | 
            +
                  t.float "theoreticalVolatility"
         | 
| 30 | 
            +
                  t.float "strikePrice"
         | 
| 31 | 
            +
                  t.float "percentChange"
         | 
| 32 | 
            +
                  t.float "markChange"
         | 
| 33 | 
            +
                  t.float "markPercentChange"
         | 
| 34 | 
            +
                  t.float "intrinsicValue"
         | 
| 35 | 
            +
                  t.float "multiplier"
         | 
| 36 | 
            +
                  t.integer "bidSize"
         | 
| 37 | 
            +
                  t.integer "askSize"
         | 
| 38 | 
            +
                  t.bigint "totalVolume"
         | 
| 39 | 
            +
                  t.integer "openInterest"
         | 
| 40 | 
            +
                  t.integer "daysToExpiration"
         | 
| 41 | 
            +
                  t.bigint "tradeTimeInLong"
         | 
| 42 | 
            +
                  t.bigint "quoteTimeInLong"
         | 
| 43 | 
            +
                  t.bigint "expirationDate", index: true
         | 
| 44 | 
            +
                  t.bigint "lastTradingDay"
         | 
| 45 | 
            +
                  t.boolean "inTheMoney"
         | 
| 46 | 
            +
                  t.boolean "nonStandard"
         | 
| 47 | 
            +
                  t.boolean "isIndexOption"
         | 
| 48 | 
            +
                  t.date "tradeDate"
         | 
| 49 | 
            +
                  t.string "interval"
         | 
| 50 | 
            +
                  t.string "ticker", limit: 32, index: true
         | 
| 51 | 
            +
                  t.timestamp "timestamp"
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  t.timestamps
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
             | 
    
        data/lib/iro/engine.rb
    ADDED
    
    
    
        data/lib/iron_warbler.rb
    CHANGED
    
    
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            namespace :db do
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              desc 'create calendar'
         | 
| 5 | 
            +
              task create_calendar: :environment do
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                year = 2023
         | 
| 8 | 
            +
                d = "#{year}-01-01".to_date
         | 
| 9 | 
            +
                out = ""
         | 
| 10 | 
            +
                368.times do
         | 
| 11 | 
            +
                  if d.strftime('%Y').to_i == year+1
         | 
| 12 | 
            +
                    break
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                  out = "#{out} ('#{d.strftime '%Y-%m-%d'}'),"
         | 
| 15 | 
            +
                  d = d + 1.day
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                out = out[0...out.length-1]
         | 
| 18 | 
            +
                out = "
         | 
| 19 | 
            +
                INSERT INTO
         | 
| 20 | 
            +
                  dates (date)
         | 
| 21 | 
            +
                VALUES
         | 
| 22 | 
            +
                  #{out} ;"
         | 
| 23 | 
            +
                File.write("/opt/tmp/#{year}_calendar.sql", out)
         | 
| 24 | 
            +
                `mv /opt/tmp/#{year}_calendar.sql doc/`
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        data/lib/tasks/iro_tasks.rake
    CHANGED
    
    | @@ -1,4 +1,38 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 1 | 
            +
             | 
| 2 | 
            +
            namespace :iro do
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              desc 'watch stocks'
         | 
| 5 | 
            +
              task watch_stocks: :environment do
         | 
| 6 | 
            +
                while true
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  begin
         | 
| 9 | 
            +
                    Timeout::timeout( 10 ) do
         | 
| 10 | 
            +
                      TDA::Api.get_quotes Iro::Stock.active.map(&:ticker).join(",")
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  rescue Exception => e
         | 
| 13 | 
            +
                    puts! e, 'Error in iro:watch_stocks'
         | 
| 14 | 
            +
                    # Wco::Exceptionist.notify(e, 'Error in iro:watch_stocks')
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  sleep Iro::Stock::SLEEP_TIME_SECONDS
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              desc 'alerts'
         | 
| 22 | 
            +
              task alerts: :environment do
         | 
| 23 | 
            +
                while true
         | 
| 24 | 
            +
                  Iro::Alert.active.each do |alert|
         | 
| 25 | 
            +
                    # price = Iro::Stock.latest( alert.ticker ).price
         | 
| 26 | 
            +
                    price = Tda::Api.get_quote( alert.symbol ).last
         | 
| 27 | 
            +
                    if  alert.direction == Iro::Alert::DIRECTION_ABOVE && price >= alert.strike ||
         | 
| 28 | 
            +
                        alert.direction == Iro::Alert::DIRECTION_BELOW && price <= alert.strike
         | 
| 29 | 
            +
                      Iro::AlertMailer.stock_alert( alert ).deliver_later
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                  sleep Iro::Alert::SLEEP_TIME_SECONDS
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
             | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: iron_warbler
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0.7
         | 
| 4 | 
            +
              version: 2.0.7.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Victor Pudeyev
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023-12- | 
| 11 | 
            +
            date: 2023-12-20 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rails
         | 
| @@ -94,6 +94,20 @@ dependencies: | |
| 94 94 | 
             
                - - "~>"
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 96 | 
             
                    version: 5.2.0
         | 
| 97 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            +
              name: sass-rails
         | 
| 99 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 | 
            +
                requirements:
         | 
| 101 | 
            +
                - - "~>"
         | 
| 102 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            +
                    version: 6.0.0
         | 
| 104 | 
            +
              type: :runtime
         | 
| 105 | 
            +
              prerelease: false
         | 
| 106 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 | 
            +
                requirements:
         | 
| 108 | 
            +
                - - "~>"
         | 
| 109 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            +
                    version: 6.0.0
         | 
| 97 111 | 
             
            description: A stocks and Options Trading Bot.
         | 
| 98 112 | 
             
            email: victor@wasya.co
         | 
| 99 113 | 
             
            executables: []
         | 
| @@ -104,22 +118,31 @@ files: | |
| 104 118 | 
             
            - app/assets/config/iron_warbler_manifest.js
         | 
| 105 119 | 
             
            - app/assets/stylesheets/iron_warbler/alerts.css
         | 
| 106 120 | 
             
            - app/assets/stylesheets/iron_warbler/application.css
         | 
| 121 | 
            +
            - app/assets/stylesheets/iron_warbler/datapoints.css
         | 
| 122 | 
            +
            - app/assets/stylesheets/iron_warbler/main.css
         | 
| 107 123 | 
             
            - app/assets/stylesheets/iron_warbler/profiles.css
         | 
| 108 124 | 
             
            - app/assets/stylesheets/scaffold.css
         | 
| 109 125 | 
             
            - app/controllers/iro/alerts_controller.rb
         | 
| 110 126 | 
             
            - app/controllers/iro/application_controller.rb
         | 
| 127 | 
            +
            - app/controllers/iro/datapoints_controller.rb
         | 
| 111 128 | 
             
            - app/controllers/iro/profiles_controller.rb
         | 
| 112 | 
            -
            - app/ | 
| 129 | 
            +
            - app/controllers/iro/stocks_controller.rb
         | 
| 113 130 | 
             
            - app/helpers/iro/application_helper.rb
         | 
| 114 | 
            -
            - app/helpers/iro/profiles_helper.rb
         | 
| 115 131 | 
             
            - app/jobs/iro/application_job.rb
         | 
| 132 | 
            +
            - app/mailers/iro/alert_mailer.rb
         | 
| 116 133 | 
             
            - app/mailers/iro/application_mailer.rb
         | 
| 117 134 | 
             
            - app/models/iro/alert.rb
         | 
| 118 135 | 
             
            - app/models/iro/application_record.rb
         | 
| 136 | 
            +
            - app/models/iro/datapoint.rb
         | 
| 137 | 
            +
            - app/models/iro/option.rb
         | 
| 138 | 
            +
            - app/models/iro/price_item.rb
         | 
| 119 139 | 
             
            - app/models/iro/profile.rb
         | 
| 120 | 
            -
            - app/ | 
| 140 | 
            +
            - app/models/iro/stock.rb
         | 
| 141 | 
            +
            - app/models/tda/api.rb
         | 
| 142 | 
            +
            - app/views/iro/alert_mailer/stock_alert.haml
         | 
| 143 | 
            +
            - app/views/iro/alerts/_form.haml
         | 
| 121 144 | 
             
            - app/views/iro/alerts/edit.html.erb
         | 
| 122 | 
            -
            - app/views/iro/alerts/index. | 
| 145 | 
            +
            - app/views/iro/alerts/index.haml
         | 
| 123 146 | 
             
            - app/views/iro/alerts/new.html.erb
         | 
| 124 147 | 
             
            - app/views/iro/alerts/show.html.erb
         | 
| 125 148 | 
             
            - app/views/iro/application/home.haml
         | 
| @@ -128,12 +151,20 @@ files: | |
| 128 151 | 
             
            - app/views/iro/profiles/index.html.erb
         | 
| 129 152 | 
             
            - app/views/iro/profiles/new.html.erb
         | 
| 130 153 | 
             
            - app/views/iro/profiles/show.html.erb
         | 
| 154 | 
            +
            - app/views/iro/stocks/_form.haml
         | 
| 155 | 
            +
            - app/views/iro/stocks/index.haml
         | 
| 131 156 | 
             
            - app/views/layouts/iro/application.haml
         | 
| 132 157 | 
             
            - config/routes.rb
         | 
| 133 158 | 
             
            - db/migrate/20231210204830_create_iro_profiles.rb
         | 
| 134 159 | 
             
            - db/migrate/20231210205837_create_iro_alerts.rb
         | 
| 160 | 
            +
            - db/migrate/20231219204329_create_dates.rb
         | 
| 161 | 
            +
            - db/migrate/20231219205644_create_datapoint.rb
         | 
| 162 | 
            +
            - db/migrate/20231220193201_create_stocks.rb
         | 
| 163 | 
            +
            - db/migrate/20231220194903_add_alert_status.rb
         | 
| 164 | 
            +
            - db/migrate/20231220223730_create_iro_price_item.rb
         | 
| 165 | 
            +
            - lib/iro/engine.rb
         | 
| 135 166 | 
             
            - lib/iron_warbler.rb
         | 
| 136 | 
            -
            - lib/ | 
| 167 | 
            +
            - lib/tasks/db_tasks.rake
         | 
| 137 168 | 
             
            - lib/tasks/iro_tasks.rake
         | 
| 138 169 | 
             
            homepage: https://wasya.co
         | 
| 139 170 | 
             
            licenses:
         | 
| @@ -1,47 +0,0 @@ | |
| 1 | 
            -
            <%= form_with(model: alert) do |form| %>
         | 
| 2 | 
            -
              <% if alert.errors.any? %>
         | 
| 3 | 
            -
                <div id="error_explanation">
         | 
| 4 | 
            -
                  <h2><%= pluralize(alert.errors.count, "error") %> prohibited this alert from being saved:</h2>
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                  <ul>
         | 
| 7 | 
            -
                    <% alert.errors.each do |error| %>
         | 
| 8 | 
            -
                      <li><%= error.full_message %></li>
         | 
| 9 | 
            -
                    <% end %>
         | 
| 10 | 
            -
                  </ul>
         | 
| 11 | 
            -
                </div>
         | 
| 12 | 
            -
              <% end %>
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              <div class="field">
         | 
| 15 | 
            -
                <%= form.label :class_name %>
         | 
| 16 | 
            -
                <%= form.text_field :class_name %>
         | 
| 17 | 
            -
              </div>
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              <div class="field">
         | 
| 20 | 
            -
                <%= form.label :kind %>
         | 
| 21 | 
            -
                <%= form.text_field :kind %>
         | 
| 22 | 
            -
              </div>
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              <div class="field">
         | 
| 25 | 
            -
                <%= form.label :symbol %>
         | 
| 26 | 
            -
                <%= form.text_field :symbol %>
         | 
| 27 | 
            -
              </div>
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              <div class="field">
         | 
| 30 | 
            -
                <%= form.label :direction %>
         | 
| 31 | 
            -
                <%= form.text_field :direction %>
         | 
| 32 | 
            -
              </div>
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              <div class="field">
         | 
| 35 | 
            -
                <%= form.label :strike %>
         | 
| 36 | 
            -
                <%= form.text_field :strike %>
         | 
| 37 | 
            -
              </div>
         | 
| 38 | 
            -
             | 
| 39 | 
            -
              <div class="field">
         | 
| 40 | 
            -
                <%= form.label :profile_id %>
         | 
| 41 | 
            -
                <%= form.number_field :profile_id %>
         | 
| 42 | 
            -
              </div>
         | 
| 43 | 
            -
             | 
| 44 | 
            -
              <div class="actions">
         | 
| 45 | 
            -
                <%= form.submit %>
         | 
| 46 | 
            -
              </div>
         | 
| 47 | 
            -
            <% end %>
         | 
| @@ -1,37 +0,0 @@ | |
| 1 | 
            -
            <p id="notice"><%= notice %></p>
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            <h1>Alerts</h1>
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            <table>
         | 
| 6 | 
            -
              <thead>
         | 
| 7 | 
            -
                <tr>
         | 
| 8 | 
            -
                  <th>Class name</th>
         | 
| 9 | 
            -
                  <th>Kind</th>
         | 
| 10 | 
            -
                  <th>Symbol</th>
         | 
| 11 | 
            -
                  <th>Direction</th>
         | 
| 12 | 
            -
                  <th>Strike</th>
         | 
| 13 | 
            -
                  <th>Profile</th>
         | 
| 14 | 
            -
                  <th colspan="3"></th>
         | 
| 15 | 
            -
                </tr>
         | 
| 16 | 
            -
              </thead>
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              <tbody>
         | 
| 19 | 
            -
                <% @alerts.each do |alert| %>
         | 
| 20 | 
            -
                  <tr>
         | 
| 21 | 
            -
                    <td><%= alert.class_name %></td>
         | 
| 22 | 
            -
                    <td><%= alert.kind %></td>
         | 
| 23 | 
            -
                    <td><%= alert.symbol %></td>
         | 
| 24 | 
            -
                    <td><%= alert.direction %></td>
         | 
| 25 | 
            -
                    <td><%= alert.strike %></td>
         | 
| 26 | 
            -
                    <td><%= alert.profile_id %></td>
         | 
| 27 | 
            -
                    <td><%= link_to 'Show', alert %></td>
         | 
| 28 | 
            -
                    <td><%= link_to 'Edit', edit_alert_path(alert) %></td>
         | 
| 29 | 
            -
                    <td><%= link_to 'Destroy', alert, method: :delete, data: { confirm: 'Are you sure?' } %></td>
         | 
| 30 | 
            -
                  </tr>
         | 
| 31 | 
            -
                <% end %>
         | 
| 32 | 
            -
              </tbody>
         | 
| 33 | 
            -
            </table>
         | 
| 34 | 
            -
             | 
| 35 | 
            -
            <br>
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            <%= link_to 'New Alert', new_alert_path %>
         |