mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-22 06:39:39 +02:00
Enhance securities de-duplication task
This commit is contained in:
parent
68d7cb5de6
commit
ab7f6a56f0
1 changed files with 47 additions and 11 deletions
|
@ -61,19 +61,55 @@ namespace :securities do
|
||||||
|
|
||||||
desc "De-duplicate securities based on ticker + exchange_operating_mic"
|
desc "De-duplicate securities based on ticker + exchange_operating_mic"
|
||||||
task :deduplicate, [ :dry_run ] => :environment do |_t, args|
|
task :deduplicate, [ :dry_run ] => :environment do |_t, args|
|
||||||
# First check if we have any securities without exchange_operating_mic
|
|
||||||
missing_mic_count = Security.where(exchange_operating_mic: nil).where.not(ticker: nil).count
|
|
||||||
|
|
||||||
if missing_mic_count > 0
|
|
||||||
puts "ERROR: Found #{missing_mic_count} securities without exchange_operating_mic."
|
|
||||||
puts "Please run 'rails securities:backfill_exchange_mic' first to ensure all securities have exchange_operating_mic values."
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
dry_run = args[:dry_run].present?
|
dry_run = args[:dry_run].present?
|
||||||
puts "Starting securities de-duplication... #{dry_run ? '(DRY RUN)' : ''}"
|
puts "Starting securities de-duplication... #{dry_run ? '(DRY RUN)' : ''}"
|
||||||
|
|
||||||
# Find all duplicate securities (same ticker + exchange_operating_mic)
|
# First handle securities without exchange_operating_mic
|
||||||
|
securities_without_mic = Security.where(exchange_operating_mic: nil).where.not(ticker: nil)
|
||||||
|
puts "\nFound #{securities_without_mic.count} securities without exchange_operating_mic"
|
||||||
|
|
||||||
|
securities_without_mic.find_each do |security|
|
||||||
|
# Find if there's a security with the same ticker that has an exchange_operating_mic
|
||||||
|
canonical = Security.where.not(exchange_operating_mic: nil)
|
||||||
|
.where(ticker: security.ticker)
|
||||||
|
.order(created_at: :asc)
|
||||||
|
.first
|
||||||
|
|
||||||
|
if canonical
|
||||||
|
puts "\nProcessing #{security.ticker} (no MIC):"
|
||||||
|
puts " Canonical: #{canonical.id} (created: #{canonical.created_at}, MIC: #{canonical.exchange_operating_mic})"
|
||||||
|
puts " Duplicate without MIC: #{security.id}"
|
||||||
|
|
||||||
|
# Count affected records
|
||||||
|
holdings_count = Account::Holding.where(security_id: security.id).count
|
||||||
|
trades_count = Account::Trade.where(security_id: security.id).count
|
||||||
|
prices_count = Security::Price.where(security_id: security.id).count
|
||||||
|
|
||||||
|
puts " Would update:"
|
||||||
|
puts " - #{holdings_count} holdings"
|
||||||
|
puts " - #{trades_count} trades"
|
||||||
|
puts " - #{prices_count} prices"
|
||||||
|
|
||||||
|
unless dry_run
|
||||||
|
begin
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
# Update all references to point to the canonical security
|
||||||
|
Account::Holding.where(security_id: security.id).update_all(security_id: canonical.id)
|
||||||
|
Account::Trade.where(security_id: security.id).update_all(security_id: canonical.id)
|
||||||
|
Security::Price.where(security_id: security.id).update_all(security_id: canonical.id)
|
||||||
|
|
||||||
|
# Delete the duplicate
|
||||||
|
security.destroy!
|
||||||
|
end
|
||||||
|
puts " ✓ Successfully merged and removed duplicate"
|
||||||
|
rescue => e
|
||||||
|
puts " ✗ Error processing #{security.ticker}: #{e.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Now handle duplicates with same ticker + exchange_operating_mic
|
||||||
duplicates = Security
|
duplicates = Security
|
||||||
.where.not(ticker: nil)
|
.where.not(ticker: nil)
|
||||||
.where.not(exchange_operating_mic: nil)
|
.where.not(exchange_operating_mic: nil)
|
||||||
|
@ -81,7 +117,7 @@ namespace :securities do
|
||||||
.having("COUNT(*) > 1")
|
.having("COUNT(*) > 1")
|
||||||
.pluck(:ticker, :exchange_operating_mic)
|
.pluck(:ticker, :exchange_operating_mic)
|
||||||
|
|
||||||
puts "Found #{duplicates.length} sets of duplicate securities"
|
puts "\nFound #{duplicates.length} sets of duplicate securities with same ticker + MIC"
|
||||||
total_holdings = 0
|
total_holdings = 0
|
||||||
total_trades = 0
|
total_trades = 0
|
||||||
total_prices = 0
|
total_prices = 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue