Miten spin-offi hinnoitellaan verotuksessa?
Case studyn otsikko "IB:n rapsat ja oikeat hankintahinnat"
Eli O:ta on otettu näillä spekseillä
Koodi:
{
"ticker": "O",
"pcs": 60,
"date": "2021-03-12",
"currency": "USD",
"price": "61.935",
"comission": "-0.36225725",
"comission_currency": "USD",
"ID": "119211577"
},
Flex query myynnit:
"USD","O","-60","63.885","2022-06-16","1201133089","2022-06-16,10:07:49","-0.45783524","USD"
"USD","O","60","58.74417685","2022-06-16","119211577","2022-06-16,10:07:49","",""
"USD","ONL","-1","11.78","2022-06-13","1191703478","2022-06-13,07:49:13","-0.121486345","USD"
"USD","ONL","1","17.638137","2022-06-13","","2022-06-13,07:49:13","",""
"USD","ONL","-1","11.76","2022-06-13","1191703479","2022-06-13,07:49:13","-0.12128574","USD"
"USD","ONL","1","17.638137","2022-06-13","","2022-06-13,07:49:13","",""
"USD","ONL","-4","11.76","2022-06-13","1191703486","2022-06-13,07:49:28","-0.110681447","USD"
"USD","ONL","4","17.63813725","2022-06-13","","2022-06-13,07:49:28","",""
Huomatkaa että ONL ostojen transactionID on "", tällöin on kyseessä joku "spesiaalitapahtuma" joka pitäisi osata kohdistaa johonkin muuhun ostoon historiassa. Ratkaisin sen nyt tässä kohtaa "bruteforcella" eli sattu käymään tuuri kun O:lle oli vain 1 osto, entäs jos O:lle olisi ollut hyvin eri hinnoilla 10 ostosta ja vielä jos menneisyydessä osa O:sta olisi myyty niin 'milläs kaivat' että mitkä O:n itemit pitää etsiä (niistähän pitäisi kaiketi laskea ostohintojen määräpainotettu keskiarvo) ONL:lle hankinta hinnaksi. Tuohon tarvitaan kaiken lisäksi erillinen query spin-off päivälle jotta ylipäänsä tiedät että paljonko sulla on O:ta silloin ollut (kts. alta 'nykyarvon' määrittely).
Koodi:
def IDexists( DictList, transID ):
for i in DictList:
seek = ('ID', transID)
if seek in i.items():
return i
ONL_O_spins = ["1191703478", "1191703479", "1191703486" ]
if transID in ONL_O_spins: # ONL spinoffs from O (ID: "119211577")
transID = "119211577"
return IDexists( DictList, transID ) # recursion call
return None
Eihän tossa nyt ole mitään järkeä, O:ta on ostettu hintaan 61,935USD ja 11.15.2021 10 kpl O:ta vastaan sai 1 "ilmaisen" ONL:n eli minun ymmärtääkseni 10 osaketta muuttui ns 11 osakkeeksi jolloin O:lle kaiken järjen mukaan jää/jäi 10/11 osa hinnasta ja ONL:lle 1/11 osa hinnasta.
Vai pitäisikö tuo olla sittenkin ONL = 10xhankintahinta*1/11 ja O=(10*hankinta*10/11)/10?
Python koodi poikkeuskäsittelyineen
Koodi:
def GetPurchasePrice( sell_item, purchase_item ):
price = Decimal(purchase_item['price'])
if sell_item['ticker'] == "ONL" and purchase_item['ticker'] == "O":
price = price/11 # every 10th O yielded 1 ONL
#price = (10*price)/11 # 1 of 11th
elif sell_item['ticker'] == "O" and purchase_item['ticker'] == "O" and GetDate(purchase_item['date']) < GetDate("2021-11-15"):
price = price*10/11 # every 10th O yielded 1 ONL
#price = ((10*price)*10/11)/10
print(f"orig price {purchase_item['price']} new price {price}" )
return price
Tuottaa seuraavanlaisen outputin:
O:ta myytäessä:
orig price 61.935 new price 56.30454545454545454545454545
ONL:ää myytäessä:
orig price 61.935 new price 5.630454545454545454545454545
ja kommenteissa olevalla koodilla molemmille tickereille
orig price 61.935 new price 56.30454545454545454545454545
56,3045 + 5,63045 = 61,93495 = 0,00005 USD:n päässä orkkishinnasta...
IB:n mielipide aiheesta 58,74+17,63 = 76,37USD orkkis O:n osake (noissa hinnoissa lienee mukana pääoman palautukset hintaa nostavana tekijänä?)
O ilmeisesti maksaa tolla 60 osakkeen satsilla noin 8-9USD/kk pääoman palautusta ja 4USD pintaan varsinaista osinkoa. ONL ei ainakaan vuonna 2021 maksanut yhtään mitään, vuodesta 2022 ei mitään hajua. O on siis maksanut 9x vuonna 2021 ja olettavasti ehti maksamaan 6x vuonna 2022 ja jos 2022 summat on about samat niin saadaan pääoman palautusta 15*8=120usd 15*9=135usd välillä. Osakketta kohdin tuosta ei koko ajalle tule kuin max. 2,25usd luokkaa ja olettavasti ONL:lle on siirtynyt osa noistakin ekalta 8:lta kuukaudelta.
IB:hän näytti ONL:n olevan oikein reilusti miinuksella eikä O:kaan hirveästi plussalla ollut, itse laskettu lopputulos EURoina olisi kuitenkin näin jälkikäteen tulittuna ilmeisesti seuraava eli nehän olikin plussalla "aivan helvetisti" vai jäikö multa tässä nyt jotain huomiotta/olenko tehnyt jonkun megalomaanisen mokan jossain vaiheessa? ONL kommenteissa laskettu hankinta-hinta on ainakin todella kaukana IB:n arvosta ja sillä saadaan sitten ihan reilusti IB:n ilmoittamia miikkoja isompia miinuksia (eli mennään toisesta suunnasta eli IB:n tietojen).
Koodi:
O 2022-06-16 sell: 3685.23 buy: 2831.34 profit: 853.90
ONL 2022-06-13 sell: 11.15 buy: 5.02 profit: 6.13
ONL 2022-06-13 sell: 11.13 buy: 5.02 profit: 6.11
ONL 2022-06-13 sell: 44.89 buy: 19.18 profit: 25.71
kommenteissa olevalla koodilla ONL osio toki saa 'hieman' eri arvot
ONL 2022-06-13 sell: 11.15 buy: 47.49 profit: -36.34
ONL 2022-06-13 sell: 11.13 buy: 47.49 profit: -36.36
ONL 2022-06-13 sell: 44.89 buy: 189.04 profit: -144.15
Tossakin kun vaihdetaan sataset kymppitonniin niin alkaa tulemaan euroissakin jo olennaisia eroja
.
Laskuissa on käytetty seuraavia valuuttakursseja jos joku haluaa nuo itsekin auki
O buy rates 1.1933
O sell rates 1.0400
ONL sell rates 1.0455
Mulla oli kyllä tehty auki oleville positioille skripti joka laskee "sisällä" olevan velan, mutta se ei ymmärrä spin-offien päälle mitään (eikä ymmärrä vieläkään) ja se näytti 15.6 O:lle ja ONL:lle 10.6 (perjantai, 13.6 maanantai jolloin myyty pois) seuraavia arvoja, mutta kun tiesin tuossa olevan spin-offin kyseessä ja sen että laskurini ei sitä ymmärrä niin aattelin IB:n online-tilan olevan "enemmän oikeassa", mutta itseasiassa se oli paljon enemmän väärässä (kiitos ainakin osittain ~15% valuuttakurssi muutoksen).
O: 2953.70 EUR, pending profit: 658.03 EUR
ONL: 88.69 EUR, pending profit: -20.22 EUR
Nuo lukemat puolestaan on saatu oheisilta flex-query riveiltä tossa on "PositionValue","CostBasisPrice" 4. ja 5. arvo, josta ekaa käytetään nykyarvon määrityksessä ylimmällä riville ja alemmilta riveiltä päivämäärän mukaan haetaan valuuttakurssi ja käytetään "CostBasisPrice"ä ko. erän hankinta-arvon määrittelyyn.
Koodi:
15.6:
"USD","O","60","3888","58.74417685",""
"USD","O","60","3888","58.74417685","2021-03-12,09:41:55"
10.6:
"USD","ONL","6","72.42","17.638137333",""
"USD","ONL","6","72.42","17.638137333","2021-03-12,09:41:55"
No jos jotain positiivista hakee niin cost-basis-price on ainakin O:lle sama myynnissä (trades-lehdykältä tehty flex query) ja nykyarvon määrityksessä ((open)positions-lehdykältä tehty flex query).
No tämä oli nyt tämmöinen pieni kurkistus "halvan välittäjän maailmaan". Jos raportoi suoraan IB:n tiedoilla niin tekee hitosti tiliä vältetyillä veroilla mikäli euro on heikentynyt, vastaavasti maksat aivan helvetisti liikaa jos euro on vahvistunut...
Sitten vielä kysymyksiä tuon itse spin-off hinnan määrityksen lisäksi
. Nyt tarttisi tosiaan jotenkin saada kuvattua tuo GetPurchasePrice() funktio geneerisemmässä muodossa eli se pitäisi olla joku json-dicti tjsp jota tuo funkkari penkoisi ja etsisi sieltä täsmääkö joku (tai peräti useita???!!!) tapahtum(i)a kyseiseen osakkeeseen (Siellähän voi olla pari splittiä ja voi joku spin-offi perään / alkuun)... Onko ideoita että saako flex-queryllä jotenkin juuri sinun omistuksiin kohdistuneet tapahtumat jossain näppärässä muodossa?
Toinen kysymys: mitenkäs tuo IDexists() tehdään geneerisemmäksi ja millä/mistä kaivetaan siihen tarvittava tieto
? Ilmeisesti GetPurchasePrice() tarvitsema 'json dict' auttaisi tässäkin ainakin jollain tasolla arvioimaan että mikä/mitkä olisi ne oikeat ostoerät joista lähteä laskemaan.
JSON dict olisi siinäkin mielessä kätevä että tarvittessa tuohon tiedostoon voisi itse käsin kuvata asioista. Onnistuuhan se toki ensihätään niinkuin että käsin lisää osto jsoniin myynnin ID:n eli esim: entryn "1191703478" jolloin vain simppelisti ostonID ollessa tyhjä ("") etsitäänkin myynnin ID:llä käsin täytetyt tiedot. Tai ehkä nuo käsin tehdyt lisäykset olisi järkevää olla jokatapauksessa omassa (osto)filussaan näin olisi selvää että mikä on itse väkästeltyä ja mikä on suoraa generointia ja jos filun rakentaa tyhjästä uusiksi niin käsin tehdyt rävellyksethän katoavat siinä kohtaa myöskin "vahingossa".
PS. nyt olisi skripti jollain tavalla kasassa joka lisää tiedostoon uusia ostoksia jos niitä ei siellä jo ole eli kun ajaa sinne vuosien 2020, 2021, 2022 trades queryt niin näyttää tältä
found 18 new purchases, total amount is 18
found 68 new purchases, total amount is 86
found 15 new purchases, total amount is 101
Ja kun ajaa jotain noita uusiksi niin näyttää tältä
found 0 new purchases, total amount in 101
Sitten tuo tosiaan näyttää kaikki flexissä olevat myynnit myös samalla ajolla eli kun valitsee (lopuksi) flex querystä haluamansa aikavälin niin saa sen aikavälin myynnit (esim vuosi 2021 tai vaikka kesäkuu 2022).
O 2022-06-16 sell: 3685.23 buy: 2831.34 profit: 853.90
ONL 2022-06-13 sell: 11.15 buy: 5.02 profit: 6.13
ONL 2022-06-13 sell: 11.13 buy: 5.02 profit: 6.11
ONL 2022-06-13 sell: 44.89 buy: 19.18 profit: 25.71
Ja sitten se vielä vääntää tarvittavat lukemat verotukseen (henkilöverotukseen aa ja bb ja yrityksen kirjanpito tarttee lisäksi sitten vielä tuon dd:n ja ee:n (e toki laskettavissa a&b&c tiedoista)
Profits aa.aa EUR, Losses: -bb.bb EUR, Total cc.cc EUR
Purchase prices total dd.dd EUR, sell prices total: ee.ee -> cc.cc EUR
Vielä puuttuu "jotain" pientä kuten hankintamenoolettama joka html parserissa jo onkin. Ja tarttis varmaan opetella oikeasti koodaamaan ja jakamaan tuota vähän eri moduleihin, ei tuo kyllä nytkään ole kuin 234 riviä kun valuuttakurssit on omassa filussa jota käyttää mun kaikki 3 skriptiä. Mutta vähän enemmän kuin
@Mooses ???:sen parituntia tähän on kyllä itseltä tähän asti mennyt
.
PPS. tietysti jos ei ikinä myy mitään niin sitten perikuntakunta pääsee aikahelpolla jos vain heti kuolinpäivänä joku ymmärtäisi tällätä "close all position" nappia niin ei tartte selvitellä mitään, sen kuin siirtää tilille saadun summan suoraan perintöverotukseen, mutta jos kuoleman ja tuon close all positions napin välillä onkin vaikka 2 vuotta niin onnea vaan pesälle alkaa tulkkaamaan kropan tekemiä pythoneita
, no menee tuokin vielä helposti kun ei tartte verrata kuin kuolinpäivän arvoa saatuun massiin jos ei pesä käy tilillä kauppaa muuten ollenkaan.