Scalable Capital Depot Export

Userscript, das den Download des aktuellen Depots bei Scalable Capital als CSV-Datei erlaubt.

  1. // ==UserScript==
  2. // @name Scalable Capital Depot Export
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Userscript, das den Download des aktuellen Depots bei Scalable Capital als CSV-Datei erlaubt.
  6. // @author https://github.com/lime-scripts
  7. // @license MIT
  8. // @match https://de.scalable.capital/**
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=scalable.capital
  10. // @grant GM_registerMenuCommand
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16.  
  17. GM_registerMenuCommand("Export Depot CSV", function () {
  18. const positions = findPositions();
  19. const csv = toCsv(positions);
  20. downloadCsv(csv, "ScalableNeu_depot_export_" + (new Date().toISOString().split(".")[0]) + ".csv");
  21. });
  22.  
  23.  
  24. function isObject(obj) {
  25. return typeof obj === 'object' && obj !== null;
  26. }
  27.  
  28.  
  29. function findPositions() {
  30.  
  31. let resultsMap = {};
  32.  
  33. function visit(node) {
  34. if (!node) {
  35. return;
  36. }
  37. else if (Array.isArray(node)) {
  38. for (const subNode of node) {
  39. visit(subNode);
  40. }
  41. }
  42. else if (isObject(node)) {
  43. if (node["isin"] && node["inventory"]) {
  44. resultsMap[node["isin"]] = { ...node };
  45. }
  46. else {
  47. for (const key of Object.keys(node)) {
  48. if (["children", "props", "security", "items"].includes(key) || key.startsWith("__reactProps")) {
  49. visit(node[key]);
  50. }
  51. }
  52. }
  53. }
  54. if (node.childNodes) {
  55. node.childNodes.forEach(n => { visit(n); });
  56. }
  57. }
  58.  
  59. visit(document.body);
  60. const positions = Array.from(Object.values(resultsMap)).map(pos => ({ isin: pos.isin, name: pos.name, amount: pos.inventory.position?.filled, price: pos.inventory.position?.fifoPrice, data: pos }));
  61. positions.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
  62. console.log(positions);
  63. console.log(positions.length, "Positionen");
  64. return positions;
  65. }
  66.  
  67.  
  68. function toCsv(rows) {
  69. const SEP = ";";
  70. const LINE_SEP = "\n";
  71. const csvRows = [];
  72. for (let i = -1; i < rows.length; i++) {
  73. const row = rows[i];
  74. const csvRow = Array(4).fill("");
  75. csvRow[0] = i >= 0 ? row.name : "Name";
  76. csvRow[1] = i >= 0 ? row.isin : "ISIN";
  77. csvRow[2] = i >= 0 ? "" + row.amount : "Anzahl";
  78. csvRow[3] = i >= 0 ? "" + row.price : "Preis";
  79. csvRows.push(csvRow);
  80. }
  81. const csv = csvRows.map(row => row.map(val => val.replaceAll(SEP, "")).join(SEP)).join(LINE_SEP);
  82. return csv;
  83. }
  84.  
  85.  
  86. function toCsvBaader(rows) {
  87. const SEP = ";";
  88. const LINE_SEP = "\n";
  89. const COL_COUNT = 63;
  90. const HEADER = "XXX-LFDNR;XXX-SNR;XXX-PFNR;XXX-DENR;XXX-DENR-EXT;XXX-DEPSPERR;XXX-WPBEZK;XXX-WPBEZ1;XXX-WPBEZ2;XXX-WPBEZ3;XXX-WPBEZ4;XXX-WPNR;XXX-WPNRID-D;XXX-WPNRID-DBOE;XXX-KONTNR;XXX-KONTRAKT;XXX-DATFAELL;XXX-STRIKE;XXX-KZCP;XXX-SERIE;XXX-NOTIER;XXX-WHG;XXX-NW-M;XXX-NWSP-M;XXX-EINKURS-M;XXX-AKTKURS-M;XXX-AKTKURSD-M;XXX-KW-M;XXX-KWB-M;XXX-ABGR-M;XXX-ABGRB-M;XXX-FAKTORI;XXX-FAKTORP;XXX-EINKURSB-M;XXX-KONTBEZ;XXX-DEPOTLANG;XXX-NAME1;XXX-NAME2;XXX-MONJAHR;XXX-KURSB;XXX-KFAKTOR;XXX-BEWMET;XXX-PRAENOT;XXX-TUVIP;XXX-WPENDF;XXX-PFBEZ1;XXX-PFBEZ2;XXX-UNDERLYING;XXX-DATUM;XXX-VVSNR;XXX-WPART;XXX-UNDERU;XXX-BLOOMBERGK;XXX-VERFALLSTAG;XXX-VERSIONSNUMM;XXX-AUSUEBUNG;XXX-NWJUR-M;XXX-UTIPOS;XXX-KURSEIND-M;XXX-KWEEUR-M;XXX-KWBEL;XXX-KWBELB";
  91. const csvRows = [];
  92. let rowCounter = 0;
  93. for (const row of rows) {
  94. rowCounter++;
  95. const csvRow = Array(COL_COUNT).fill("");
  96. csvRow[0] = "" + rowCounter;
  97. csvRow[7] = row.name;
  98. csvRow[11] = row.isin;
  99. csvRow[22] = ("" + row.amount).replaceAll(".", ",");
  100. csvRow[24] = ("" + row.price).replaceAll(".", ",");
  101. csvRows.push(csvRow);
  102. }
  103. const csv = HEADER + LINE_SEP + csvRows.map(row => row.map(val => val.replaceAll(SEP, "")).join(SEP)).join(LINE_SEP);
  104. return csv;
  105. }
  106.  
  107.  
  108. function downloadCsv(csv, filename) {
  109. const data = "data:text/csv;charset=utf-8," + csv;
  110. const link = document.createElement("a");
  111. link.setAttribute("href", encodeURI(data));
  112. link.setAttribute("download", filename);
  113. document.body.appendChild(link);
  114. link.click();
  115. }
  116.  
  117. })();