Skip to content

Instantly share code, notes, and snippets.

@vitouXY
Last active February 3, 2024 19:29
Show Gist options
  • Save vitouXY/a246135dbf61583782919e1ae31a4210 to your computer and use it in GitHub Desktop.
Save vitouXY/a246135dbf61583782919e1ae31a4210 to your computer and use it in GitHub Desktop.
Dividendos | Bolsa de Santiago | BCS | JavaScript | JS

gDiv

!!!warning Este código está diseñado exclusivamente para el sitio de la Bolsa de Santiago. !!!note Este código JavaScript recopila y suma los dividendos registrados por año, mostrando un porcentaje basado en el precio ingresado por el usuario. !!!danger Asegúrate de utilizar un Navegador Web que admita la ejecución de códigos JavaScript.

Código

javascript: async function getD(symbol) {
    const d = new Date();
    const injector = angular.element(document.body).injector();

    try {
        const [stock, dividends] = await Promise.all([
            getStockData(symbol, injector),
            getDividendsData(symbol, d, injector),
        ]);

        const precio = prompt('Ingrese Precio:', stock.PRECIO_CIERRE) || stock.PRECIO_CIERRE;
        const dividendsByYear = processDividends(dividends);

        updateDOM(stock, precio, d, dividendsByYear);
    } catch (error) {
        console.error('Error:', error);
    }
}

function getStockData(symbol, injector) {
    return new Promise(resolve => {
        injector.get('RV_Instrumentos')['getResumenInstrumento']({ nemo: symbol }, data => resolve(data.listaResult[0]));
    });
}

function getDividendsData(symbol, d, injector) {
    return new Promise(resolve => {
        injector.get('RV_ResumenMercado')['getDividendos']({
            fec_pagoini: `${d.getFullYear()}-01-01`,
            fec_pagofin: `${d.getFullYear()}-12-31`,
            nemo: symbol,
        }, data => resolve(data.listaResult));
    });
}

function processDividends(dividends) {
    const wordFind = 'DIVID';
    const dividendsByYear = {};

    dividends.forEach(dividendo => {
        const { fec_pago, val_acc, descrip_vc } = dividendo;

        if (fec_pago && descrip_vc.includes(wordFind)) {
            const year = fec_pago.split('-')[0];
            dividendsByYear[year] = (dividendsByYear[year] || 0) + val_acc;
        }
    });

    return dividendsByYear;
}

function updateDOM(stock, precio, d, dividendsByYear) {
    const result = [];
    result.push(`${stock.NEMO_SASA}\n${stock.RAZON_SOCIAL}\nPrecio Actual: \$${stock.PRECIO_CIERRE}\nFecha Hoy: ${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}\n\nPrecio: \$${precio}\n`);
    result.push(`-\tDIVID\t-\n`);

    Object.entries(dividendsByYear).sort().forEach(([year, total]) => {
        const moneda = '$';
        const percentage = (total / precio * 100).toFixed(1);
        result.push(`${year} - ${moneda}${total} (${percentage}%).\n`);
    });

    result.push(`-\t-\t-\n\n`);

    document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";
    document.body.textContent = result.join('');
}

const pathnameSplit = window.location.pathname.split("/");
if (window.location.hostname === "www.bolsadesantiago.com" && (pathnameSplit[1] === "dividendos" || pathnameSplit[1] === "resumen_instrumento") && pathnameSplit[2]) {
    const NEMOX = pathnameSplit[2];
    alert(`[${NEMOX}] Dividendos % Precio`);
    getD(NEMOX);
} else {
    alert('wrongSite!');
};;
void 0

Antes de Ejecutar el Código

Este código trabaja únicamente en el sitio de la Bolsa de Santiago. Específicamente con las URL:

  • https://www.bolsadesantiago.com/resumen_instrumento/{NEMO}
  • https://www.bolsadesantiago.com/dividendos/{NEMO}

Por ejemplo, para el instrumento CFMDIVO, accede a la URL: https://www.bolsadesantiago.com/resumen_instrumento/CFMDIVO Luego, sin cambiar de pestaña, ejecuta el código.

Alternativas de Ejecución del Código

  1. Añadir a Favoritos/Marcadores:
  • Crear un nuevo Favorito/Marcador en tu Navegador Web.
  • En el campo del Nombre, escribe lo que desees.
  • En el campo de la URL, pega el código.
  1. Ejecución directa en la Barra de Direcciones:
  • Copia el código sin la primera letra, la j.
  • Antes o después de pegarlo en la Barra de Direcciones, escribe la j faltante. Esto es debido a la seguridad de los Navegadores Web que impide la ejecución directa de códigos potencialmente peligrosos.
  1. Utilizar una Extensión o Add-on:
  • Instalar en el Navegador Web una Extensión o Add-on que ejecute códigos Javascript.
  • Copia y pega el código sin el texto javascript: al inicio.




Extra:

javascript: const { hostname, pathname } = window.location;
const pathnameSplit = pathname.split("/");

if (hostname === "www.bolsadesantiago.com" && ["dividendos", "resumen_instrumento"].includes(pathnameSplit[1]) && pathnameSplit[2]) {
    (async () => {
        const currentDate = new Date();
        const dataStr = JSON.stringify(await new Promise(resolve => angular.element(document.body).injector().get('RV_ResumenMercado')['getDividendos']({
            fec_pagoini: `${currentDate.getFullYear()}-01-01`,
            fec_pagofin: `${currentDate.getFullYear()}-12-31`,
            nemo: pathnameSplit[2],
        }, resolve))).replace('listaResult', pathnameSplit[2]);

        document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";
        document.body.textContent = `${dataStr}`;

        const element = document.createElement('a');
        element.href = `data:text/json;charset=utf-8,${encodeURIComponent(dataStr)}`;
        element.download = `getDividendos_${pathnameSplit[2]}.json`;
        element.style.display = 'none';
        document.body.appendChild(element);
        element.click();
        document.body.removeChild(element);
    })();
} else {
    alert('wrongSite!');
};;
void 0
/* curl --url 'https://www.bolsadesantiago.com/api/RV_ResumenMercado/getDividendos' -H 'content-type: application/json;charset=UTF-8' --data-binary '{"fec_pagoini":"2023-01-01","fec_pagofin":"2023-12-31","nemo":""}' */
javascript:const hostname = window.location.hostname;if (hostname === "www.bolsadesantiago.com") {async function downloadJSON(pathAPI, getAPI, symbol) {const d = new Date();const fec_ini = `${d.getFullYear()}-01-01`;const fec_fin = `${d.getFullYear()}-12-31`;const rvInstrum = angular.element(document.body).injector().get(pathAPI);const jsonData = await new Promise(resolve => {rvInstrum[getAPI]({fec_pagoini: fec_ini,fec_pagofin: fec_fin,nemo: symbol,}, data => resolve(data));});const dataStr = JSON.stringify(jsonData);document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";document.body.textContent = `${symbol} \t${fec_ini}..${fec_fin}\n${dataStr}`;const element = document.createElement('a');element.setAttribute('href', `data:text/json;charset=utf-8,${encodeURIComponent(dataStr)}`);element.setAttribute('download', `${getAPI}_${symbol}_${fec_ini}_${fec_fin}.json`);element.style.display = 'none';document.body.appendChild(element);element.click();document.body.removeChild(element);}const pathnameSplit = window.location.pathname.split("/");if (pathnameSplit[1] === "dividendos" || pathnameSplit[1] === "resumen_instrumento") {if (pathnameSplit[2]) {const NEMO = pathnameSplit[2];alert(`getDividendos(${NEMO})`);downloadJSON('RV_ResumenMercado', 'getDividendos', NEMO);} else {alert(`getDividendos`);downloadJSON('RV_ResumenMercado', 'getDividendos', '');}} else {alert(`getDividendos`);downloadJSON('RV_ResumenMercado', 'getDividendos', '');}} else {alert('wrongSite!');};;void 0
javascript:async function dJSON(pathAPI1, getAPI1, pathAPI2, getAPI2, symbol) {document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";document.body.textContent = `[${symbol}] \tObteniendo datos!`;const rvInstrum1 = angular.element(document.body).injector().get(pathAPI1);const rvInstrum2 = angular.element(document.body).injector().get(pathAPI2);const d = new Date();const jsonData1 = await new Promise(resolve => {rvInstrum1[getAPI1]({fec_pagoini: `${d.getFullYear()}-01-01`,fec_pagofin: `${d.getFullYear()}-12-31`,nemo: symbol,}, data => resolve(data));});const jsonData2 = await new Promise(resolve => {rvInstrum2[getAPI2]({nemo: symbol,}, data => resolve(data));});const stock = jsonData2.listaResult[0];var stock_PRECIO_CIERRE = prompt("Precio:",`${stock.PRECIO_CIERRE}`);const dividendsByYear = {};jsonData1.listaResult.forEach(dividendo => {const fec_pago = dividendo.fec_pago;if (fec_pago) {const year = fec_pago.split('-')[0];const val_acc = dividendo.val_acc;const moneda = '$';if (dividendsByYear[year]) {dividendsByYear[year].total += val_acc;dividendsByYear[year].moneda = moneda;} else {dividendsByYear[year] = { total: val_acc, moneda: moneda };}}});document.body.textContent = `[${symbol}] \t\$${stock_PRECIO_CIERRE} ($${stock.PRECIO_CIERRE})\n\n`;Object.entries(dividendsByYear).sort().forEach(([year, data]) => {const total = data.total;const moneda = data.moneda;const percentage = (total / stock_PRECIO_CIERRE * 100).toFixed(1);document.body.textContent += `${year}: ${moneda}${total} (${percentage}%)\n`;});document.body.textContent += `\n\n\n* Porcentajes obtenidos con mismo Precio!`}const hostname = window.location.hostname;const pathnameSplit = window.location.pathname.split("/");if (pathnameSplit[2] && hostname === "www.bolsadesantiago.com" && pathnameSplit[1] === "dividendos" || pathnameSplit[1] === "resumen_instrumento") {const NEMO = pathnameSplit[2];alert(`[${NEMO}] - Dividendos % Valor Actual`);dJSON('RV_ResumenMercado', 'getDividendos', 'RV_Instrumentos', 'getResumenInstrumento', NEMO);} else {alert('wrongSite!');};;void 0
javascript:async function gJSON(symbol) {body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";body.textContent = `Obteniendo datos!... [${symbol}]\n\n`;const injector = angular.element(body).injector();const jData1 = await new Promise(resolve => {injector.get('RV_Instrumentos')['getResumenInstrumento']({nemo: symbol,}, data => resolve(data));});const stock = jData1.listaResult[0];if (stock.PRECIO_CIERRE) {var stock_PRECIO_CIERRE = prompt('Precio Cierre:',stock.PRECIO_CIERRE);const d = new Date();jData2 = await new Promise(resolve => {injector.get('RV_ResumenMercado')['getDividendos']({fec_pagoini: `${d.getFullYear()}-01-01`,fec_pagofin: `${d.getFullYear()}-12-31`,nemo: symbol,}, data => resolve(data));});const dividendsByYear = {};jData2.listaResult.forEach(dividendo => {const fec_pago = dividendo.fec_pago;if (fec_pago) {const year = fec_pago.split('-')[0];const val_acc = dividendo.val_acc;const moneda = '$';const descrip_vc = dividendo.descrip_vc;if (descrip_vc.includes('DIVIDENDO')) {if (dividendsByYear[year]) {dividendsByYear[year].total += val_acc;dividendsByYear[year].moneda = moneda;dividendsByYear[year].reparto += 0;dividendsByYear[year].emis += '';dividendsByYear[year].canje += '';} else {dividendsByYear[year] = {total: val_acc,moneda: moneda,reparto: 0,emis: '',canje: ''};}} else if (descrip_vc.includes('REPARTO')) {if (dividendsByYear[year]) {dividendsByYear[year].total += 0;dividendsByYear[year].moneda = moneda;dividendsByYear[year].reparto += val_acc;dividendsByYear[year].emis += '';dividendsByYear[year].canje += '';} else {dividendsByYear[year] = {total: 0,moneda: moneda,reparto: val_acc,emis: '',canje: ''};}} else if (descrip_vc.includes('EMIS')) {if (dividendsByYear[year]) {dividendsByYear[year].total += 0;dividendsByYear[year].moneda = moneda;dividendsByYear[year].reparto += 0;dividendsByYear[year].emis += 'E';dividendsByYear[year].canje += '';} else {dividendsByYear[year] = {total: 0,moneda: moneda,reparto: 0,emis: 'E',canje: ''};}} else if (descrip_vc.includes('CANJE')) {if (dividendsByYear[year]) {dividendsByYear[year].total += 0;dividendsByYear[year].moneda = moneda;dividendsByYear[year].reparto += 0;dividendsByYear[year].emis += '';dividendsByYear[year].canje += 'C';} else {dividendsByYear[year] = {total: 0,moneda: moneda,reparto: 0,emis: '',canje: 'C'};}}}});body.textContent += `${stock.RAZON_SOCIAL}\n\t\$${stock_PRECIO_CIERRE} (\$${stock.PRECIO_CIERRE})\n\n`;body.textContent += `-\t-\t-\n`;Object.entries(dividendsByYear).sort().forEach(([year, data]) => {const total = data.total;const moneda = data.moneda;const reparto = data.reparto;const emis = data.emis;const canje = data.canje;const percentage = (total / stock_PRECIO_CIERRE * 100).toFixed(1);const percentage_r = (reparto / stock_PRECIO_CIERRE * 100).toFixed(1);body.textContent += `${year} - D:${moneda}${total} (${percentage}%), R:${moneda}${reparto} (${percentage_r}%), ${emis},${canje}\n`;});body.textContent += `-\t-\t-\n\n`;}}const body = document.body;const pathnameSplit = window.location.pathname.split("/");if (window.location.hostname=== "www.bolsadesantiago.com") {if (pathnameSplit[1] === "dividendos" || pathnameSplit[1] === "resumen_instrumento") {if (pathnameSplit[2]) {const NEMOX = pathnameSplit[2];alert(`[${NEMOX}] Dividendos % Valor Actual`);gJSON(NEMOX);}}} else {alert('wrongSite!');};; void 0

Accede a la URL desde un Navegador Web, y una vez cargue el sitio, ejecuta el Script desde la barra de direcciónes (Reemplazando la URL).

Inyección de JavaScript en:

  • https://www.bolsadesantiago.com/resumen_instrumento/{NEMO}
  • https://www.bolsadesantiago.com/dividendos/{NEMO}

Script A (CSV):

javascript:const NEMO = window.location.pathname.split("/").pop();async function downloadCSV(nemo) {const rvInstrum = angular.element(document.body).injector().get('RV_ResumenMercado');const listaResult = await new Promise(resolve => {rvInstrum.getDividendos({ nemo }, data => resolve(data.listaResult));});const dataStr = listaResult.map(result => `${result.nemo},${result.fec_pago},${result.val_acc}`).join('\n');const dataLine = `Nemo,Date,Dividend\n${dataStr}\r\n`;document.body.innerText = `${dataLine}\n`;document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";const element = document.createElement('a');element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(dataLine));element.setAttribute('download', `${nemo}.csv`);element.style.display = 'none';document.body.appendChild(element);element.click();document.body.removeChild(element);}alert(`Nemo: [${NEMO}]`);downloadCSV(NEMO);;void 0

Script B (JSON):

javascript:const NEMO = window.location.pathname.split("/").pop();async function downloadJSON(pathAPI, getAPI, nemo) {const rvInstrum = angular.element(document.body).injector().get(pathAPI);const jsonData = await new Promise(resolve => {rvInstrum[getAPI]({ nemo }, data => resolve(data));});const dataStr = JSON.stringify(jsonData);document.body.innerText = `${jsonData.listaResult[0].nemo}:\n${dataStr}\n`;document.body.style.cssText = "white-space: pre-wrap; margin: 20px; font-size: 16px";const dataLine = `data:text/json;charset=utf-8,${encodeURIComponent(dataStr)}`;const element = document.createElement('a');element.setAttribute('href', dataLine);element.setAttribute('download', `${getAPI}-${nemo}.json`);element.style.display = 'none';document.body.appendChild(element);element.click();document.body.removeChild(element);}alert(`Nemo: [${NEMO}]`);downloadJSON('RV_ResumenMercado','getDividendos',NEMO);;void 0

Referencia: "AutoControl config - BCS Puntas.dat" @Get Free #ChileBolsa.com


  • https://www.bolsadesantiago.com/api/RV_ResumenMercado/getDividendos
{"listaResult":[{"descrip_vc":"DIVIDENDO PROV $ 123","fec_lim":"2023-03-23","fec_pago":"2023-03-28","moneda":"$","nemo":"XXXXXXX","num_acc_ant":0,"num_acc_der":10000000,"num_acc_nue":0,"pre_ant_vc":0,"pre_ex_vc":0,"val_acc":123},{...},{...}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment