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
2 changes: 2 additions & 0 deletions .github/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
agents
skills
20 changes: 12 additions & 8 deletions .migrations/001_init.down.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
drop table if exists users;
drop table if exists assets;
drop table if exists portfolios;
drop table if exists transactions;
-- 001_init.down.sql

drop view if exists portfolios_ext;
-- triggers
drop trigger if exists check_holdings_before_insert_sell;
drop trigger if exists check_holdings_before_update_sell;

-- views
drop view if exists asset_transactions;
drop view if exists asset_holdings;
drop view if exists portfolios_ext;
drop view if exists assets_contributions;

drop trigger if exists check_holdings_before_insert_sell;
drop trigger if exists check_holdings_before_update_sell;

-- tables
drop table if exists users;
drop table if exists assets;
drop table if exists portfolios;
drop table if exists transactions;
28 changes: 26 additions & 2 deletions .migrations/002_portfolio_view.down.sql
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
ALTER TABLE transactions
DROP COLUMN comments;
-- 002_portfolio_view.down.sql

-- revert views to previous state
drop view if exists portfolios_ext;

create view portfolios_ext as
select
p.*,
coalesce(a.total_invested, 0) as total_invested,
coalesce(a.num_assets, 0) as num_assets
from
portfolios p
left join (
select
portfolio_id,
sum(invested) as total_invested,
count(id) as num_assets
from
asset_holdings
group by
portfolio_id
) as a on p.id = a.portfolio_id;

-- remove comments column
alter table transactions
drop column comments;
126 changes: 125 additions & 1 deletion .migrations/005_num_shares.down.sql
Original file line number Diff line number Diff line change
@@ -1 +1,125 @@
-- drop view if exists asset_transactions;
-- 005_num_shares.down.sql

-- drop new triggers
drop trigger if exists check_holdings_before_insert_sell;
drop trigger if exists check_holdings_before_update_sell;

-- drop new views
drop view if exists transactions_ext;
drop view if exists assets_ext;
drop view if exists portfolios_ext;

-- recreate portfolios_ext from 002
create view portfolios_ext as
select
p.*,
coalesce(a.total_invested, 0) as total_invested,
coalesce(a.num_assets, 0) as num_assets,
coalesce(total_invested / sum(total_invested) over (partition by p.user_id), 0) as contribution
from
portfolios p
left join (
select
portfolio_id,
sum(invested) as total_invested,
count(id) as num_assets
from
asset_holdings
group by
portfolio_id
) as a on p.id = a.portfolio_id;

-- recreate old views from 001
create view asset_holdings as
select
sub.*,
case
when sub.holdings = 0 then null
else sub.invested / sub.holdings
end as avg_price
from
(
select
a.*,
u.id as user_id,
coalesce(
sum(
case
when t.type = 'buy' then t.quantity
else - t.quantity
end
),
0
) as holdings,
coalesce(
sum(
case
when t.type = 'buy' then t.quantity * t.price
else - t.quantity * t.price
end
),
0
) as invested,
count(t.id) as num_tx
from
assets a
inner join portfolios p on p.id = a.portfolio_id
left join transactions t on t.asset_id = a.id
inner join users u on u.id = p.user_id
group by
a.id,
a.name
) as sub;

create view asset_transactions as
select
t.*,
a.name,
a.ticker,
p.name as portfolio_name,
p.description as portfolio_description,
p.user_id
from
transactions t
inner join assets a on a.id = t.asset_id
inner join portfolios p on p.id = a.portfolio_id;

create view assets_contributions as
select
ah.*,
coalesce(ah.invested / coalesce(pt.total_invested, 1), 0) as portfolio_contribution
from
asset_holdings ah
left join portfolios_ext pt on ah.portfolio_id = pt.id;

-- recreate old triggers
create trigger check_holdings_before_insert_sell before insert on transactions for each row when new.type = 'sell' begin
select
case
when (
select
holdings
from
asset_holdings a
where
id = new.asset_id
) < new.quantity then raise (abort, 'Insufficient holdings')
end;

end;

create trigger check_holdings_before_update_sell before
update on transactions for each row when new.type = 'sell' begin
select
case
when (
select
holdings
from
asset_holdings a
where
id = new.asset_id
) < new.quantity then raise (abort, 'Insufficient holdings')
end;

end;
174 changes: 174 additions & 0 deletions .migrations/006_self_enriched_tx.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
-- 006_self_enriched_tx.down.sql

-- drop new views
drop view if exists transactions_ext;
drop view if exists assets_ext;
drop view if exists portfolios_ext;

-- recreate portfolios_ext from 005
create view portfolios_ext as
with
portfolio_assets as (
select
portfolio_id,
sum(invested) as total_invested,
count(id) as num_assets
from
assets_ext
group by
portfolio_id
)
select
p.*,
coalesce(pa.total_invested, 0) as total_invested,
coalesce(pa.num_assets, 0) as num_assets,
coalesce(
pa.total_invested / sum(pa.total_invested) over user_portfolios,
0
) as contribution
from
portfolios p
left join portfolio_assets as pa on p.id = pa.portfolio_id
window
user_portfolios as (
partition by
p.user_id
);

-- recreate assets_ext from 005
create view assets_ext as
with
avg_unit_cost as (
select
asset_id,
sum(quantity * price) / sum(quantity) as avg_price
from
transactions
where
type = 'buy'
group by
asset_id
),
tx_stats as (
select
asset_id,
sum(quantity_ext) as holdings,
count(*) as num_txs
from
transactions_ext
group by
asset_id
)
select
a.*,
u.id as user_id,
coalesce(t.holdings, 0) as holdings,
coalesce(t.holdings * c.avg_price, 0) as invested,
coalesce(t.num_txs, 0) as num_txs,
c.avg_price
from
assets a
inner join portfolios p on p.id = a.portfolio_id
left join avg_unit_cost c on a.id = c.asset_id
left join tx_stats t on a.id = t.asset_id
inner join users u on u.id = p.user_id;

-- recreate transactions_ext from 005
create view transactions_ext as
with
txs_ext as (
select
*,
case
when type = 'buy' then quantity
else 0 - quantity
end as quantity_ext
from
transactions
),
total_contr as (
select
asset_id,
sum(quantity_ext) as total_quantity
from
txs_ext
group by
asset_id
)
select
t.*,
sum(quantity_ext) over upto_tx as holdings,
sum(quantity_ext * price) over upto_tx as total_invested,
coalesce(
sum(
case
when type = 'buy' then quantity * price
else 0
end
) over upto_tx / sum(
case
when type = 'buy' then quantity
else 0
end
) over upto_tx,
0
) as avg_price,
case
when tc.total_quantity = 0 then 0
else quantity_ext / tc.total_quantity
end AS contribution,
a.name,
a.ticker,
p.name as portfolio_name,
p.description as portfolio_description,
p.user_id
from
txs_ext t
join total_contr tc on t.asset_id = tc.asset_id
inner join assets a on a.id = t.asset_id
inner join portfolios p on p.id = a.portfolio_id
window
upto_tx as (
partition by
t.asset_id
order by
date ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW
)
order by
date;

-- recreate triggers from 005
drop trigger if exists check_holdings_before_insert_sell;
drop trigger if exists check_holdings_before_update_sell;

create trigger check_holdings_before_insert_sell before insert on transactions for each row when new.type = 'sell' begin
select
case
when (
select
holdings
from
assets_ext a
where
id = new.asset_id
) < new.quantity then raise (abort, 'Insufficient holdings')
end;

end;

create trigger check_holdings_before_update_sell before
update on transactions for each row when new.type = 'sell' begin
select
case
when (
select
holdings
from
assets_ext a
where
id = new.asset_id
) < new.quantity then raise (abort, 'Insufficient holdings')
end;

end;
Loading
Loading