s-leroux / fin

Set of tools for personal investment
MIT License
1 stars 0 forks source link

Adjust quotes #3

Closed s-leroux closed 2 months ago

s-leroux commented 1 year ago

Yahoo Finance (and other data providers) return the quotes as (open, high, low, close, adj close). Only the close price is adjusted for splits and dividends. We should provide a function to rescale the open, high, and low accordingly.

An option is to express the open, high, and low relative to (unadjusted) close, then apply these ratios to the adjusted close price to find the other adjusted prices.

s-leroux commented 3 months ago

We may also add an option to the quote retrieval API so the values are returned adjusted. I consider making that the default and not returning the "Adj close" column in that case.

s-leroux commented 3 months ago

If we could write macros, that would be designed as:

( spread(mul), ("Open", "High", "Low", "Close"), (div, "Adj close", "Close") )

However, that doesn't work with the current evaluation process since nested tuples are evaluated first, and all arguments are flattened.

Maybe related to #16.

s-leroux commented 3 months ago

Mathematica has the Thread function. Using the same name, we could implement a macro-like at the Python level:

( thread(mul, ("Open", "High", "Low", "Close"), (div, "Adj close", "Close") ) )
def thread(f, lst, *args):
    return tuple((f, x, *args) for x in lst) 

I don't find that very elegant since it breaks the LISP-like syntax with parenthesing that is inconsistent with the other expressions.

Another option would be to explicitly specify the number of columns we will spread over:

( thread(mul, 4), "Open", "High", "Low", "Close", (div, "Adj close", "Close") ) )

(This is an example of threading left. We may use negative numbers for threading right)

Expression rewriting occurs at evaluation time:

def thread(fct, n):
    def _thread(series, *args):
        return tuple( (fct, x, *args[n:]) for x in args[:n] )
s-leroux commented 3 months ago

The fin.sec.fc.adj() adjusts prices but not volumes because it requires a different solution for dividends depending if they were settled in cash or stocks.

From https://forum.alpaca.markets/t/why-is-price-but-not-volume-adjusted-for-dividends/12345:

Whether a dividend adjusts the volume depends In the case of a stock split, the company issues more shares (eg 2x in the case of a 2:1 split). In order to not make it look like the shareholder just increased percent ownership of the company (because their shares held just doubled), their previous holdings are multiplied by 2.[...]

A similar thing happens with a stock dividend. The company floats more shares with the dividend, but in order for it not to look like the shareholder increased their percent ownership of the company, their previous holdings are increased by a factor. The price is adjusted down by a proportional amount so, again, the ‘net equity’ remains the same. [...]

Now consider a cash dividend. The company doesn’t float any more shares. The shareholder doesn’t see any change in their shares held, but they do see a change in their ‘net equity’ because they now have cash they didn’t have before. The price of their shares before the dividend is adjusted down by some amount to reflect that increase in equity. The quantity of their shares however is not adjusted. If one were to adjust the quantity of shares, since the company didn’t change the shares outstanding, it would imply their percent ownership somehow changed. Therefore, share volumes are not adjusted by a cash dividend.

While we may use a heuristic to distinguish between splits and dividends, we still need some external information to know how dividends were settled.