AutomationFlowsWeb Scraping › Track ETF & Stock Prices with Baserow

Track ETF & Stock Prices with Baserow

Original n8n title: Track Investments Using Baserow and N8n

ByTom @mutedjam on n8n.io

This workflow uses a number of technologies to track the value of ETFs, stocks and other exchange-traded products: Baserow: To keep track of our investments n8n’s Cron node: To trigger the workflow compiling our daily morning briefing Webscraping: The HTTP Request & HTML Extract…

Event trigger★★★★☆ complexity9 nodesBaserowHTTP RequestHtml ExtractSendGrid
Web Scraping Trigger: Event Nodes: 9 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #1785 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "70a44436-4b51-458a-ae93-60edeed170de",
      "name": "On clicking 'execute'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        240,
        300
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d4c2dfa2-30bb-4f06-96c2-5811472302d2",
      "name": "Cron",
      "type": "n8n-nodes-base.cron",
      "position": [
        240,
        100
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "mode": "custom",
              "cronExpression": "15 7 * * 1-6"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "86924546-e4f2-4795-8e80-9e49626d2c42",
      "name": "Baserow",
      "type": "n8n-nodes-base.baserow",
      "position": [
        460,
        200
      ],
      "parameters": {
        "tableId": 680,
        "databaseId": 146,
        "additionalOptions": {}
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "36f2947b-67cf-47eb-891f-e7e3b5ba9eac",
      "name": "Fetch tradegate stock page",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        680,
        200
      ],
      "parameters": {
        "url": "https://www.tradegate.de/orderbuch.php",
        "options": {},
        "responseFormat": "string",
        "queryParametersUi": {
          "parameter": [
            {
              "name": "isin",
              "value": "={{$json[\"ISIN\"]}}"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b516e751-d1d1-43a0-8f19-6787a5c56ddc",
      "name": "Parse tradegate stock page",
      "type": "n8n-nodes-base.htmlExtract",
      "position": [
        900,
        200
      ],
      "parameters": {
        "options": {},
        "extractionValues": {
          "values": [
            {
              "key": "WKN",
              "cssSelector": "#col1_content > table > tbody > tr:nth-child(2) > td:nth-child(1)"
            },
            {
              "key": "ISIN",
              "cssSelector": "#col1_content > table > tbody > tr:nth-child(2) > td:nth-child(3)"
            },
            {
              "key": "Currency",
              "cssSelector": "#col1_content > table > tbody > tr:nth-child(2) > td:nth-child(4)"
            },
            {
              "key": "Name",
              "cssSelector": "#col1_content > h2"
            },
            {
              "key": "Bid",
              "cssSelector": "#bid"
            },
            {
              "key": "Ask",
              "cssSelector": "#ask"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e51556c7-3f3a-4e4d-96e9-942f436422af",
      "name": "Build HTML",
      "type": "n8n-nodes-base.function",
      "position": [
        1560,
        200
      ],
      "parameters": {
        "functionCode": "const columns = Object.keys(items[0].json);\n\n// Define the basic table structure\nlet table_header = `<table style=\"border: 1px solid black; border-collapse: collapse;\"><tr>${columns.map(e => '<th style=\"border: 1px solid black; border-collapse: collapse;\">' + e + '</th>').join('')}</tr>`;\nlet table_content = \"\";\nlet table_footer = '</table>';\n\n// Add content to our table\nfor (item of items) {\n    table_content += '<tr>'\n    for (column of columns) {\n        table_content += `<td style=\\\"border: 1px solid black; border-collapse: collapse;\\\">${item.json[column]}</td>`\n    }\n    table_content += '</tr>'\n}\n\n// Prepare HTML email body\nconst email_html = `<body style=\"font-family: Sans-Serif;\">\n<p>Investments as of ${$now.setZone(\"Europe/Dublin\").setLocale('ie').toFormat('fff')}:</p>\n${table_header}\n${table_content}\n${table_footer}\n<p>Total: ${items.map(e => parseFloat(e.json['Current Value'])).reduce((a, b) => a + b, 0).toFixed(2)}</p>\n<p><small>Workflow #${$workflow.id}</small></p>\n</body>`\n\n\nreturn [{\n    json: {\n        html: email_html\n    }\n}];"
      },
      "typeVersion": 1
    },
    {
      "id": "361bf8f2-298c-4b96-9f21-4f4620f1e9a9",
      "name": "Format result",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        200
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "Name",
              "value": "={{ $node[\"Baserow\"].json[\"Name\"] }}"
            },
            {
              "name": "ISIN",
              "value": "={{ $node[\"Baserow\"].json[\"ISIN\"] }}"
            },
            {
              "name": "Count",
              "value": "={{ $node[\"Baserow\"].json[\"Count\"] }}"
            },
            {
              "name": "Purchase Price",
              "value": "={{ $node[\"Baserow\"].json[\"Purchase Price\"] }}"
            },
            {
              "name": "Current Value",
              "value": "={{ (parseFloat($json[\"Bid\"].replace(',', '.')) * parseFloat($node[\"Baserow\"].json[\"Count\"])).toFixed(2) }}"
            }
          ]
        },
        "options": {},
        "keepOnlySet": true
      },
      "typeVersion": 1
    },
    {
      "id": "c2f329dc-3b97-402a-9d63-ed863c2aee84",
      "name": "Calculate change",
      "type": "n8n-nodes-base.set",
      "position": [
        1340,
        200
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "Change",
              "value": "={{ ( parseFloat($json[\"Current Value\"]) - parseFloat($json[\"Purchase Price\"]) ).toFixed(2) }}"
            },
            {
              "name": "Change (%)",
              "value": "={{ ( ( ( parseFloat($json[\"Current Value\"]) - parseFloat($json[\"Purchase Price\"]) ) / parseFloat($json[\"Purchase Price\"]) ) * 100).toFixed(2) }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "e0876374-c9f3-4253-8764-9aa78faa2193",
      "name": "SendGrid",
      "type": "n8n-nodes-base.sendGrid",
      "position": [
        1780,
        200
      ],
      "parameters": {
        "subject": "Investment report",
        "toEmail": "user@example.com",
        "resource": "mail",
        "fromEmail": "user@example.com",
        "contentType": "text/html",
        "contentValue": "={{ $json[\"html\"] }}",
        "additionalFields": {}
      },
      "credentials": {
        "sendGridApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Cron": {
      "main": [
        [
          {
            "node": "Baserow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baserow": {
      "main": [
        [
          {
            "node": "Fetch tradegate stock page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build HTML": {
      "main": [
        [
          {
            "node": "SendGrid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format result": {
      "main": [
        [
          {
            "node": "Calculate change",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate change": {
      "main": [
        [
          {
            "node": "Build HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On clicking 'execute'": {
      "main": [
        [
          {
            "node": "Baserow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch tradegate stock page": {
      "main": [
        [
          {
            "node": "Parse tradegate stock page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse tradegate stock page": {
      "main": [
        [
          {
            "node": "Format result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow uses a number of technologies to track the value of ETFs, stocks and other exchange-traded products: Baserow: To keep track of our investments n8n’s Cron node: To trigger the workflow compiling our daily morning briefing Webscraping: The HTTP Request & HTML Extract…

Source: https://n8n.io/workflows/1785/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

Manual Baserow. Uses manualTrigger, baserow, httpRequest, htmlExtract. Event-driven trigger; 9 nodes.

Baserow, HTTP Request, Html Extract +1
Web Scraping

extract_swifts. Uses manualTrigger, httpRequest, htmlExtract, splitInBatches. Event-driven trigger; 23 nodes.

HTTP Request, Html Extract, MongoDB +5
Web Scraping

Anyone who wants to improve the SEO of their website Umami users who want insights on how to improve their site SEO managers who need to generate reports weekly

HTTP Request, Baserow
Web Scraping

Pulling Data From Services That N8N Doesnt Have A Pre Built Integration For. Uses manualTrigger, stickyNote, itemLists, htmlExtract. Event-driven trigger; 14 nodes.

Item Lists, Html Extract, HTTP Request
Web Scraping

Workflow 1748. Uses itemLists, htmlExtract, httpRequest. Event-driven trigger; 14 nodes.

Item Lists, Html Extract, HTTP Request