Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ gem "thruster", require: false

gem "chartkick"

gem "sidekiq", "~> 7.3"

gem "redis", "~> 5.3"

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
gem "image_processing", "~> 1.2"

Expand Down
27 changes: 20 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ GEM
bindex (0.8.1)
bootsnap (1.21.1)
msgpack (~> 1.2)
brakeman (7.1.2)
brakeman (8.0.1)
racc
builder (3.3.0)
bullet (8.1.0)
Expand Down Expand Up @@ -203,7 +203,7 @@ GEM
pp (0.6.3)
prettyprint
prettyprint (0.2.0)
prism (1.8.0)
prism (1.9.0)
propshaft (1.3.1)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
Expand Down Expand Up @@ -255,12 +255,17 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.1)
rbs (3.10.2)
rbs (3.10.3)
logger
tsort
rdoc (7.1.0)
erb
psych (>= 4.0.0)
tsort
redis (5.4.1)
redis-client (>= 0.22.0)
redis-client (0.26.4)
connection_pool
regexp_parser (2.11.3)
reline (0.6.3)
io-console (~> 0.5)
Expand All @@ -283,16 +288,16 @@ GEM
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.6)
rubocop (1.82.1)
rspec-support (3.13.7)
rubocop (1.84.0)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.48.0, < 2.0)
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.49.0)
Expand Down Expand Up @@ -326,6 +331,12 @@ GEM
securerandom (0.4.1)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
sidekiq (7.3.9)
base64
connection_pool (>= 2.3.0)
logger
rack (>= 2.2.4)
redis-client (>= 0.22.2)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand Down Expand Up @@ -366,7 +377,7 @@ GEM
thruster (0.1.17-x86_64-linux)
timeout (0.6.0)
tsort (0.2.0)
turbo-rails (2.0.21)
turbo-rails (2.0.23)
actionpack (>= 7.1.0)
railties (>= 7.1.0)
tzinfo (2.0.6)
Expand Down Expand Up @@ -411,6 +422,7 @@ DEPENDENCIES
propshaft
puma (>= 5.0)
rails (~> 8.1.1)
redis (~> 5.3)
rspec-rails (~> 7.1, >= 7.1.1)
rubocop (~> 1.69)
rubocop-performance (~> 1.24)
Expand All @@ -419,6 +431,7 @@ DEPENDENCIES
rubocop-rspec (~> 3.3)
ruby-lsp
shoulda-matchers (~> 6.5)
sidekiq (~> 7.3)
simplecov (~> 0.21.2)
solid_cable
solid_cache
Expand Down
42 changes: 21 additions & 21 deletions app/controllers/dashboard_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class DashboardController < ApplicationController
def index
@wallets = current_user.wallets.includes(:holdings, :transactions, :strategy)

@total_wallets = @wallets.count
@active_wallets = @wallets.active.count
@inactive_wallets = @wallets.inactive.count

@wallet_summaries = @wallets.map do |wallet|
{
wallet: wallet,
Expand All @@ -16,56 +16,56 @@ def index
has_strategy: wallet.strategy.present?
}
end

@total_invested = @wallet_summaries.sum { |ws| ws[:total_invested] }
@total_current_value = @wallet_summaries.sum { |ws| ws[:current_value] }
@total_profit_loss = @total_current_value - @total_invested
@total_profit_loss_percentage = @total_invested.zero? ? 0 : ((@total_profit_loss / @total_invested) * 100)

@recent_transactions = current_user.wallets
.joins(:transactions)
.includes(transactions: :instrument)
.merge(Transaction.order(occurred_at: :desc))
.limit(10)
.flat_map(&:transactions)
.first(10)


@wallet_distribution = @wallet_summaries.map do |summary|
[summary[:wallet].name, summary[:current_value].to_f]
[ summary[:wallet].name, summary[:current_value].to_f ]
end.to_h

transactions_last_6_months = current_user.wallets
.joins(:transactions)
.where("transactions.occurred_at >= ?", 6.months.ago)
.pluck("transactions.occurred_at")

@transactions_by_month = transactions_last_6_months
.compact
.group_by { |date| date.beginning_of_month.strftime("%b %Y") }
.transform_values(&:count)
.sort_by { |month, _| Date.parse("01 #{month}") }
.to_h

@buy_vs_sell = {
"Buys" => current_user.wallets.joins(:transactions).merge(Transaction.buy).count,
"Sells" => current_user.wallets.joins(:transactions).merge(Transaction.sell).count
}

holdings_with_instruments = current_user.wallets
.joins(holdings: :instrument)
.select("instruments.ticker, holdings.average_price, holdings.quantity")

@top_instruments = holdings_with_instruments
.group_by(&:ticker)
.map { |ticker, holdings|
.map { |ticker, holdings|
total = holdings.sum { |h| (h.average_price || 0) * (h.quantity || 0) }
[ticker, total.to_f]
[ ticker, total.to_f ]
}
.sort_by { |_, value| -value }
.first(5)
.to_h

@wallet_comparison_data = @wallet_summaries.map do |summary|
[
summary[:wallet].name,
Expand All @@ -76,14 +76,14 @@ def index
]
end.to_h
end

private

def calculate_total_invested(wallet)
wallet.transactions.buy.sum('price * quantity')
wallet.transactions.buy.sum("price * quantity")
end

def calculate_current_value(wallet)
wallet.holdings.sum('average_price * quantity')
wallet.holdings.sum("average_price * quantity")
end
end
end
1 change: 1 addition & 0 deletions app/models/instrument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ class Instrument < ApplicationRecord
has_many :holdings, dependent: :destroy
has_many :transactions, dependent: :destroy
has_many :wallets, through: :holdings
has_many :instrument_metrics, dependent: :destroy
end
3 changes: 3 additions & 0 deletions app/models/instrument_metric.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class InstrumentMetric < ApplicationRecord
belongs_to :instrument
end
4 changes: 2 additions & 2 deletions app/models/strategy_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ class StrategyRule < ApplicationRecord

validates :asset_kind, presence: true
validates :strategy_id, presence: true
validate :validate_percentage_rule, if: -> { rule_type == 'percentage' }
validate :validate_prohibition_rule, if: -> { rule_type == 'prohibition' }
validate :validate_percentage_rule, if: -> { rule_type == "percentage" }
validate :validate_prohibition_rule, if: -> { rule_type == "prohibition" }

# Métodos auxiliares
def prohibition?
Expand Down
10 changes: 10 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,19 @@ services:
networks:
- ledger_net

redis:
container_name: ledger_redis
image: "redis:latest"
command: redis-server
volumes:
- redis_data:/data
networks:
- ledger_net

volumes:
postgres_data:
gem_cache:
redis_data:

networks:
ledger_net:
7 changes: 7 additions & 0 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Sidekiq.configure_server do |config|
config.redis = { url: ENV.fetch("REDIS_URL") }
end

Sidekiq.configure_client do |config|
config.redis = { url: ENV.fetch("REDIS_URL") }
end
7 changes: 7 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
require "sidekiq/web"

Rails.application.routes.draw do
devise_for :users
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

Sidekiq::Web.use Rack::Auth::Basic do |username, password|
username == ENV["SIDEKIQ_USERNAME"] && password == ENV["SIDEKIQ_PASSWORD"]
end

mount Sidekiq::Web => "/sidekiq"
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live.
get "up" => "rails/health#show", as: :rails_health_check
Expand Down
17 changes: 17 additions & 0 deletions db/migrate/20260131171800_create_instrument_metrics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class CreateInstrumentMetrics < ActiveRecord::Migration[8.1]
def change
create_table :instrument_metrics do |t|
t.references :instrument, null: false, foreign_key: true
t.decimal :price, precision: 15, scale: 4, null: false
t.decimal :dy, precision: 5, scale: 2
t.decimal :p_vp, precision: 5, scale: 2
t.decimal :daily_liquidity, precision: 15, scale: 2
t.decimal :market_cap, precision: 20, scale: 2
t.datetime :recorded_at, null: false

t.timestamps
end

add_index :instrument_metrics, [ :instrument_id, :recorded_at ]
end
end
17 changes: 16 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.