Du kan nu finde opdaterede udgaver af mine forskellige værktøjer til at hente data på Nordnet på https://github.com/helmstedt/nordnet-utilities. God fornøjelse.
Tag: investering
Opdateret program til at hente dine transaktionsdata fra Saxo Bank
Saxo Bank har opdateret nogle småting i deres login-procedure, og derfor har jeg opdateret mit program til at hente transaktionsdata.
Læs om hvordan jeg har udviklet programmet i indlægget om den gamle udgave.
Her er den opdaterede kode:
# -*- coding: utf-8 -*-
# Author: Morten Helmstedt. E-mail: helmstedt@gmail.com
"""This program logs into a Saxo Bank account and lets you make API requests."""
import requests
from datetime import datetime
from datetime import date
from bs4 import BeautifulSoup
# USER ACCOUNT AND PERIOD DATA. SHOULD BE EDITED FOR YOUR NEEDS #
# Saxo user account credentials
user = '' # your user id
password = '' # your password
# Start date (start of period for transactions) and date today used for extraction of transactions
startdate = '2019-01-01'
today = date.today()
enddate = datetime.strftime(today, '%Y-%m-%d')
# LOGIN TO SAXO BANK
# Start requests session and set user agent
session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; rv:112.0) Gecko/20100101 Firefox/112.0'
# Visit login page and get AuthnRequest token value from input form
url = 'https://www.saxoinvestor.dk/Login/da/'
request = session.get(url)
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"id":"AuthnRequest"})
authnrequest = input[0]["value"]
# Login step 1: Submit username, password and token and get another token back
url = 'https://www.saxoinvestor.dk/Login/da/'
request = session.post(url, data = {'field_userid': user, 'field_password': password, 'AuthnRequest': authnrequest})
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"name":"SAMLResponse"})
# Most of the time this works
if input:
samlresponse = input[0]["value"]
# But sometimes there's a disclaimer that Saxo Bank would like you to accept
else:
input = soup.find_all('input')
inputs = {}
try:
for i in input:
inputs[i['name']] = i['value']
except:
pass
url = 'https://www.saxotrader.com/disclaimer'
request = session.post(url, data=inputs)
cook = request.cookies['DisclaimerApp']
returnurl = cook[cook.find("ReturnUrl")+10:cook.find("&IsClientStation")]
url = 'https://live.logonvalidation.net/complete-app-consent/' + returnurl[returnurl.find("complete-app-consent/")+21:]
request = session.get(url)
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"name":"SAMLResponse"})
samlresponse = input[0]["value"]
# Login step 2: Get bearer token necessary for API requests
url = 'https://www.saxoinvestor.dk/investor/login.sso.ashx'
response = session.post(url, data = {'SAMLResponse': samlresponse})
response_text = response.text
bearer = response_text[response_text.find("BEARER"):response_text.find("/exp/")]
# START API CALLS
# Documentation at https://www.developer.saxo/openapi/learn
# Set bearer token as header
headers = {'Authorization': bearer}
# First API request gets Client Key which is used for most API calls
# See https://www.developer.saxo/openapi/learn/the-tutorial for expected return data
url = 'https://www.saxoinvestor.dk/openapi/port/v1/clients/me'
r = requests.get(url, headers=headers)
clientdata = r.json()
clientkey = clientdata['ClientKey']
# Example API call #1
url = 'https://www.saxoinvestor.dk/openapi/cs/v1/reports/aggregatedAmounts/' + clientkey + '/' + startdate + '/' + enddate + '/'
r = requests.get(url, headers=headers)
data = r.json()
# Working on that data to add some transaction types to personal system
saxoaccountname = "Aktiesparekonto: Saxo Bank"
currency = "DKK"
saxotransactions = ""
for item in data['Data']:
if item['AffectsBalance'] == True:
date = item['Date']
amount = item['Amount']
amount_str = str(amount).replace(".",",")
if item['UnderlyingInstrumentDescription'] == 'Cash deposit or withdrawal' or item['UnderlyingInstrumentDescription'] == 'Cash inter-account transfer':
if amount > 0:
transactiontype = 'INDBETALING'
elif amount < 0:
transactiontype = 'HÆVNING'
saxotransactions += ";" + date + ";" + date + ";" + date + ";" + transactiontype + ";;;;;;;;" + amount_str + ";" + currency + ";;;;;;;;;" + saxoaccountname + "\r\n"
if item['AmountTypeName'] == 'Corporate Actions - Cash Dividends':
transactiontype = "UDB."
if item['InstrumentDescription'] == "Novo Nordisk B A/S":
paper = "Novo B"
papertype = "Aktie"
if item['InstrumentDescription'] == "Tryg A/S":
paper = "TRYG"
papertype = "Aktie"
saxotransactions += ";" + date + ";" + date + ";" + date + ";" + transactiontype + ";" + paper + ";" + papertype + ";;;;;;" + amount_str + ";" + currency + ";;;;;;;;;" + saxoaccountname + "\n"
# Example API call #2
url = "https://www.saxoinvestor.dk/openapi/cs/v1/reports/trades/" + clientkey + "?fromDate=" + startdate + "&" + "toDate=" + enddate
r = requests.get(url, headers=headers)
data = r.json()
# Working on that data to add trades to personal system
for item in data['Data']:
date = item['AdjustedTradeDate']
numberofpapers = str(int(item['Amount']))
amount_str = str(item['BookedAmountAccountCurrency']).replace(".",",")
priceperpaper = str(item['BookedAmountAccountCurrency'] / item['Amount']).replace(".",",")
if item['TradeEventType'] == 'Bought':
transactiontype = "KØBT"
if item['AssetType'] == 'Stock':
papertype = "Aktie"
if item['InstrumentDescription'] == "Novo Nordisk B A/S":
paper = "Novo B"
isin = "DK0060534915"
if item['InstrumentDescription'] == "Tryg A/S":
paper = "TRYG"
isin = "DK0060636678"
saxotransactions += ";" + date + ";" + date + ";" + date + ";" + transactiontype + ";" + paper + ";" + papertype + ";" + isin + ";" + numberofpapers + ";" + priceperpaper + ";;;" + amount_str + ";" + currency + ";;;;;;;;;" + saxoaccountname + "\n"
ETF’er og fonde med aktiebeskatning 2021
For et par år siden blev det muligt at købe og tjene/tabe penge på aktiebaserede ETF’er og udenlandske investeringsfonde som aktieindkomst og ikke længere som kapitalindkomst.
Det eneste problem er/var, er at det velmenende regneark, der viser aktiebaserede investeringsselskaber, som er godkendt til den lavere beskatning på skat.dk, er en lille smule svært at bruge, når man gerne vil sammenligne værdipapirerne og finde ud af, hvor de kan købes.
Derfor har jeg lavet https://wallnot.dk/stocks.
Her kan du læse om, hvordan jeg gjorde.
- Jeg downloaded excelarket fra skat.dk
- Jeg tilføjede nogle kolonner og gemte som CSV-fil
- Jeg brugte Python til at hente data og links til værdipapirer hos Saxo Bank, Nordnet og Morningstar
- Jeg oprettede en app i Django og definerede en datamodel tilsvarende excelarket
- Jeg importerede data til Django
- Jeg byggede visningen
Nogle timers arbejde for mig. Forhåbentlig nogle sparede timer for dig.
Download af excelark
https://skat.dk/getfile.aspx?id=145013&type=xlsx
Tilføje nogle kolonner og gemme som CSV-fil
Lidt upædagogisk, men hvad:
Registreringsland/Skattemæssigt hjemsted;ISIN-kode;Navn;LEI kode;ASIDENT;CVR/SE/TIN;Venligt navn;Første registreringsår;Morningstar_id;Saxo_id;Nordnet_url;Nordnet_id;Nordnet_ÅOP;Nordnet_udbyttepolitik;Nordnet_prospekt;Saxo_url;Morningstar_prospekt;Morningstar_url;Morningstar_ÅOP
Hente data og links til værdipapirer
Ret sjusket Python-program. Men fungerer OK:
import csv
import requests
import re
import json
from bs4 import BeautifulSoup
def nordnet_cookies():
# Nordnet user account credentials
user = ''
password = ''
# A cookie dictionary for storing cookies
cookies = {}
# First part of cookie setting prior to login
url = 'https://classic.nordnet.dk/mux/login/start.html?cmpi=start-loggain&state=signin'
request = requests.get(url)
cookies['LOL'] = request.cookies['LOL']
cookies['TUX-COOKIE'] = request.cookies['TUX-COOKIE']
# Second part of cookie setting prior to login
url = 'https://classic.nordnet.dk/api/2/login/anonymous'
request = requests.post(url, cookies=cookies)
cookies['NOW'] = request.cookies['NOW']
# Actual login that gets us cookies required for later use
url = "https://classic.nordnet.dk/api/2/authentication/basic/login"
request = requests.post(url,cookies=cookies, data = {'username': user, 'password': password})
cookies['NOW'] = request.cookies['NOW']
cookies['xsrf'] = request.cookies['xsrf']
# Getting a NEXT cookie
url = "https://classic.nordnet.dk/oauth2/authorize?client_id=NEXT&response_type=code&redirect_uri=https://www.nordnet.dk/oauth2/"
request = requests.get(url, cookies=cookies)
cookies['NEXT'] = request.history[1].cookies['NEXT']
return cookies
def saxo_headers():
# Saxo user account credentials
user = ''
password = ''
# Visit login page and get AuthnRequest token value from input form
url = 'https://www.saxoinvestor.dk/Login/da/'
request = requests.get(url)
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"id":"AuthnRequest"})
authnrequest = input[0]["value"]
# Login step 1: Submit username, password and token and get another token back
url = 'https://www.saxoinvestor.dk/Login/da/'
request = requests.post(url, data = {'field_userid': user, 'field_password': password, 'AuthnRequest': authnrequest})
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"name":"SAMLResponse"})
# Most of the time this works
if input:
samlresponse = input[0]["value"]
# But sometimes there's a disclaimer that Saxo Bank would like you to accept
else:
input = soup.find_all('input')
inputs = {}
try:
for i in input:
inputs[i['name']] = i['value']
except:
pass
url = 'https://www.saxotrader.com/disclaimer'
request = requests.post(url, data=inputs)
cook = request.cookies['DisclaimerApp']
returnurl = cook[cook.find("ReturnUrl")+10:cook.find("&IsClientStation")]
url = 'https://live.logonvalidation.net/complete-app-consent/' + returnurl[returnurl.find("complete-app-consent/")+21:]
request = requests.get(url)
soup = BeautifulSoup(request.text, "html.parser")
input = soup.find_all('input', {"name":"SAMLResponse"})
samlresponse = input[0]["value"]
# Login step 2: Get bearer token necessary for API requests
url = 'https://www.saxoinvestor.dk/investor/login.sso.ashx'
r = requests.post(url, data = {'SAMLResponse': samlresponse})
bearer = r.history[0].headers['Location']
bearer = bearer[bearer.find("BEARER"):bearer.find("/exp/")]
bearer = bearer.replace("%20"," ")
# START API CALLS
# Documentation at https://www.developer.saxo/openapi/learn
# Set bearer token as header
headers = {'Authorization': bearer}
return headers
nordnet_cookies = nordnet_cookies()
saxo_headers = saxo_headers()
filename = 'Copy of ABIS liste 2021 - opdateret den 11-01-2021.csv'
output_file = 'stocks.csv'
get_nordnet = True
get_saxo = True
get_morningstar = True
with open(output_file, 'w', newline='') as output_csv:
paperwriter = csv.writer(output_csv, delimiter=';', quotechar ='"', quoting = csv.QUOTE_MINIMAL)
with open(filename) as csvfile:
paperreader = csv.reader(csvfile, delimiter=';')
for row in paperreader:
if row[1] != '0' and row[1] != 'ISIN-kode' and row[1] != '':
isin = row[1]
if get_morningstar == True:
morningstar = requests.get('https://www.morningstar.dk/dk/util/SecuritySearch.ashx?q=' + isin)
morningstar_text = morningstar.text
if morningstar_text:
first_hit = morningstar_text[morningstar_text.index("{"):morningstar_text.index("}")+1]
first_hit_json = json.loads(first_hit)
morningstar_id = first_hit_json['i']
morningstar_url = 'https://www.morningstar.dk/dk/funds/snapshot/snapshot.aspx?id=' + morningstar_id
morningstar_info = requests.get(morningstar_url)
soup = BeautifulSoup(morningstar_info.text, "lxml")
try:
aop = soup.find(text=re.compile('Løbende omkostning'))
aop_value = aop.parent.next.next.next.next.next.next.next.string
if aop_value:
cleaned_aop = aop_value.replace(",",".").replace("%","")
else:
cleaned_aop = ''
except:
cleaned_aop = ''
morningstar_documents = requests.get('https://www.morningstar.dk/dk/funds/snapshot/snapshot.aspx?id=' + morningstar_id + '&tab=12')
document_soup = BeautifulSoup(morningstar_documents.text, "lxml")
try:
prospect = document_soup.find(text=re.compile('CI'))
prospect_link = prospect.parent.next.next.next.next.next.next.next.next.a['href']
document_id = prospect_link[prospect_link.index("Id=")+3:prospect_link.rfind("&")]
document_url = 'https://doc.morningstar.com/document/' + document_id + '.msdoc'
except:
try:
prospect = document_soup.find(text=re.compile('Prospekt'))
prospect_link = prospect.parent.next.next.next.next.next.next.next.next.a['href']
document_id = prospect_link[prospect_link.index("Id=")+3:prospect_link.rfind("&")]
document_url = 'https://doc.morningstar.com/document/' + document_id + '.msdoc'
except:
document_url = ''
row[8] = morningstar_id
row[16] = document_url
row[17] = morningstar_url
row[18] = cleaned_aop
if get_saxo == True:
saxo = requests.get('https://www.saxotrader.com/openapi/ref/v1/instruments/?$top=201&$skip=0&includeNonTradable=true&AssetTypes=Stock,Bond,MutualFund,Etf,Etc,Etn,Fund,Rights,CompanyWarrant,StockIndex&keywords=' + isin + '&OrderBy=', headers=saxo_headers)
try:
saxo_json = saxo.json()
if saxo_json and saxo.status_code == 200:
try:
data = saxo_json['Data']
if data:
identifier = data[0]['Identifier']
assettype = data[0]['AssetType']
saxo_url = 'https://www.saxotrader.com/d/trading/product-overview?assetType=' + assettype + '&uic=' + str(identifier)
row[9] = identifier
row[15] = saxo_url
except Exception as e:
print(e)
breakpoint()
except:
pass
if get_nordnet == True:
nordnet = requests.get('https://www.nordnet.dk/api/2/main_search?query=' + isin + '&search_space=ALL&limit=60', cookies=nordnet_cookies)
nordnet_json = nordnet.json()
if nordnet_json and nordnet.status_code == 200:
try:
display_types = [hit['display_group_type'] for hit in nordnet_json]
except:
breakpoint()
good_hit = "wait"
try:
good_hit = display_types.index('ETF')
base_url = 'https://www.nordnet.dk/markedet/etf-lister/'
except:
try:
good_hit = display_types.index('PINV')
base_url = 'https://www.nordnet.dk/markedet/investeringsforeninger-liste/'
except:
try:
good_hit = display_types.index('FUND')
base_url = 'https://www.nordnet.dk/markedet/fondslister/'
except:
try:
bad_hit = display_types.index('NEWS')
except:
try:
good_hit = display_types.index('EQUITY')
base_url = 'https://www.nordnet.dk/markedet/aktiekurser/'
except:
breakpoint()
if good_hit != 'wait':
results = nordnet_json[good_hit]['results']
instrument_id = results[0]['instrument_id']
display_name = results[0]['display_name']
space_counter = 0
paper_url = ''
for letter in display_name:
if letter == " ":
space_counter += 1
if space_counter > 2:
break
letter = '-'
paper_url += letter
else:
letter = letter.lower()
paper_url += letter
full_url = base_url + str(instrument_id) + '-' + paper_url
if "&" in full_url:
full_url = full_url.replace("&","")
check_full_url = requests.get(full_url)
soup = BeautifulSoup(check_full_url.text, "lxml")
try:
policy = soup.find('span', text=re.compile('Udbyttepolitik'))
policy_value = policy.next.next.string
except:
policy_value = "Ukendt"
try:
prospectus = soup.find('span', text=re.compile('Faktaark'))
prospectus_value = prospectus.next.next.a['href']
cleaned_prospectus = prospectus_value[:prospectus_value.rfind("?")].replace('http','https')
except:
cleaned_prospectus = "Ukendt"
try:
aop = soup.find('span', text=re.compile('Årlig omkostning'))
aop_value = aop.next.next.get_text()
cleaned_aop = aop_value.replace(",",".").replace("%","")
except:
cleaned_aop = "Ukendt"
row[10] = check_full_url.url
row[11] = instrument_id
row[12] = cleaned_aop
row[13] = policy_value
row[14] = cleaned_prospectus
print(row)
paperwriter.writerow(row)
Datamodel i Django
Her er models.py:
from django.db import models
class Stock(models.Model):
country = models.CharField('Registreringsland', max_length=2)
isin = models.CharField('ISIN-kode', max_length=20, blank=True)
name = models.CharField('Navn', max_length=200, blank=True)
lei = models.CharField('LEI-kode', max_length=20, blank=True)
asident = models.CharField('ASIDENT', max_length=20, blank=True)
cvr = models.CharField('CVR/SE/TIN', max_length=20, blank=True)
friendly_name = models.CharField('Venligt navn', max_length=200, blank=True)
first_registration_year = models.CharField('Første registreringsår', max_length=4, blank=True)
morningstar_id = models.CharField('Morningstar: Id', max_length=20, blank=True)
saxo_id = models.CharField('Saxo Bank: Id', max_length=20, blank=True)
nordnet_id = models.CharField('Nordnet: Id', max_length=20, blank=True)
morningstar_url = models.URLField('Morningstar: Url', max_length=200, blank=True)
saxo_url = models.URLField('Saxo Bank: Url', max_length=200, blank=True)
nordnet_url = models.URLField('Nordnet: Url', max_length=200, blank=True)
morningstar_aop = models.FloatField('Morningstar: Løbende omkostninger', null=True, blank=True)
nordnet_aop = models.FloatField('Nordnet: Løbende omkostninger', null=True, blank=True)
nordnet_dividend = models.CharField('Nordnet: Udbyttepolitik', max_length=20, blank=True)
nordnet_prospect = models.URLField('Nordnet: Investorinformation', max_length=200, blank=True)
morningstar_prospect = models.URLField('Morningstar: Investorinformation', max_length=200, blank=True)
Importere data til Django
Her brugte jeg Django’s databasehåndtering i stedet for selv at skrive SQL-sætninger:
import csv
with open('stocks.csv', newline='\n') as csvfile:
reader = csv.DictReader(csvfile, delimiter=";")
count = 0
for row in reader:
stock = Stock(country = row['Registreringsland/Skattemæssigt hjemsted'])
if row['ISIN-kode']:
stock.isin = row['ISIN-kode']
if row['Navn']:
stock.name = row['Navn']
if row['LEI kode']:
stock.lei = row['LEI kode']
if row['ASIDENT']:
stock.asident = row['ASIDENT']
if row['CVR/SE/TIN']:
stock.cvr = row['CVR/SE/TIN']
if row['Venligt navn']:
stock.friendly_name = row['Venligt navn']
if row['Første registreringsår']:
stock.first_registration_year = row['Første registreringsår']
if row['Morningstar_id']:
stock.morningstar_id = row['Morningstar_id']
if row['Saxo_id']:
stock.saxo_id = row['Saxo_id']
if row['Nordnet_id']:
stock.nordnet_id = row['Nordnet_id']
if row['Morningstar_url']:
stock.morningstar_url = row['Morningstar_url']
if row['Saxo_url']:
stock.saxo_url = row['Saxo_url']
if row['Nordnet_url']:
stock.nordnet_url = row['Nordnet_url']
if row['Morningstar_ÅOP']:
stock.morningstar_aop = row['Morningstar_ÅOP']
if row['Nordnet_ÅOP'] and row['Nordnet_ÅOP'] != '-' and row['Nordnet_ÅOP'] != 'Ukendt':
stock.nordnet_aop = row['Nordnet_ÅOP']
if row['Nordnet_udbyttepolitik']:
stock.nordnet_dividend = row['Nordnet_udbyttepolitik']
if row['Nordnet_prospekt']:
stock.nordnet_prospect = row['Nordnet_prospekt']
if row['Morningstar_prospekt']:
stock.morningstar_prospect = row['Morningstar_prospekt']
stock.save()
count += 1
print(count)
Bygge visningen
Her er views.py:
from django.shortcuts import render
from .models import Stock
def index(request):
#FILTER LOGIC
if request.GET.get('filter'):
filter = request.GET.get('filter')
if filter == 'nordnetsaxo':
stocks = Stock.objects.exclude(nordnet_url='') | Stock.objects.exclude(saxo_url='')
elif filter == 'nordnet':
stocks = Stock.objects.exclude(nordnet_url='')
elif filter == 'saxo':
stocks = Stock.objects.exclude(saxo_url='')
elif filter == 'ikkenordnetsaxo':
stocks = Stock.objects.filter(nordnet_url='').filter(saxo_url='')
elif filter == 'alle':
stocks = Stock.objects.all()
else:
stocks = Stock.objects.exclude(nordnet_url='') | Stock.objects.exclude(saxo_url='')
#SORT LOGIC
sort = request.GET.get('sort')
print(sort)
if sort == "name" or not sort:
stocks = stocks.order_by('name')
elif sort == "-name":
stocks = stocks.order_by('-name')
elif sort == "isin":
stocks = stocks.order_by('isin')
elif sort == "-isin":
stocks = stocks.order_by('-isin')
elif sort == "morningstar_aop":
stocks = stocks.order_by('morningstar_aop')
elif sort == "-morningstar_aop":
stocks = stocks.order_by('-morningstar_aop')
elif sort == "nordnet_aop":
stocks = stocks.order_by('nordnet_aop')
elif sort == "-nordnet_aop":
stocks = stocks.order_by('-nordnet_aop')
context = {'stocks': stocks}
return render(request, 'stocks/index.html', context)
Og her er så skabelonen index.html:
{% extends "stocks/base.html" %}
{% load static %}
{% block title %}ETF'er og fonde med aktiebeskatning 2021{% endblock %}
{% block content %}{% spaceless %}
<h1>ETF'er og fonde med aktiebeskatning 2021</h1>
<p>Du har læst om, <a href="https://www.nordnet.dk/blog/nye-regler-for-beskatning-af-investeringsfonde/">at aktiebaserede ETF'er og udenlandske investeringsfonde fra 2020 beskattes som aktieindkomst og ikke længere som kapitalindkomst</a>.</p>
<p>Du har endda fundet <a href="https://skat.dk/getfile.aspx?id=145013&type=xlsx">det fine regneark, der viser aktiebaserede investeringsselskaber</a> på <a href="https://skat.dk/skat.aspx?oid=2244641">skat.dk</a>.</p>
<p>Men det er godt nok svært for dig at få overblik over, hvilke af papirerne du overhovedet kan købe som almindelig hobby-/cryptoinvestor, og at sammenligne omkostninger, ÅOP og hvad det ellers hedder, for at finde det rigtige køb.</p>
<p>Her er et forsøg på at løse dit (og mit) problem. Data kommer fra <a href="https://skat.dk/getfile.aspx?id=145013&type=xlsx">det fine regneark</a> og har samme fejl og mangler, men er suppleret med nyttige informationer og links.</p>
<p><a href="#forbehold">Du kan læse om forbehold nederst på siden</a> og du kan <a href="https://helmstedt.dk/2021/03/etfer-og-fonde-med-aktiebeskatning-2021/">læse om hvordan siden er lavet på min blog</a>.</p>
<p><strong>Vis til salg hos:</strong>
<form id="prefs">
<input type="radio" id="nordnetsaxo" name="filter" value="nordnetsaxo"{% if request.GET.filter == "nordnetsaxo" or not request.GET.filter %} checked{% endif %}>
<label title="Værdipapirer til salg hos Nordnet, Saxo Bank eller begge steder" for="nordnetsaxo">Nordnet og/eller Saxo Bank</label>
<input type="radio" id="nordnet" name="filter" value="nordnet"{% if request.GET.filter == "nordnet" %} checked{% endif %}>
<label title="Værdipapirer til salg hos Nordnet" for="nordnet">Nordnet</label>
<input type="radio" id="saxo" name="filter" value="saxo"{% if request.GET.filter == "saxo" %} checked{% endif %}>
<label title="Værdipapirer til salg hos Saxo Bank" for="saxo">Saxo Bank</label>
<input type="radio" id="ikkenordnetsaxo" name="filter" value="ikkenordnetsaxo"{% if request.GET.filter == "ikkenordnetsaxo" %} checked{% endif %}>
<label title="Værdipapirer, der hverken er til salg hos Nordnet eller Saxo Bank" for="ikkenordnetsaxo">Ikke Nordnet og/eller Saxo</label>
<input type="radio" id="alle" name="filter" value="alle"{% if request.GET.filter == "alle" %} checked{% endif %}>
<label title="Alle værdipapirer, både dem der kan købes hos Nordnet/Saxo Bank og de, der ikke kan" for="alle">Hele pivtøjet</label>
</form>
</p>
<table>
<tr>
<th><a href="{% url 'stocks_index' %}?sort={% if request.GET.sort == "-name" %}name{% else %}-name{% endif %}">Navn</a></th>
<th><a href="{% url 'stocks_index' %}?sort={% if request.GET.sort == "isin" %}-isin{% else %}isin{% endif %}">Isin</a></th>
<th><a href="{% url 'stocks_index' %}?sort={% if request.GET.sort == "morningstar_aop" %}-morningstar_aop{% else %}morningstar_aop{% endif %}">Løbende omkostninger</a></th>
<th><a href="{% url 'stocks_index' %}?sort={% if request.GET.sort == "nordnet_aop" %}-nordnet_aop{% else %}nordnet_aop{% endif %}">ÅOP</a></th>
<th>Investorinformation</th>
<th>Morningstar</th>
<th>Nordnet</th>
<th>Saxo</th>
</tr>
{% for stock in stocks %}
<tr>
<td>{{ stock.name }}</td>
<td>{{ stock.isin }}</td>
<td>{% if stock.morningstar_aop %}{{ stock.morningstar_aop }}%{% endif %}</td>
<td>{% if stock.nordnet_aop %}{{ stock.nordnet_aop }}%{% endif %}</td>
<td>{% if stock.nordnet_prospect %}<a href="{{ stock.nordnet_prospect }}">Info</a>{% elif stock.morningstar_prospect %}<a href="{{ stock.morningstar_prospect }}">Info</a>{% endif %}</td>
<td>{% if stock.morningstar_url %}<a href="{{ stock.morningstar_url }}">Link</a>{% endif %}</td>
<td>{% if stock.nordnet_url %}<a href="{{ stock.nordnet_url }}">Link</a>{% endif %}</td>
<td>{% if stock.saxo_url %}<a href="{{ stock.saxo_url }}">Link</a>{% endif %}</td>
</tr>
{% endfor %}
</table>
<a name="forbehold"></a>
<h2>Forbehold</h2>
<p>Alt hvad du læser på denne side er løgn og fiktion fra ende til anden og har ingen relation til virkeligheden. Hvis du kunne finde på at læse indholdet, som om det omhandlede værdipapirer, eller at købe, sælge eller tage dig af din personlige hygiejne med værdipapirer på grund af indholdet på denne side, er det fuldstændig et hundrede procent på eget ansvar. Alt hvad der findes på siden er fejlbehæftet, forældet og lavet af en uduelig amatør uden forstand på noget som helst. Du skal regne med, at alle links fører til nogle andre værdipapirer, end man skulle tro, og at de værdipapirer som står til salg et sted sikkert ikke sælges der - og omvendt. Alle oplysninger om løbende omkostninger og ÅOP er fundet ved hjælp af hønebingo og dermed så godt som tilfældige.</p>
{% endspaceless %}{% endblock %}