• python
  • javascript
  • reactjs
  • sql
  • c#
  • java
Facebook Twitter Instagram
Devs Fixed
  • python
  • javascript
  • reactjs
  • sql
  • c#
  • java
Devs Fixed
Home ยป Resolved: Find portfolio balance efficiently (remove nested query)

Resolved: Find portfolio balance efficiently (remove nested query)

0
By Isaac Tonny on 17/06/2022 Issue
Share
Facebook Twitter LinkedIn

Question:

I could not find an issue like this one on SO. I have seen the following:
  • R/SQL – Portfolio Performance
  • SQL Server : Group By Price and Sum Amount
  • SQL Query Balance
  • Sql query to find total balance

None of them help me with the issue I have.
Lets say that I have a system that keeps track of my portfolio of shares. I have two main tables. one with the buy and sell orders that I have made, and the other with share prices for many shares over multiple years.
I am looking for an efficient script that gives me the overall portfolio dollar value for each order I have made over time. The current implementation I am using is far too slow: it executes a sub-query for every order I have. I can sometimes have tens of thousands of orders in the table.

The SQL


I am running this on an Oracle database:
I am looking for a faster way to get portfolio_balance_dollars. One with less runtime complexity.

Alternative


An efficient answer for the above would be first prize. But instead of looking up the share prices of all the relevant shares on each order, it also suffices to use the latest share price for the relevant share found within summary itself. This is fine because there are orders taking place quite often. So the following output will also be good enough:
That is instead of multiplying GOOG share balance with the GOOG share price at 2022-01-04, we instead multiply the share amount by the share price at 2022-01-02 to get a balance of 2155 for 2022-01-02. So it takes the latest available share price shown in summary itself.
db<>fiddle

Answer:

You can use:

SELECT *
FROM (
SELECT t.*,
SUM(balance_dollars) OVER (PARTITION BY dt)
AS portfolio_balance_dollars
FROM (
SELECT t.ticker,
o.dt,
p.price AS share_price,
o.shares AS order_shares,
o.shares * p.price AS order_dollars,
SUM(o.shares) OVER (PARTITION BY t.ticker ORDER BY o.dt)
AS balance_shares,
SUM(o.shares) OVER (PARTITION BY t.ticker ORDER BY o.dt)
* p.price AS balance_dollars
FROM ( SELECT DISTINCT ticker FROM orders ) t
LEFT OUTER JOIN (
SELECT ticker,
dt,
SUM(shares) AS shares
FROM orders
GROUP BY ticker, dt
) o
PARTITION BY (o.dt)
ON (t.ticker = o.ticker)
CROSS JOIN LATERAL (
SELECT p.*
FROM prices p
WHERE p.ticker = t.ticker
AND p.dt <= o.dt ORDER BY p.dt DESC FETCH FIRST ROW ONLY ) p ORDER BY o.dt, t.ticker, share_price ) t ) WHERE order_shares IS NOT NULL; [/code]

Which, for the sample data, outputs:

TICKER DT SHARE_PRICE ORDER_SHARES ORDER_DOLLARS BALANCE_SHARES BALANCE_DOLLARS PORTFOLIO_BALANCE_DOLLARS AAPL 02-JAN-22 1.1 1000 1100 1000 1100 2150 GOOG 02-JAN-22 10.5 100 1050 100 1050 2150 AAPL 04-JAN-22 1.3 -150 -195 850 1105 2115 AAPL 05-JAN-22 1.1 -100 -110 750 825 1946.1 GOOG 05-JAN-22 11.1 1 11.1 101 1121.1 1946.1


db<>fiddle here

If you have better answer, please add a comment about this, thank you!

oracle sql
Share. Facebook Twitter LinkedIn

Related Posts

Resolved: significance letter above bar graphic in wrong order

01/04/2023

Resolved: VBA – Applying border around the areas with value/text

01/04/2023

Resolved: How can I implement a function depending on picked up items?

01/04/2023

Leave A Reply

© 2023 DEVSFIX.COM

Type above and press Enter to search. Press Esc to cancel.