Salkkujen seuranta: excel-taulukot

Saat helposti toimimaan, kun vaihdat hakemaan yahoosta

YAHOOFINANCE(“NDA-FI.HE”)

7 tykkäystä

Suuret kiitokset @Con4n ! Kaikki lähti toimimaan ja taas saa sheetseissä seurattua salkkua.

Tälle omalle seurannalle ei oikeastaan olisi tarvetta jos kaikki sijoitukset olisi hankittu Nordnetin kautta, täytyy melkein ehdottaa Nordnetille että voisivat lisätä toiminnallisuuden jolla voisi lisätä Nordnetin ulkopuoliset sijoitukset käsin salkkuun ihan pelkästään seurantaa varten…

1 tykkäys

thanks bro

onko yahoossa muuten jotain muita hyötyjä vs googlefinance?

2 tykkäystä

Kiitos tästä!

Muotoilin vielä eurooppa-sheettimuotoon jos joku sattuu tarvitsemaan suoraan… (alla oleva noutaa nordnet suomi-indeksin kurssin)

SUBSTITUTE(INDEX(importxml("https://markets.ft.com/data/funds/tearsheet/summary?s=SE0005993102:EUR";"//li[1]/span[2]");1;1);".";","

Mites tällä hetkellä saatte toimivat haut ETF-rahastoille Google Sheetsiin? Yllä esitetyt Financial Timesin haut eivät tunnu toimivan luotettavasti.

YahooFinancen kautta tuntuu toimivan parhaiten. Ohjeet sen käyttöön löytyy ylempää tästä ketjusta.

3 tykkäystä

Jos ei mikään muu enää toimi niin voi koittaa Nordnettiä. Sieltä ei toki kaikkea löydy. Ainakin Indeksirahastoihin toimii esimerkiksi:

=IMPORTXML(“https://www.nordnet.fi/markkinakatsaus/rahastolistat/16801606-nordnet-indeksirahasto-suomi","(//span[contains(@class,‘StatsBox__StyledPriceText-sc’)])[1]”)

1 tykkäys

Moi!
Tämä koodi toimii oikein hyvin!
Muutama parannusehdotus vielä lisäksi, en tiedä kuka tätä päivittää niin ehdotan nyt sinulle :slight_smile:

Jotkut osakkeet ja ETFt eivät maksa osinkoa, riippuen tyypistä funktio palauttaa nyt joko N/A tai ERROR virheen Googlesheetsille, saisiko tuon harmonisoitua ERROR viestiksi tai mieluummin vaikka negatiivikseksi luvuksi jolloin sen voisi omissa kaavoissa ottaa huomioon?

Yahoolla on paljon myös muuta dataa tarjolla ainkain verkkosivujensa kautta. Onko tässä kaikki, vai saisiko tähän myös pb luvun ja muutamia muita finalukuja?

t. Ville

Titanium lakkasi toimimasta vähän aikaa sitten. Kaava:

=GOOGLEFINANCE(“TITAN”;“price”)

vaikuttaisi palauttavan nykyään jonkin ihan muun osakkeen tiedot. Onko jollain toimiva kaava?

Googlettaessa osakekurssin näkee, millä tunnuksella se löytyy google financesta: HEL:TITAN

1 tykkäys

Kiitoksia! Kokeilin kaikkia välimerkkejä, mutta HEL olikin väärässä paikassa :slight_smile:

Portfolio performance on julkaissut nyt myös applikaation:

Lisää tietoa foorumilla:

6 tykkäystä

Olisko kellään heittää korkoa korolle -kaavaa, jossa lisätään pääomaa ajan saatossa, ratkaistuna ajan suhteen? :smiley: Voisi siis laskea kuinka kauan menee saavuttaa tietty loppupääoma tietyllä alkupääomalla, korolla ja kk-säästöllä.

Löysin täältä peruskaavan loppupääoman suhteen:

En saa sillä kuitenkaan ihan samoja arvoja kuin tällä Networthifyn laskurilla, jolla saa ratkaistuksi suoraan jäljellä olevan ajan. (Eipä ole kaavaa näkyvillä)

Yiritin vielä käsin kääntä yo. kaavan ratkaistuna ajan suhteen ja heitin ko. logaritmiyhtälön taulukkoon, mutta tulee vähän outoja tuloksia.

Seligsonilla ainakin tavoitelaskuri tällasta varten.

Kuten varmasti monella muullakin. Nyt tarvittiin kaavaa.

Voisihan siitä luoda vaikka sadan rivin excel himmelin, jossa jokainen rivi on vuosi lisää korkoa korolle. Muuttujina omissa soluissaan sitten nuo alkupääoma, kk-summa ja korko. Sitten vaan katselee loppusummia, että millä rivillä, eli monenko vuoden päästä, on haluttu summa kasassa.

1 tykkäys

Yahoo Financen HTML on näköjään taas elänyt. Ainakin hintatieto näyttää siirtyneen value -attribuutista data-value -attribuuttiin.

Fiksattu yahoofinance-skripti:

function yahoofinance(symbol, mode="price") {
  symbol = symbol.toUpperCase();
  mode = mode.toLowerCase();

  const content = UrlFetchApp.fetch("https://finance.yahoo.com/quote/" + symbol).getContentText();
  const $ = Cheerio.load(content);

  if (mode === "price") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketPrice"]').attr('data-value')) || 0;
  else if (mode === "name") return $("div#quote-header-info h1").first().text().split("(" + symbol + ")")[0] || "N/A";
  else if (mode === "change") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketChange"]').attr('data-value')) || 0;
  else if (mode === "changepct") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketChangePercent"]').attr('data-value')) || 0;

  var summaryArr = $("div#quote-summary").children().children().children().children().toArray().map((element) => { return $(element).text() });

  if (mode === "high") return Number(summaryArr[4].split(" ")[3].replace(/\,/g, "")) || "N/A";
  else if (mode === "low") return Number(summaryArr[4].split("e")[1].split(" ")[0].replace(/\,/g, "")) || "N/A";
  else if (mode === "high52") return Number(summaryArr[5].split(" ")[4].replace(/\,/g, "")) || "N/A";
  else if (mode === "low52") return Number(summaryArr[5].split("ge")[1].split(" ")[0].replace(/\,/g, "")) || "N/A";
  else if (mode === "open") return Number(summaryArr[1].split("n")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "volume") return Number(summaryArr[6].split("e")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "volumeavg") return Number(summaryArr[7].split("e")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "beta") return Number(summaryArr[9].split(")")[1]) || "N/A";
  else if (mode === "pe") return Number(summaryArr[10].split(")")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "eps") return Number(summaryArr[11].split(")")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "edate") return summaryArr[12].split("Date")[1] || "N/A";
  else if (mode === "divdate") return summaryArr[14].split("Date")[1] || "N/A";
  else if (mode === "target") return Number(summaryArr[15].split("st")[1].replace(/\,/g, "")) || "N/A";
  else if (mode === "div") return Number(summaryArr[13].split("ld")[1].split(" ")[0].replace(/\,/g, "")) || "N/A";
  else if (mode === "yield") return Number(summaryArr[13].split("(")[1].split("%")[0]) || "N/A";
  else throw new Error("Unknown mode");
}

Edit:

Haen itse tuolta vain “pricen”, joten en tiedä onko prosenteissa tapahtunut jotain muutosta. Jos käytössä on Google Sheets:n päässä “prosenttiformatointi” kannattaa yrittää jakamista 100:lla.

Esim.

=yahoofinance("NDA-FI.HE";"changepct")/100
7 tykkäystä

Oli tosiaan joku häiriö ettei näyttänyt hintoja, mutta nyt tuon skriptin korjauksen jälkeen näyttää. Tosin itsellä näyttää päivämuutos %:t aika hurjalta, joten jotain on vielä pielessä.

Hinta näyttäisi pelittävän. Käytän itse tuosta vain divdatea ja se ei itselläni enää toimi. Tällaista pukkaa

image

1 tykkäys

Näköjään muutkin kentät olivat menneet enemmän tai vähemmän uusiksi.

Loppujenkin kenttien osalta päivitetty skripti:

function yahoofinance(symbol, mode="price") {
  symbol = symbol.toUpperCase();
  mode = mode.toLowerCase();

  const content = UrlFetchApp.fetch("https://finance.yahoo.com/quote/" + symbol).getContentText();
  const $ = Cheerio.load(content);

  if (mode === "price") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketPrice"]').attr('data-value')) || 0;
  else if (mode === "name") return $("section.container h1").first().text().split("(" + symbol + ")")[0] || "N/A";
  else if (mode === "change") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketChange"]').attr('data-value')) || 0;
  else if (mode === "changepct") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketChangePercent"]').attr('data-value')) || 0;
  else if (mode === "high") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketDayRange"]').attr('data-value').split(" - ")[1].replace(/\,/g, "")) || 0;
  else if (mode === "low") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketDayRange"]').attr('data-value').split(" - ")[0].replace(/\,/g, "")) || 0;
  else if (mode === "high52") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="fiftyTwoWeekRange"]').attr('data-value').split(" - ")[1].replace(/\,/g, "")) || 0;
  else if (mode === "low52") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="fiftyTwoWeekRange"]').attr('data-value').split(" - ")[0].replace(/\,/g, "")) || 0;
  else if (mode === "open") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketOpen"]').attr('data-value').replace(/\,/g, "")) || 0;
  else if (mode === "volume") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketVolume"]').attr('data-value').replace(/\,/g, "")) || 0;
  else if (mode === "volumeavg") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="averageVolume"]').attr('data-value').replace(/\,/g, "")) || 0;
  else if (mode === "target") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="targetMeanPrice"]').attr('data-value').replace(/\,/g, "")) || 0;
  
  var summaryArr = $("div[data-testid=quote-statistics]").children().children().children().toArray().map((element) => { return $(element).text() });

  if (mode === "beta") return Number(summaryArr[19].replace(/\,/g, "")) || 0;
  else if (mode === "pe") return Number(summaryArr[21].replace(/\,/g, "")) || 0;
  else if (mode === "eps") return Number(summaryArr[23].replace(/\,/g, "")) || 0;
  else if (mode === "edate") return summaryArr[25] || "N/A"; 
  else if (mode === "divdate") return summaryArr[29] || "N/A";
  else if (mode === "div") return Number(summaryArr[27].split(" ")[0].replace(/\,/g, "")) || 0;
  else if (mode === "yield") return Number(summaryArr[27].split("(")[1].split("%")[0].replace(/\,/g, "")) || 0;

  else throw new Error("Unknown mode");
}

Kevyen testin perusteella näyttäisi toimahtelevan:

Edit:

Paha sanoa, itsellä nuo näyttäisi toimivan ok:
test

Tuo skriptihän pitää ottaa käyttöön navigoimalla Google Sheetsissä Extensions > Apps Script (alkuperäinen käyttöönotto-ohje: Salkkujen seuranta: excel-taulukot - #174 käyttäjältä Prophier)

Joskus toki tuntuu että Yahoon päässä jokin tökkii, ja lopputuloksena on erroria. Tällöin yksittäistä kenttää voi yrittää päivittää hakkaamalla yksittäisessä solussa “Delete, Ctrl+Z” tms.

Edit2:

Sinuna tekisin muutoksen (vain kerran) sinne yahoofinance-skriptin puolelle:

...
  else if (mode === "changepct") return Number($('fin-streamer[data-symbol="' + symbol + '"][data-field="regularMarketChangePercent"]').attr('data-value'))/100 || 0;
...
5 tykkäystä