Skip to main content
This page lists the requirements for CSV files used as external data sources, how the files are fetched, and what the error codes mean.

File structure

  • UTF-8 encoding; a leading BOM is tolerated.
  • Comma (,) is the only supported delimiter — no semicolons, tabs or auto-detection.
  • Standard CSV quoting (RFC 4180): a field containing commas, quotes or newlines must be enclosed in double quotes.
  • Both LF and CRLF line endings work; blank lines are ignored.
  • A header row is required. Column order does not matter, unknown extra columns are ignored.

The time column

The time column (default name time, case-insensitive, configurable via sources.Csv(url, time_column=...)) accepts exactly three formats: Notes:
  • Seconds vs milliseconds are distinguished by magnitude: values of 1012 and above are read as milliseconds.
  • A bare date without a time part (2024-01-02) is not accepted.
  • Timezone offsets are normalized to UTC; timestamps without an explicit offset are not accepted.
  • Timestamps must be strictly increasing: duplicates and out-of-order rows are rejected, nothing is sorted or deduplicated for you.
  • The resolved date must fall between years 1900 and 2200.
  • Candle CSVs do not accept sub-second timestamps. Typed-data CSVs have millisecond resolution.

Cell values

Missing values. The only way to express “no value” is an empty (or whitespace-only) cell, and it is only allowed in columns mapped to Optional fields. Literal markers like NA, N/A, null or - are not recognized — they are parse errors in numeric and bool columns. In a candle CSV only the volume cell may be empty (it reads as 0). Validation is all-or-nothing. A single bad cell — an unparseable timestamp, an empty required value, a malformed number — rejects the entire file. Rows are never silently skipped or filled with defaults.

Hosting requirements

  • HTTPS only, with a valid certificate. Plain http:// URLs are rejected.
  • The file must be publicly reachable: no authentication headers can be sent, and URLs with embedded credentials (https://user:pass@...) are rejected. If you need access control, use signed URLs (the query string is part of the URL and is kept out of server logs).
  • Up to 3 redirects are followed; every hop must also be HTTPS.
  • Addresses on private and internal networks are blocked.
  • gzip-compressed responses are supported; all size limits apply to the decompressed data.

Fetching and caching

  • The file is downloaded when the indicator instance is created, with a 30-second fetch timeout. The dataset is a frozen snapshot: it is not refreshed while the indicator runs.
  • Downloads are cached on the server for about 10 minutes. Re-adding an indicator within that window may serve the previous content of the file.
  • Requests to the same URL are throttled; under heavy concurrent use a fetch can fail with external_rate_limited — retry by re-adding the indicator.

Limits

Error reference

When an external source fails, the indicator shows the error code followed by a short explanation, for example external_invalid_number: high 5 is below low 7 (line 12). Errors found while reading the file name the CSV line they come from. The codes are:

Errors when declaring the source

The URL itself is validated when the indicator instance is created, before any download, so these errors appear without the file ever being fetched: