An open API service indexing awesome lists of open source software.

https://github.com/mario-so/ohlcv

OHLCV library in zig
https://github.com/mario-so/ohlcv

Last synced: 28 days ago
JSON representation

OHLCV library in zig

Awesome Lists containing this project

README

        

# πŸ“Š OHLCV Zig Library

A modern Zig library for fetching and parsing Open-High-Low-Close-Volume (OHLCV) financial data from remote CSV filesβ€”no API keys or registration required.

---

## ✨ Features

- **Fetch remote OHLCV data** for BTC, S&P 500, ETH, and Gold (from GitHub)
- **Fast, robust CSV parsing** (handles headers, skips invalid/zero rows)
- **Simple, ergonomic API** (single import, clear types)
- **Technical Indicators**: Includes implementations for SMA and EMA, easily extensible.
- **Memory safe**: all allocations are explicit, easy to free
- **Extensible**: add new data sources or formats easily

---

## πŸ—οΈ Building & Running

1. **Build the library and demo:**
```sh
zig build
```
2. **Run the demo application:**
```sh
zig build run
```
The demo fetches S&P 500 data and prints a sample of parsed rows.

---

## πŸš€ Usage Example

```zig
const std = @import("std");
const ohlcv = @import("lib/ohlcv.zig");

pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const alloc = gpa.allocator();

// Fetch S&P 500 data (network + parser)
const rows = try ohlcv.fetch(.sp500, alloc);
defer alloc.free(rows);

std.debug.print("Fetched {d} rows of data.\n", .{rows.len});

// Print the first 5 rows as a sample
const count = if (rows.len < 5) rows.len else 5;
for (rows[0..count], 0..) |row, i| {
std.debug.print("Row {d}: ts={d}, o={d:.2}, h={d:.2}, l={d:.2}, c={d:.2}, v={d}\n",
.{i, row.ts, row.o, row.h, row.l, row.c, row.v});
}
}
```

---

## πŸ§‘β€πŸ’» API Overview

### Types

- `Row` β€” One OHLCV record:
```zig
const Row = struct {
ts: u64, // Unix timestamp (seconds)
o: f64, // Open
h: f64, // High
l: f64, // Low
c: f64, // Close
v: u64, // Volume
};
```
- `Bar` β€” OHLC (no volume):
```zig
const Bar = struct {
ts: u64, o: f64, h: f64, l: f64, c: f64
};
```
- `DataSet` β€” Enum of available remote datasets:
```zig
const DataSet = enum { btc_usd, sp500, eth_usd, gold_usd };
```

### Functions

- `fetch(ds: DataSet, alloc: Allocator) FetchError![]Row` β€” Fetch and parser remote CSV
- `parseCsv(alloc, reader) ![]Row` β€” Parse CSV from any reader (default parser)
- `parseCsvFast(alloc, reader) ![]Row` β€” Fast state-machine parser
- `parseFileCsv(alloc, path) ![]Row` β€” Parse CSV from file
- `parseStringCsv(alloc, data) ![]Row` β€” Parse CSV from in-memory string

### Errors

- `ParseError` β€” Possible parsing errors:
- `InvalidFormat`, `InvalidTimestamp`, `InvalidOpen`, `InvalidHigh`, `InvalidLow`, `InvalidClose`, `InvalidVolume`, `InvalidDateFormat`, `DateBeforeEpoch`, `OutOfMemory`, `EndOfStream`
- `FetchError` β€” `HttpError` or any `ParseError`

---

## πŸ“ Project Structure

```
.
β”œβ”€β”€ build.zig # Build script
β”œβ”€β”€ build.zig.zon # Package manifest
β”œβ”€β”€ demo.zig # Example usage executable
β”œβ”€β”€ INDICATORS.md # List and status of technical indicators
β”œβ”€β”€ lib/ # Library source code
β”‚ β”œβ”€β”€ ohlcv.zig # Public API (root source file)
β”‚ β”œβ”€β”€ parser/
β”‚ β”‚ β”œβ”€β”€ parser.zig # Main parser functions
β”‚ β”‚ β”œβ”€β”€ state_machine.zig # Internal state machine for parseCsvFast
β”‚ β”‚ └── parser.test.zig # Tests for parser
β”‚ β”œβ”€β”€ provider/
β”‚ β”‚ β”œβ”€β”€ provider.zig
β”‚ β”‚ └── provider.test.zig
β”‚ β”œβ”€β”€ types/
β”‚ β”‚ β”œβ”€β”€ bar.zig
β”‚ β”‚ β”œβ”€β”€ errors.zig
β”‚ β”‚ └── row.zig
β”‚ β”œβ”€β”€ indicators/
β”‚ β”‚ β”œβ”€β”€ indicators.zig # Indicator functions (SMA, EMA)
β”‚ β”‚ └── *.zig # Individual indicator implementations
β”‚ └── util/
β”‚ β”œβ”€β”€ date.zig
β”‚ └── date.test.zig
└── README.md # This file
```

---

## ⚠️ Row Skipping & Data Cleaning

- The parser **skips**:
- The header row
- Rows with invalid format or parser errors
- Rows with pre-1970 dates
- Rows where any of the OHLCV values are zero
- This means the number of parsed rows may be less than the number of lines in the CSV file.

---

## 🧩 Extending & Contributing

- Add new formats: add new parser functions in `parser.zig`
- PRs and issues welcome!

---

## πŸ“š See Also

- [demo.zig](demo.zig) β€” Full example usage
- [INDICATORS.md](INDICATORS.md) β€” List of implemented and planned technical indicators
- [lib/ohlcv.zig](lib/ohlcv.zig) β€” Public API

---

MIT License