CB
editStarted here March 2000
Portföljutveckling
editBakgrund
editIden med portföljutveckling är att man betraktar depån som en fond. Alla fonder har en fiktiv kurs som kallas NAV-kurs. NAV-kurs motsvarar pris per andel, fondens värde är då fondkurs multiplicerat med totalt andelar i fonden. Nu har vi gjort likadant för en depå vi betraktar depån som fond/fondbolag med en fiktiv fondkurs NAV och andelarna justeras då man gör insättningar och uttag. En anledning till vi gjorde så här, var en ide att man i framtiden skulle kunna köpa andelar i någon annans depå.
Skiss på hur det fungerar
editDepåvärde D(t) hämtas från från portfolio_data och insättningar uttag från tabellen transactions samt hjälp tabellen transactions_types, nav=1 ger en lista på de trtcoder som är insättningar/uttag.
Grund formel
D(t) = x(t)*y(t) x(t) - fiktiv NAV-kurs y(t) - andelar
Vi sätter dag 1 NAV-kursen till 100, kan då enkelt beräkna andelarna som är depåvärde/100 eller D(t)/100 dag 2 beräknas de nya andelarna om det har skett en insättning eller uttag under ett dygn, beteckning u(t). Andelarna justeras enligt formel
y(t)= y(t-1)*( 1 + u(t)/D(t-1)) (1)
Detta är en rekursiv formel, dagens andelar beräknas med hjälp av gårdagens andelar
och nav kurs kan beräknas
x(t) = D(t)/y(t)
En detalj om nettoinsättning u<0 används (1) om nettoinsättningen u > 0 används denna formel
y(t)= y(t-1)*( D(t)/(D(t)-u(t)) )
Nordnet visar resultatet av beräkningarna dels har på grafen depåutveckling på depåöversikten samt under avkastningsfliken.
Tidigare dokumentation finns på sidan Min_aktie-_och_fonddepå
Beräkningar
editUttgår från crontab på tux15.dev som gör NAV beräkningar
#NAV prylar 30 4 * * 1-5 /perl/cron/nav/nav_run.pl >/tmp/nav_run.log; /perl/cron/nav/nav_stat.sh > /tmp/nav_stat_sh.log 15 22 * * 1-5 /perl/cron/nav/nav_data2sakila.pl > /tmp/nav_data2sakila.log; /perl/cron/nav/nav_stat2sakila.pl > /tmp/nav_stat2sakila.log 30 22 * * 1 /perl/cron/nav/nav_init_add.pl >/tmp/nav_init_add.log; /perl/cron/nav/nav2_fix.pl > /tmp/nav2_fix_add.log
Maskiner databaser och tabeller Scripten finns på tux15.dev i katalogen
/perl/cron/nav
Databasen ProdCalc
- portfolio_nav_last
- portfolio_nav
- portfolio_nav_init
- portfolio_nav_stat
Databasen Sinaradce
- close_price_nav
Sakila
- portfolio_nav_intraday
- portfolio_nav_stat
Script 1.
/perl/cron/nav/nav_run.pl
Varje morgon kl 05:00 mellan måndag till fredag startar ett script som hämtar depåvärde från tabellen portfolio_data samt insättningar/uttag från tabellen transactions och därefter beräknar NAV-kurs och andelar, sparar sedan resultatet i en tabell som heter portfolio_nav_last samt portfolio_nav både dessa tabelller finns i databasen ProdCalc (mysql). Vi sparar ocå ner resultatet till Comstock databasen i en tabell som heter close_price_nav för att kunna generera grafer.
Flöde
För den senate handelsdagen depåer från portfolio_nav_last (Prodcalc) samt nav och andelar
För varje depå hämtar vi det senaste depåvärdet i basvaluta från portfolio_data (Sakila) samt tar fram insättningar/uttag från transactions här används även tabellen transaction_types som avgär vilka transationstyper som insättningar/uttag sätter nav=1
För specilella transaktionstyper tex insättningar av värdepapper behöver man beräkna värde av insättningen enda som finns i transactions är antal (qty) och vilket instrument (insid) och insatt belopp beräknas enligt
d = qty * factor * price * valutakurs
factor och price kommer från tabellen instrumnents och valutakurs kommer från tabellen valutor
sedan beräknas andelar och NAV enligt formel se nedan
Och resultatet uppdateras i portolio_nav_last samt insert med datum i portfolio_nav och close_price_nav
För att kunna skapa en graf, I tabellen close_price_nav har vi primär nycklarna crypt och datum crypt är här ett krypterat depånummer med en hemlighet. Förekommer när man hämtar grafen
https://www.nordnet.se/chart?style=sweb-style-plus&ins=NAV.26741c1cbbf6a6dcf81a0018e87c9088fbe554ca&from=months-1&to=&src=historic&plot=value&filter=weekend&filter=markettime(09:00,17:30)&fixedxaxis=on
Script 2
/perl/cron/nav/nav_stat.sh
Beräknar statistik för olika perioder resultat sparas i tabellen portfolio_nav_stats , i kolumnen period finns koderna D30 D90 D365 som betyder antal dagar bakåt i tiden samt den udda koden Y2001 som betyder sedan årsskiftet I huvudsak sparar vi data per datum period= D30 betyder andelar och NAV för 30 dagar sedan. Vi gör även volatilitets beräkning nav_std som används portföljrapporten Script 3
/perl/cron/nav/nav_data2sakila.pl
Kopierar data från tabellen portfolio_nav_last på ProdCalc till Sakila spara data i tabellen portfolio_nav_last_intraday
Script 4
/perl/cron/nav/nav_stat2sakila.pl
På samma sätt men nu tabellen portfolio_nav_stat
Tidigare för några månader sedan gjordes den här kopieringen efter nav_stat.sh var klart men vi var tvugna att flytta kopieringen till kvällen, scriptet nav_stat.sh var inte klar innan marknaden öppnade.
Script 5
/perl/cron/nav/nav_init_add.pl
Det här scriptet tar fram nya kunder gör en left join mellan portfolio_data och portfolio_nav_last_intraday
select a.portfolio from portfolios a JOIN portfolio_data b LEFT JOIN portfolio_nav_last_intraday c ON (a.portfolio=c.portfolio) where a.portfolio=b.portfolio and b.owncapital<>0 and a.ofcid not in (89,77,38,39) and c.portfolio is null
Gör sedan en insert av de nya depåerna i tabellen portfolio_nav_init på ProdCalc, sätter start NAV till 100 samt startdatum till 2007-01-01
Script 6
/perl/cron/nav/nav2_fix.pl
Det här scriptet gör beräkning för nya depåer från startdatum som finns i portfolio_nav_init.
Kör dag för dag hämtar depåvärde från asset.portfolio_data_hist på DWP historiska priser från tbl_snapshot.instruments (DWP)
Varning
editScriptet
/perl/cron/nav/nav_run.pl
Får under inga omständigheter köras manuellt, Anledning scriptet fungerar rekursivt eller faran ligger nav_run.pl körs en extra gång under smma dygn kommer det komma in dubletter
Adminstration
editFinns möjligehet att följa beräkningarna dag för dag för en enskild depå via den här länken
https://www.dev.nordnet.se/mux/cb/nav.html
visar data in tabell med kolumnerna ( med beskrivning) hämtar data direkt från portfolio_nav från databasen ProdCalc
portfolio base_currency datum ( datum enligt accountdate i transactions) owncapital ( Eget kapital från abasec nästan samma sak som depåvärde på depåöversikten owncapital inkuderar även räntan på pengarna) k50pant ( kan vara K50 eller K250 och någon annan pant ) owncapitalkorr ( owncapital - k50pant) io ( Insättning/uttag) iosum ( Ackumelerad insättnng) nav ( NAV-lurs) share ( andelar) error ( insid för de instrument som saknar priser ) portfolio_sum ( Saldo kommer från portfolio_data)
Omkörning av en enskild depå
Ibland kan det finnas skäl gör om beräkningen för en enskild depå, en ny transaktionstyp har lagts men kodningen har varit kodad som en insättning i tabellen transaktion_types
Här behöver vi göra en Request
på tux15.dev kör
/perl/cron/nav/nav_delete.pl 2020188
/perl/cron/nav/nav2_fix.pl
Adminstration av transaktions typer
NAV använder tabellen transactions_types för att avgöra om transaktion är insättning/uttag. Tabellen har även översättningar för de olika transaktionstypenra den adminsterars av Torbjörn via ett admin
https://newadmin.dev.nordnet.se/tux/extern/stats/transtyp_group.pl
Varje gång det kommer en ny transaktionstyper går ett mail till Torbjörn,mailet skapas av det här cronjobbet som även gör en insert av de nya transaktionstyperna
10 8 * * * /var/entrypoint/base/scheduled/risk/transtyp_insert_dwp.pl 2>&1 >> /var/log/data/transtyp_insert_dwp.log
Modell
editz = x*y
där z = depåvärde, x NAV kurs, y andelar vi kan även skriva z = U + R Där U total insättning/uttag och R totalt resultat
nu tar vi förändring z' =zt- zt_1
z'= x'*y + x *y'
och
z' = u + r
x* y' = u som ger yt=yt_1 + u /xt_1= yt_1 + u * yt_1 /zt_1 = yt_1(1 + u/zt_1)
sedan får vi xt genom
xt=zt/yt
Förbättringsförslag
editInser att hatera andelar och nav-kurs är komplicerat, ännu enklare och bättre är att använda en ränta på rå ränta modell
x(n) = 100 * (1+r(1))*(1+r(2))* ... * (1+r(n)) (1)
Där
r(i) = res(i)/|D(i-1)|
Som alla vet, depåvärde eller egetkapital är
D = T -S
D kan även skrivas
D = C - W + I - K
vi sätter
U = C - W R = I - K
T är tillgångar S är skulder, res resultat I Intäkt K kostnad W uttag C insatt start kapital och U är netto insättning
Nu förändring av eget kapital
Delta D(t) = D(t) - D(t-1) = u(t) + res(t)
res = D(t) - D(t-1) - u(t) u(t)= U(t) - U(t-1) dvs insättningar under ett dygn
dela upp insättning/uttag i insättning = upos och uttag = uminus OBS upos >= 0 och uminus >=0
u(t)= upos(t) - uminus(t) res(t) = D(t) - D(t-1) - dpos(t) + uminus(t) = D(t) + uminus(t) - (D(t-1) + upos(t))
r(t) = res(t)/(|D(t-1) + upos(t)|)
Anledning till division med (E(t-1) + dpos(t)) är att man måste anta att man börjar dagen med en insättning om det har gjort en insättning
x(n) kan då beräknas enligt (1)
x(n) = 100 * (1+r(1))*(1+r(2))* ... * (1+r(n))
och sedan andelar
y=E(t)/x(t)
FIFO
editFIFO står för First In First Out, på Nordnet används FIFO-netoden den för att beräkna realisationer dvs resultat av en realisering (Sälj ) för en period i vårt fall kalender år. FIFO-metod används i länderna Finland och Norge. Sverige och Danmark använder snitt metoden för att beräkna realiserat resultat, finns faktiskt fler metoder än snitt och FIFO metoden.
Typiskt för FIFO är att den är beräknings intensiv. Vi gör nu mera beräkningen varje dag för de senast dygnets realiseringar, ger även då kunderna möjlighet se sina realiseringar löpande. Alternativt och som vi gjorde tidigare göra beräkningen årligen inför skatte redovisningen.
Tänkte beskriva cronjobbet som går varje morgon och beräknar realiserat resultat och sedan FIFO algoritmen
Beräkningar
editSjälva iden är fånga upp de depåer som har gjort en affär sedan senaste körningen. Gör vi genom att spara det högsta värdet av acsid från tabellen transactions. Maxvärder av maxacid sparas i tabellen fifo_maxacids med kolumnerna portfolio och maxacsid
Har delat upp beräkningar på de olika länderna, på tron1 har vi
0 3 * * 2-6 /var/entrypoint/now/scheduled/fifo/runfifo.sh NORGE > /tmp/fifo_norge.log 15 3 * * 2-6 /var/entrypoint/now/scheduled/fifo/runfifo.sh FINLAND > /tmp/fifo_finland.log 45 3 * * 2-6 /var/entrypoint/now/scheduled/fifo/runfifo.sh DANMARK > /tmp/fifo_danmark.log
runfifo.sh
ORIGIN=$1 DIR=/var/entrypoint/now/scheduled/fifo LOG=/var/entrypoint/now/scheduled/fifo cd echo ${ORIGIN} $DIR/new_transactions.pl ${ORIGIN} > $DIR/new_${ORIGIN}.txt # Sätter maxid till noll $DIR/set_maxid.pl $DIR/new_${ORIGIN}.txt wc $DIR/new_${ORIGIN}.txt $DIR/get_fifodepots.pl ${ORIGIN} > $DIR/${ORIGIN}.txt wc $DIR/${ORIGIN}.txt # Flitrerar ut de senast gjorda affärerna $DIR/last_transactions_dep.pl $DIR/${ORIGIN}.txt > $DIR/${ORIGIN}_last.txt wc $DIR/${ORIGIN}_last.txt # Här körs FIFO time $DIR/fifodep.pl $DIR/${ORIGIN}_last.txt > $LOG/${ORIGIN}_last.log 2> $LOG/${ORIGIN}_last.err
Databaser och tabeller DWP
- transactions.transactions
- transactions.fifo_maxacsid
- transactions.fifo_data
- transactions.fifo_change
Sakila
- fifo_result
- fifo_result_extra
- fifo_instorder
- fifo_agreement
Steg 1
Fånga upp de depåer som är nya samt har gjor den senaste körning, när listan är klar kan man köra huvud programmet fifodep.pl new_transactions.pl
Tar fram helt nya depå depåer som har gjort affärer för första gången för perioden nuvarande år, som är default period Sparar depåerna på fil
set_maxid.pl
Sätter maxid till noll i tabellen fifo_maxacsid
get_fifodepots.pl
och
last_transactions_dep.pl
Resulterar i en lista med depåer som har gjort affärer sedan den senaste körning samt
Slutligen körs huvudprogrammet för listan av depåer som har tagits fram ovan
fifodep.pl $DIR/${ORIGIN}_last.txt
Klart.
Perl moduler
edit- Nordnet::FIFO::Fifoc
- Nordnet::FIFO::Fifohtml
- Nordnet::Fifocalc
- Nordnet::Fifonew2
Modul som gör beräkningen av realisationer är Nordnet::FIFO::Fifoc som ärver metoder från den äldre modulen Nordnet::Fifocalc
NAME Nordnet::FIFO::Fifoc - Beräknas avkastning enligt FIFO medoden för en period SYNOPSIS Nordnet::FIFO::Fifoc; DESCRIPTION Beräkna avkastnig enligt FIFO ärver från modulen Nordnet::Fifocalc Constructor new() my $fifocalc = new Nordnet::FIFO::Fifoc( deklyear => $deklyear, depot_nr => $depot_nr, dbh_ro => $dbh_ro, service => $service, lang => $lang, ); Example: my $fifocalc = new Nordnet::FIFO::Fifoc( deklyear => $deklyear, depot_nr => $depot_nr, dbh_ro => $dbh_ro, service => $service, lang => $lang, ); Kort beskriving # Hämtar de senate instrumenten som som har gjort en affär sedan förra körningen my @inst=$fifocalc->senaste_trans(); my @MAX; # För varje instrument foreach my $h ( @inst ) { # Gör en FIFO beräkning my $data = $fifocalc->do_fifo( $h->{insid} ); # Beräknar snitt-avkastning $data = $fifocalc->do_snitt( $data); # Sapar data $fifocalc->save_data($data,$h->{insid}); # Tar bort och sparar resultat för varje instrument $fifocalc->delete_save_result($h->{insid}); $fifocalc->save_result($data,$h->{insid}) if $fifocalc->realisering($data); # Sparar transactionsid i en lista push @MAX,$fifocalc->max_acsid($data);; } # Uppdaterar maxid $fifocalc->update_maxid($fifocalc->max(@MAX);); senaste_trans() my @inst=$fifocalc->senaste_trans(); Hämtar de senaste transaktionera sedan den senaste körningen perl v5.8.8 var::entrypoint::base::Nordnet::FIFO::Fifoc(3)
Modulen Nordnet::FIFO::Fifohtml bygger upp html sidan med klasssisk CGI. Modulen ärver även den metoder från den äldre modulen Nordnet::Fifonew2
Adminstration
editI vårt gröna admin kan vi köra realisationsprogrammet för en enskild depå
https://newadmin.dev.nordnet.se/mux/web/deklaration/fifo.html
Ett trick att göra om en körning för en depå fungerar både på web och admin lägga till reset=1 i som parameter i url
https://newadmin.dev.nordnet.se/mux/web/deklaration/fifo2008.html?reset=1
klicka sedan på beräknings knappen och en ny beräkning görs för alla instrument för perioden
Delar av content reporting
editVarje månad tar vi fram statistik för hur många kunder samt typer av kunder (proffisionell eller icke proffisionell) och hur ofta kunder är använt realtidsinformation (snapshot) från de olika börserna. Varje börs vill ha data i sitt eget format Dokumentation sedan tidigare finns här Content Reporting
Vi har två web sidor där man kan hämta information på antal snapshot
Filserver där vi kan lägger upp filer på legacyapp1.prod.nordnet.se
http://10.64.169.25/stats/
samt i gröna adminet
https://newadmin.dev.nordnet.se/mux/web/content_reporting/index.html
crontab
15 22 3 * * /var/entrypoint/now/scheduled/snapshot/report_to_deutchebors.sh > /var/log/report_to_deutchebors.log 25 22 3 * * /var/entrypoint/now/scheduled/snapshot/report_db.sh > /var/log/report_db.log 45 22 3 * * /var/entrypoint/now/scheduled/snapshot/ub_report_db.sh > /var/log/ub_report_db.log 5 23 1 * * /var/entrypoint/now/scheduled/snapshot/omx_report.sh 35 22 1 * * /var/entrypoint/now/scheduled/snapshot/cme_report.sh 35 23 1 * * /var/entrypoint/now/scheduled/snapshot/cme_snapshot.pl 0 23 1 * * /var/entrypoint/ica/scheduled/ica.sh >> /var/log/icastats.log
Statistik beräkningar för instrument, volatilitet
editVi gör en del statistk berkningar som volatiliet och genomsnittlig avkastning samt sparar start väden för olika perioder
Vi använder historisk kurser som hämtas frånsix varje dag hefter nya kurser har tankats från sis starts ett script som statistk beäkningarna
crontab
10 8 * * * /perl/cron/six/quotehistory.sh
efter data kurser tankats in i tabellen history_six
startar
/var/entrypoint/base/scheduled/cron/six/stat2db.pl
som gör satstistik beräkningar för olika perioder
my %period=('D7'=>7, 'D30'=>30, 'D90'=>90, 'D180'=>180, 'D365'=>365, 'D730'=>730, 'D1095'=>1095, 'D1825'=>1825, 'D10000'=>10000, 'Y2001'=>$dagar, );
Y2001 betyder här antal dagar från det senaste årsskiftet
Resultatet sparas i tabellen history_six_stat på Sakila
Beräkning av volatilitet eller statndard avikelse anvönds modulen
Nordnet::Stat
Först beäknas procentuell färädring aktiekursen
my $posdata=$s->positive(\@data); my $logdata = $s->log($posdata); my $propc = $s->diff($logdata);
sedan beräknas volatiliet mm
my $mean_p=$s->mean($propc); my $std_p=$s->std($propc); my $min_p=$s->min($propc); my $max_p=$s->max($propc);
Aktiedirekt
editAktiedirekt byggdes innan NOW byggdes har nåhot annan strukter, anv'nder is stror den struktur som beskrivs i Mason boken. dvs Control Vy ligger i samma fil och autohandel anvämds i varje kataolg finns ingen dhandler som i NOW
Startsidan är speciell, för att start url ska vara
https://www.nordnetdirekt.se/
Skapa vi en semistatisk första sida med cronjobb som går varje minut
* * * * * /var/entrypoint/aktiedirekt/scheduled/gen_firstpage_nordnetdirekt.sh > /var/log/ndindex.log 2>&1
ICA
editICA tjänsten har i grunden samma struktur som Aktiedirekt och samma innehåll kurser och nyheter men utan meny system. ICA ramar in våra script samt gör en en inloggning vi en separat lina (Snix??). ICA skickar personnummer och en krypterad sträng (delad hemlighet) till oss, om allt ok skickar vi tillbaka en tcket (crypterad sträng) som sedan ICA skickar tillbaka i kundens inlognings url, om allt ok sätts kaka på Nordnet och kunden är inloggad.
Finn/Gripen/Öresund
editÄr minimal applikation som ramas in av tredjeparts samarbeten Består av 38 script i en och samma katalog
clabjo /var/entrypoint/finngripen/perl/mason/web$ ls autohandler graph.html logout.html passandeavbestall.html purchase.html stoploss.html vinnare.html avslut.mas handla.html notor.html passandebedomning.html shownote2.html stoploss_info.html visanyhet.html check.html help.html nyheter.html passandefragor1.html shownote.html stoplossorder.mas warrantkurser.mas depa.html kurser.html order.mas passandefragor.html shownote_oldfinn.html tickinfo.html warrantsform.mas dropdown.mas login.html oversikt.html passandelasmer.html soksymbol.html transaktioner.html
vilka instrument som tillåts handlas begränsas av vilken lista som instrumentet ligger på.
select b.* from nemo_instr a JOIN nemo_meta_norden b on (a.identifier=b.identifier and a.marketplace=b.marketplace and a.marketplace in (11,13,30) and a.shortname is not null) left join nemo_listor c on (a.marketplace=c.marketplace and a.identifier=c.identifier) where (b.kind in ('A') and c.listid in (6,8,9,10,12,23,24,25,13,366337,7000,22,26,41) and b.shortname=?) or ( b.kind in ('WNT') an d a.currency='SEK' and b.shortname=?)
CM
editClient manager (CM) gar funktionen ett användare kan handla på fler depåer. Användaren loggar in via NASA antingen med eller utan SMS ticket. Användare kommer till en startsida med information om depåvärden, marknadsvärden mm för de depåer som är kopplade. Användaren kan se depåöversikt och genomföra handel. Det som inte finns i CM jämfört med NOW är marknadsinformation som aktiekurser nyheter mm.
tabeller som används finns i schemat clientmanager på ORAP
users users_accno users_roles
Username och userid finns i tabellen users (primärnyckel userid), vid inloggning hämtas alla depåer frpn NASA och sparas temporaärt i tabellen users_accno
tabellen users_roles beskriver vilken beärighet anvädaren har det advisor som betyder bara se och broker som betyder se och handla
för en användare ska vara broker ska både advisot och broker finnas i tabellen users_roles dvs en rad med adisor och en rad med broker tvår rader för samma userid
Portföljrapport
editPortfölj rapporten syfte är att visa hur depån ser ut för en viss period, balans och resultat räkning för en period. indata är startdatum slutdatum. Som ger en bild av hur depån ser för ett visst datum skutdatum i det här fallet. Startdatum används för att beräkna avksatning under perioden samt perioden för transaktioner.
Vi använder Abasec data som sparas undan varje dag. Tabellerna vi använder finns på DWP i schemat tbl_snapshot
- portfolio_data
- positions
- instrument
Data tankas kl 3 varje natt mellan tisdag till fredag. För att få fram korrekt data för ett givet datum får man backa datum med en dag, giver att man har "accountdate" som indatum som ligger mellan måndag till fredag