CSV check
Find missing evidence before calculating performance
A result sheet can look polished while hiding duplicate signals, impossible chronology, unresolved trades, omitted losses, missing costs, or source links that were never recorded. This validator checks those structural conditions before a rate or return is interpreted. The distinction matters because arithmetic can be reproducible even when the underlying records are incomplete.
The parser uses the RFC 4180 quote model. Commas and line breaks are accepted inside double-quoted fields, and a double quote inside a quoted field must be doubled. It accepts CRLF, LF, or CR line endings and an optional UTF-8 byte-order mark. It intentionally does not guess semicolon, tab, or pipe delimiters because silent delimiter guessing can shift evidence into the wrong columns.
Comma-delimited UTF-8 CSV with one header row, no more than 256,000 bytes, 2,000 data rows, and 40 columns.
Why the file stays local: the validator runs as JavaScript in this page and contains no fetch, XMLHttpRequest, beacon, WebSocket, form submission, or storage call for CSV content.
Current structural result
The tested structure is complete. Continue with source, execution, denominator, and risk review.
| Severity | Code | Row | Column | Finding | Repair |
|---|---|---|---|---|---|
| No structural issues found by this validator. | |||||
Starter CSV checked locally.
Decision sequence
Build the audit trail before choosing a denominator
A provider result sheet usually fails long before the percentage calculation. The first question is whether the published population can be reconstructed: one stable row per source signal, clear timestamps, explicit non-winning states, costs, and a source reference. Only after that structure is defensible can a reviewer decide which rows belong in a particular metric.
The seven steps below are deliberately ordered. Skipping directly to win rate can turn missing rows into exclusions, unresolved trades into invisible risk, or duplicated updates into extra opportunities. The validator automates narrow checks; the human review still decides whether the records correspond to the actual source history.
Freeze one header schema
Export one header row and keep the same columns for every record. A changing schema can hide missing losses, costs, or sources.
Give each source signal one stable ID
Keep edits and later outcomes attached to the original signal ID. A second row with the same ID is a duplicate, not a new opportunity.
Use UTC chronology
Record publication and close timestamps in UTC. A close cannot precede the source message, and an open row should not carry a closing time.
Separate outcomes from exclusions
Win, loss, and break_even are resolved executed outcomes. Cancelled, no_fill, and open rows remain visible without entering a binary hit-rate denominator.
Keep costs beside gross R
Fees and slippage are explicit nonnegative deductions. Net R must reconcile to gross R minus both costs.
Attach a source and edit state
Every row needs an HTTPS source reference and a visible edit classification. Syntax does not establish authenticity, so the source still needs human review.
Interpret structure before performance
Repair format and completeness first. Only then can a separate evidence review test execution, denominators, risk, and performance claims.
Field reference
Fourteen required columns keep identity, risk, outcome, cost, and source on the same row
The schema is intentionally narrow. It does not try to encode every trading strategy or exchange detail. Instead, it preserves the minimum structure needed to ask whether a published signal had a stable identity, a plausible sequence, a declared direction and stop, a non-cherry-picked outcome state, explicit costs, and a source trail.
Optional columns can carry context, but adding dozens of custom fields does not compensate for a missing signal ID, timestamp, loss, cost, or source. Header names are interpreted after trimming and lowercasing so common export mistakes remain reviewable, but the tool emits a warning because a canonical schema reduces future ambiguity.
| Column | Group | Status | Type | Example | Validation rule |
|---|---|---|---|---|---|
signal_id | Identity and chronology | Required | text | SYN-001 | A nonblank unique identifier from 1 to 80 characters using letters, numbers, dot, underscore, colon, or hyphen. |
posted_at_utc | Identity and chronology | Required | UTC timestamp | 2026-01-10T10:00:00Z | A real ISO 8601 UTC timestamp ending in Z, with optional milliseconds. |
closed_at_utc | Identity and chronology | Required | UTC timestamp or blank | 2026-01-10T18:00:00Z | Required for win, loss, and break_even rows; blank for open rows; never earlier than posted_at_utc. |
instrument | Trade model | Required | text | BTC-USDT | A nonblank market or instrument label. The validator does not decide whether the instrument existed or was tradable. |
direction | Trade model | Required | enum | long | Use long or short in lowercase. |
entry_price | Trade model | Required | positive number | 100 | A finite number greater than zero. A listed price is not evidence of an executable fill. |
stop_price | Trade model | Required | positive number | 95 | A finite number greater than zero and different from entry_price; below entry for long rows and above entry for short rows. |
outcome | Outcome and costs | Required | enum | win | Use one frozen lowercase outcome. Cancelled and no_fill are not wins or losses. Open rows are unresolved. |
gross_r | Outcome and costs | Required | number or blank | 1.2 | Required for win, loss, and break_even rows; positive for win, negative for loss, and zero for break_even. Blank for unresolved or non-executed rows. |
fees_r | Outcome and costs | Required | nonnegative number or blank | 0.03 | Required for resolved executed rows, including an explicit zero. Express fees in R using the same risk unit as gross_r. |
slippage_r | Outcome and costs | Required | nonnegative number or blank | 0.02 | Required for resolved executed rows, including an explicit zero. A modelled value does not prove an actual fill. |
net_r | Outcome and costs | Required | number or blank | 1.15 | Required for resolved executed rows and equal to gross_r minus fees_r minus slippage_r within 0.001 R. |
source_url | Evidence and change history | Required | HTTPS URL | https://example.invalid/evidence/SYN-001 | A nonblank absolute HTTPS reference with a usable host and without embedded credentials, embedded literal ASCII whitespace, control characters, backslash normalization, or malformed percent escapes. The validator checks syntax, not whether the source exists or proves the row. |
edit_status | Evidence and change history | Required | enum | original | Record whether the source was original, edited before or after entry, deleted, or unknown. Unknown is accepted with a visible warning. |
venue | Optional context | Optional | text | Synthetic venue | Optional venue label. Presence does not prove the venue, account, or fill. |
notes | Optional context | Optional | text | Invented fixture row | Optional context. Commas, line breaks, and quotes must use RFC 4180 quoting. |
Outcome model
Unresolved and non-executed rows stay visible without becoming wins or losses
A clean result sheet does not force every published idea into a binary outcome. Open positions have not resolved. Cancelled signals and no-fill calls may matter to the published population even though they do not describe an executed win or loss. Preserving these states makes the denominator decision inspectable instead of silently deleting inconvenient rows.
Resolved rows require a close time plus gross R, fees R, slippage R, and net R. The validator recomputes the row identity net_r = gross_r - fees_r - slippage_r with a tolerance of 0.001 R. That is an arithmetic consistency check, not evidence that the listed execution or cost occurred.
| Outcome | Classification | Gross R rule | Structural requirement |
|---|---|---|---|
| win | Resolved and executed | Positive gross_r | Close time and all R fields required |
| loss | Resolved and executed | Negative gross_r | Close time and all R fields required |
| break_even | Resolved and executed | Zero gross_r | Close time and all R fields required |
| open | Unresolved | No result values | No close time; keep the row visible |
| cancelled | Not a resolved executed result | No result values | Keep it outside win/loss denominators |
| no_fill | Not a resolved executed result | No result values | A published idea without an assumed fill |
Four result states
The output says what the parser found, not what the provider deserves
Structurally reviewable
When: The CSV parses and contains no validator errors or warnings.
Meaning: Required fields and tested row relationships are present and internally consistent.
Structurally reviewable with warnings
When: The CSV parses with no errors and at least one warning.
Meaning: The sheet can be reviewed, but one or more non-blocking ambiguities should stay visible.
Incomplete record set
When: The CSV parses but contains one or more structural errors.
Meaning: Repair the named headers or rows before treating the file as a complete review input.
Malformed CSV
When: The text cannot be parsed safely within the documented CSV limits.
Meaning: Repair quoting, file size, row count, NUL bytes, or other fatal format defects before row validation.
Every state describes machine-tested structure only. No state establishes that a source message is authentic, a trade was executable, an outcome is accurate, a provider is honest, a strategy is profitable, or future performance is likely.
Deterministic fixtures
Five invented sheets prove the clean, incomplete, and malformed paths
Each fixture is recalculated by the generator and checker. The complete fixture includes a quoted comma, a line break inside a quoted note, and a doubled quote. Other fixtures isolate a duplicate ID, impossible chronology, missing loss evidence, and an unclosed quoted field. No row came from a provider, market feed, exchange account, or subscriber.
| Fixture | Purpose | Expected state | Expected issues |
|---|---|---|---|
SHEET-VALIDComplete mixed-outcome sheet | Proves a quoted, complete sheet can reach the clean structural state. | Structurally reviewable | 0 errors; 0 warnings |
SHEET-DUPLICATE-IDDuplicate signal identifier | Proves that updates cannot masquerade as separate signals under one identifier. | Incomplete record set | 1 errors; 0 warnings |
SHEET-INVALID-CHRONOLOGYClose precedes publication | Proves that a parseable timestamp pair still fails chronology. | Incomplete record set | 1 errors; 0 warnings |
SHEET-MISSING-LOSS-EVIDENCELoss row without costs or source column | Proves that a loss cannot be structurally complete when cost and source fields are omitted. | Incomplete record set | 3 errors; 0 warnings |
SHEET-MALFORMED-QUOTEUnclosed quoted field | Proves that malformed quoting stops row interpretation instead of silently shifting columns. | Malformed CSV | 1 errors; 0 warnings |
All rows are invented parser fixtures. They are not provider records, market results, recommendations, or evidence that a trade occurred.
Issue reference
Every issue names the row, field, and next repair
Errors block a structurally reviewable state because they affect parsing, required evidence, chronology, outcome classification, cost arithmetic, or source syntax. Warnings preserve a reviewable state while keeping ambiguity visible. The tool avoids generic failure messages so a reviewer can repair the sheet without guessing which rule was applied.
| Issue code | Severity | Scope | Repair |
|---|---|---|---|
input_too_large | error | file | Reduce the UTF-8 file to 256000 bytes or fewer. |
too_many_rows | error | file | Split the file into review periods of 2000 data rows or fewer. |
too_many_columns | error | file | Reduce the file to 40 columns or fewer and move unrelated fields into a separate evidence file. |
empty_csv | error | file | Paste a CSV with one header row and at least one data row. |
no_data_rows | error | file | Add at least one nonblank data row below the header. |
nul_byte | error | file | Export plain UTF-8 CSV without binary NUL bytes. |
unclosed_quoted_field | error | file | Close the quoted field and double any quote that belongs inside its value. |
unexpected_quote | error | file | Quote the entire field and double internal quote characters. |
unexpected_character_after_quote | error | file | After a closing quote, use a comma, line break, or end of file. |
missing_required_header | error | header | Add the named required header exactly once. |
blank_header | error | header | Name every header column or remove the empty trailing column. |
duplicate_header | error | header | Keep one copy of the named header. |
noncanonical_header | warning | header | Use the lowercase trimmed header shown in the starter CSV. |
unknown_header | warning | header | Keep the column only if it carries useful context; the validator does not interpret it. |
row_width_mismatch | error | row | Make the row contain the same number of fields as the header. |
missing_value | error | cell | Add the named value or change the row outcome when the record is unresolved. |
duplicate_signal_id | error | row | Give each source signal one stable identifier and keep updates under that identifier. |
invalid_signal_id | error | cell | Use 1 to 80 allowed identifier characters. |
invalid_utc_timestamp | error | cell | Use a real UTC timestamp such as 2026-01-10T10:00:00Z. |
close_before_post | error | row | Correct the timestamps so the close is not earlier than the post. |
invalid_enum | error | cell | Use one of the documented lowercase values for this field. |
invalid_number | error | cell | Use a finite base-10 number without a percent or currency symbol. |
invalid_price | error | cell | Use a finite price greater than zero. |
stop_equals_entry | error | row | Record a distinct entry and stop price. |
stop_side_conflict | error | row | Use a stop below entry for long rows or above entry for short rows. |
outcome_sign_conflict | error | row | Make gross_r positive for win, negative for loss, or zero for break_even. |
negative_cost | error | cell | Record fees_r and slippage_r as nonnegative deductions. |
net_r_mismatch | error | row | Set net_r to gross_r minus fees_r minus slippage_r within 0.001 R. |
invalid_source_url | error | cell | Use an absolute HTTPS URL with a usable host, valid percent escapes, and no credentials, embedded literal ASCII whitespace, control characters, or backslashes. |
unknown_edit_status | warning | cell | Inspect the source history and replace unknown when the edit state can be established. |
open_has_close | warning | row | Clear closed_at_utc or change the outcome to the resolved state. |
unresolved_has_result | warning | row | Clear gross_r, fees_r, slippage_r, and net_r until the row is resolved and executed. |
formula_like_text | warning | cell | Remove spreadsheet formula prefixes from text fields before sharing or opening the CSV in spreadsheet software. |
What remains human
A valid CSV can still describe evidence that is false, selected, or impossible to execute
The CFTC's trading-system advisory distinguishes hypothetical results from trading subjected to actual market conditions. It also points to stops that can execute at a different price or not at all, bid-ask spreads, commissions, fees, subscriptions, and the need to ask for independent verification. A CSV schema can keep those questions attached to each row; it cannot answer them by itself.
Source URLs need direct inspection. A reviewer should compare the original publication time, edits, deleted messages, entry conditions, target and stop updates, and the full visible population. Account-level conclusions also require position sizing, leverage, overlapping exposure, deposits and withdrawals, and drawdown. None of those facts can be inferred from a clean header row.
- A valid row can still contain fabricated, altered, cherry-picked, or stale information.
- The validator does not fetch source_url values, inspect Telegram edit history, or authenticate screenshots.
- The validator does not know whether an entry, target, or stop could be filled under real market conditions.
- R-multiple arithmetic does not establish account return, position sizing, leverage, drawdown, or suitability.
- The tool does not calculate a provider rating, win rate, profitability score, recommendation, or verified status.
- Passing the schema is a prerequisite for review, not a substitute for independent evidence.
Method and provenance
The validator is source-backed, reproducible, and bounded against overclaiming
The existing canonical was selected because a first-party Search Console export recorded 49 impressions, 0 clicks, and average position 6.67 during its historical window. The query signal result
recorded 2 impressions at average position 8. These observations explain the upgrade choice. They do not establish current rank, indexing, traffic, future search visibility, or AI citation.
The source ledger freezes the schema, parser limits, issue taxonomy, fixtures, official-source observations, and output list. The generator recalculates every fixture before writing the page. The checker independently runs the generated browser core against the same fixtures and adversarial CSV cases. When released from an immutable commit, the manifest binds the source, generator, checker, page, starter CSV, summary, sitemap, LLMS companion, and auxiliary WordPress plugin to exact SHA-256 hashes.
| Publisher | Accessed | Capture | Boundary used here |
|---|---|---|---|
| Google Search Central Optimizing your website for generative AI features on Google Search | 2026-07-13 | 88a9c15e137427d3...191,867 bytes |
|
| Google Search Central Spam Policies for Google Web Search | 2026-07-13 | ec4cbb9e1f19419c...198,340 bytes |
|
| RFC Editor Common Format and MIME Type for Comma-Separated Values Files | 2026-07-13 | 5d9ec035aa40c010...12,931 bytes |
|
| U.S. Commodity Futures Trading Commission Fraud Advisory: Commodity Trading Systems Sold on the Internet | 2026-07-13 | 19240975884d4371...44,430 bytes |
|
| OpenAI Publishers and Developers - FAQ | 2026-07-13 | The official page was readable through browser extraction, but its CDN rejected the separate command-line capture with HTTP 403. No capture hash is claimed. |
|
Reuse boundary: the schema, issue definitions, and synthetic starter may be reused with attribution to CryptoSignalsReview and this canonical. Keep the structural-only conclusion, synthetic-data label, source limitations, and research date attached. Do not relabel a passing fixture or a passing user file as verified provider performance.
Immutable source ledger Dataset ID csr-crypto-signal-result-sheet-schema-validator-2026-07-13 Source commit fae3ede6ec3a7613924491b9626f7f1c7584301a
Questions
Common result-sheet schema questions
Does a structurally reviewable sheet count as verified performance?
No. It means the required fields and tested relationships are present. Source authenticity, execution, completeness, and provider claims still require separate evidence review.
Does the CSV leave my browser?
No. The page uses browser JavaScript to parse the text in the current tab. It makes no upload, storage, analytics payload, or validation API request with the CSV.
Why are fees and slippage required even when they are zero?
An explicit zero distinguishes a considered cost field from a missing field. The CFTC warns that spreads, execution, commissions, and fees can change reported performance.
Why keep cancelled, open, and no-fill signals?
They preserve the published population and exclusion trail. Hiding non-winning records can make a selected denominator look cleaner than the source history.
Can the validator read semicolon-delimited or spreadsheet files?
No. Export comma-delimited UTF-8 CSV. The parser accepts standard quoting, CRLF or LF line endings, a UTF-8 BOM, commas inside quoted fields, line breaks inside quoted fields, and doubled internal quotes.
What should happen after the CSV passes?
Preserve the file and its source archive, inspect source URLs and edit history, define the denominator, test execution assumptions, and keep every limitation beside any reported metric.
Continue the review