Peter Baričič's avatar
Peter Baričič
peter@baricic.com
npub1x7ap...mdc8
I’m a fullstack developer (nodejs, graphql, postgresql, vuejs), bitcoiner, but primarily a believer in Jesus Christ, my Lord and Savior.
Peter Baričič's avatar
PeterBaricic 2 years ago
When I don't check nostr for few days it's hard to get to notes older than 24h on my iPhone XR. - plebstr crashes - nostur crashes - damus just won't load all notes (only from 1 or 2 accounts) older than 12-15h
Peter Baričič's avatar
PeterBaricic 2 years ago
There is no trans “community”. There is only a worlwide toxic, leftist, marxist, brainwashed, satanistic, child grooming and child sacrificing cult. Servants of Ahab and Jezebel.
Peter Baričič's avatar
PeterBaricic 2 years ago
If most shitcoiners whom lost a lot of money by “investing” into shitcoin casinos would now “invest” (with their greed and stupidity) into BRC-20 tokens and ordinals, then probably the whole BRC-20 scam would die quickly.
Peter Baričič's avatar
PeterBaricic 2 years ago
The new media view with the ability to download media in the latest #[0] update is sic
Peter Baričič's avatar
PeterBaricic 2 years ago
I would love to have a hybrid of Pocket Casts and Fountain
Peter Baričič's avatar
PeterBaricic 2 years ago
Instead of paying for Twitter Blue for 1y, you can stack around 400k sats.
Peter Baričič's avatar
PeterBaricic 2 years ago
Emails should just die. Emails are heavily centralized, unsecure and just old. We should not need to use emails. But because most users and companies don’t care and are lazy, we have to. But I hope it will change, because the tech to replace emails is already here. There is really no need to use emails anymore. Instead of sending email newsletters, publish it on nostr and tell your readers to subscribe. For private (group) messages use nostr (or signal for now). And the worst of all, using email addresses as logins. Just stop. We have better alternatives like lnurl-auth or passkeys. Email adresses should be just lightning adresses and NIP-05, nothing else.
Peter Baričič's avatar
PeterBaricic 2 years ago
If you are against bitcoin mining then you are against the environment
Peter Baričič's avatar
PeterBaricic 2 years ago
SVB is the best latest example of “go woke go broke”
Peter Baričič's avatar
PeterBaricic 2 years ago
Every day is a good day to stack sats and if some bank goes bust or some shitcoin crashes, then it’s even a better day to earn or buy more sats (non-kyc only)! Every sat counts.
Peter Baričič's avatar
PeterBaricic 2 years ago
I know it’s Sunday, but a new update of ANY Nostr client on iOS would be nice :)
Peter Baričič's avatar
PeterBaricic 2 years ago
This will be a long note about coding some financial software functionality and SQL (PostgreSQL). Finally I finished stock split feature in one Portfolio management software. The hardest part was calculating the current amount of owned shares and their respective price (PPS - price per share), in SQL. Why it was hard? First let me explain some basics. You can have multiple investments (companies), where you have shares, which you can buy, sell (exit), transfer (receive or send), reevaluate (change PPS), convert (technically it exits one share and buys another share). You can also write off an investment, where you technically still own shares you had there, but their PPS is zero. Every time you buy or receive a share we track it as a separate transaction, which we call a tranche. So you buy 200 shares of A and later you buy 300 shares of A, you own 500 shares, but in database it’s 200 and 300 separated. This is for FIFO/LIFO functionality, so when you exit or sell 300 shares of A using FIFO, you exit 200 from the first tranche and 100 from the second tranche. For now it seems easy, but I didn’t feel like that when I was coding the FIFO/LIFO functionality :-). And now add STOCK SPLIT. I won’t explain what a stock split it, you can find and explanation yourself. In our app stock split is feature heavy: - you can define rounding (round up, round down, round mathematically) - you can define method of split, either using a ratio (2 for 3, 5 for 2 etc), or a multiple (basic decimal number multiplier, like 2.5x, 0.5x) - you can toggle “split all” or “don’t split all” shares, which has an effect how exceptions works - if you are splitting all shares, then in exceptions you can define another ratio or multiplier for some specific shares (or you enter a specific amount of shares after stock-split, then the ratio or multiple is calculated) - if you don’t split all shares, then in exceptions you define which are splitted and how (ratio or multiple) Creating the basic functionality of adding/editing/deleting stock split event (backend, frontend, extend some DB tables) was easy. The harder part was connecting the stock split data with the rest of the application, mainly calculating of how many shares you own and what is their PPS at specific time (today or random day in past). You have to take into account every possible event that can occur, like multiple buyings, exits, writeoffs, multiple stocksplits in row. I’ll give you one an example: - buy 100 shares with PPS = 2 (fair value is 100 x 2 = 200) - stock split 2 for 1 (shares = 200, and because fair value didn’t change, PPS is now = 1) - buy 100 shares (the same kind), set PPS = 1.5 (every time you buy shares you set new PPS, which is saved to DB and which kinda resets dynamic calculated PPS if there was a stock split before) - so now you own 300 shares with PPS = 1.5 , fair value is therefore 450 - stock split 3 for 1, now you own 900 shares (600 in first tranche, 300 in second tranche), PPS is 0.5 - exit 200 shares … now it get’s interesting. Be default you exit/sell using FIFO method, so you basically exited 200 in the first tranche, so you have 400 in the first tranche and 300 in the second tranche … PPS stays the same 0.5 - another stock split 2 for 3 with rounding down, so you have 266 shares in the first tranche and 200 shares in the second tranche, 466 total, and because fair value is always the same (it was 700 x 0.5 = 350), the new PPS is (700 x 0.5) / 466 = 0.751 Now let’s go into code. For performance and simplicity reasons, I have one SQL function which gives you list of shares you own with their amounts and PPS for specific date. The inputs of the function are Fund ID (because I calculate it for specific fund), list of investments IDs (you have multiple investments in a fund and this function will calculate it for every investment which ID you provide) and of course date. This is used for example for calculating equity fair value (share amounts x pps, summed, which can be then consolidated into specific currency with FX rate for the date you want, because you can buy different shares in different currencies … worldwide bitcoin standard would simplify this heavily). I don’t want to explain my code in heavy detail, but I’ll mention few things: - I have tables: obtained shares, exited shares, PPS of shares (as I mentioned before, every time you buy a share you set a price, or you change the price in a separate event) and table of events that happened in an investments (like stock split, equity investment, exit, share transfer, conversion, write off etc.) - I used SQL recursion heavily - the function is full of CTEs (common table expressions) for easier understanding, here I must say that naming those CTEs is as hard as coding them - window functions like row_number, dense_rank, last_value are used multiple times - in one part I had to use jsonb_build_objec, jsonb_agg and then also cross join with jsonb_array_elements, but for the fun I also used jsonb_to_recordset Length of the function is under 400 lines, it could be shorter, but I format it using Datagrip and that always makes my functions longer, but atleast they are more readable. My biggest issue while coding it was calculating of PPS. The calculation of current amount was hard in the beginning, but now it seems easy. But what about them PPSes: - I can’t just get the latest PPS from their table, because PPS will be different after stock split and I don’t save it (I did it in the beginning, but then I realised if someone edited some event before the stock split, I would have to update every following event and that seemed harder) - first I thought that I would just get the latest set PPS, calculate the amount at the time when the PPS was set and the new PPS would be (PPS x old_amount ) / new_amount, which kinda worked, until it DIDN’T :-) - it didn’t work in the example mentioned before, because of those exited shares. Why? Because I calculate amounts for each tranche, I would get this: - first tranche: new_amount = 266, old_amount = 0 - second tranche: new_amount = 200, old_amount = 100 - pps calculated (don’t forget that we must calculate pps for shares as a whole, not for each tranche) would be (100 x 1.5) / 466 = 0.321888412 - if I would calculate it for each tranche, then I would get (0 x 1.5) / 266 = 0, (100 x 1.5) / 200 = 0.75 … which looks like a correct result, but it’s not, the correct result is (700 x 0.5) / 466 = 0.7510729614 … it might seem like the same, but when you are dealing with millions or billions, even the smallest differences in decimal places can change your final amounts (again, PPS and share amounts are used to get equity fair value and that is used in calculation of another financial/investment metrics) - so what to do? It looks easy, just get the PPS from before the current stock split (call this function again ignoring this event), but what is that PPS is also dynamic and not saved, so you would get another recursion and you would need a way to know when to stop - I needed another and simpler way and that was calculate the change of PPS the same way how I calculate change of amounts on each step, where each step is every stock split and obtaining or exit of a share, but this time not for each tranche, but for a share as a whole - so first I calculate how those amounts change, then I sum and group them by their share ID, then I calculate how the PPS changes and as a final step I get the latest calculated PPS for each share and join it with the CTE of calculated latest amounts. Here I had to use jsonb, because I couldn’t return multiple columns/rows in this part of my code So now after multiple iterations of testing and fixing I think I can safely say IT WORKS (without bugs), it’s fast and it will be released shortly, but I don’t decide when :-). Coding this in SQL wasn’t easy, but I really enjoyed it. For the past 12+ months I’ve been coding more and more SQL code and I spent more time in Datagrip than in VSCode.
Peter Baričič's avatar
PeterBaricic 2 years ago
I don't usually post stuff on social networks, because my personal social circles don't really care (or are not interested) about the same things as I am. I didn't just stop posting on FB many many years ago, but I also deleted everything I posted in the past. I used to post on Twitter many years ago, but for the past few years I was there just reading and retweeting. But Nostr feels different, so I'll try to post something about my coding and I have a very long post prepared, so this is also a warning 😄. I hope that Nostr will handle it.