Insyra v0.3.5 "Huashan": what's new
Insyra v0.3.5, still on the “Huashan” 0.3.x line, was released on October 24, 2026. Here’s the part I’d want to know if I were upgrading. Everything below comes from the v0.3.5 release notes and the changelog.
Highlights
- A training step can stay on the GPU.
Tensor.To(dev),ToHost()andRelease()move a float32 tensor to a device and back bit for bit, and the tape’s MatMul, Add, SoftmaxCrossEntropy and the SGD, Adam and AdamW steps run there. The release notes also put 2-D float32MatMulon the CPU at 1.2 to 2.9 times faster. - New
quant/tapackage for technical analysis. Trend (SMA,EMA,MACD,Ichimoku, …), channels and stops (Bollinger,Keltner,SuperTrend, …), oscillators (RSI,KD,CCI, …), volume (OBV,MFI, …),CandlePatternsand more. Where TA-Lib has the same indicator, the result is checked against it. quantfor market-efficiency research.QuantileSort,FamaMacBeth,EventStudy, and data-snooping testsRealityCheck,SPATestandRomanoWolf.datafetchfor Taiwan and Japan markets. TAIFEX futures and options history, odd-lot quotes, shareholding distribution, monthly revenue, FinMind and JPX investor-type trading.- I/O without a file on disk.
ReadCSVreads from anyio.Reader,StreamCSVreads a CSV a batch at a time, and aDataTablecan now be written to Excel withToExcel. - Smaller core niceties.
SliceRows/SliceCols,FilterRowsWhere,ColDataTypes,ShowHead/ShowTail, and CCLDATEPART.
The one I’ll use every day: read from anywhere, write to Excel
Before v0.3.5, reading a CSV meant a file path or a string. Now ReadCSV takes any io.Reader (an HTTP response body, an embed.FS file, bytes in memory), and ToExcel writes a table as one sheet of a workbook:
package main
import (
"fmt"
"strings"
"github.com/HazelnutParadise/insyra"
)
func main() {
// Any io.Reader works: an HTTP body, an embed.FS file, bytes in memory.
r := strings.NewReader("name,age,city,joined\nAmy,31,Taipei,2024\nBen,27,Tainan,2025\nCara,35,Taichung,2023\n")
dt, err := insyra.ReadCSV(r, insyra.CSVReadOptions{FirstRowToColNames: true})
if err != nil {
panic(err)
}
fmt.Println(dt.ColDataTypes())
// Columns from B up to (not including) D, like s[from:to] on a Go slice.
dt.SliceCols("B", "D").ShowHead(2)
// Write the table as one sheet of a workbook.
if err := dt.ToExcel("people.xlsx", insyra.ExcelWriteOptions{
Sheet: "2026",
SetColNamesToFirstRow: true,
}); err != nil {
panic(err)
}
fmt.Println("saved people.xlsx")
}
Output with v0.3.5 (the first line is Insyra’s info log):
2026/11/10 19:00:50 [insyra - Info] insyra.ReadCSV: Auto-detected encoding utf-8 for the CSV input
[string number string number]
DataTable (3 rows x 2 columns) [showing rows 0 to 1]
================================================================================
stat (selected range): A(mean=29.00, range=[27.00, 31.00])
--------------------------------------------------------------------------------
RowNames A(age) B(city)
---------- ------- ---------
0: 31 'Taipei'
1: 27 'Tainan'
saved people.xlsx
If people.xlsx already exists, ToExcel keeps its other sheets. If the sheet you name is already there, it returns an error matching ErrSheetExists and leaves the file alone, unless you set IfSheetExists: insyra.SheetExistsReplace. So one workbook with one sheet per year is a few lines. (Run the example above twice and you’ll see it: the second run stops with sheet already exists: 2026 in people.xlsx. That’s the safe default doing its job.)
Breaking changes
The release notes list five. Each one is an input or output that was wrong, refused or unsafe before:
- Go 1.26 is required. The
godirective is1.26.9. Go 1.25 stopped receiving fixes when Go 1.27 was released, and eleven standard-library vulnerabilities published on 2026-10-08 were fixed only in newer releases. ToSQLnames an unnamed column by its letter (A,B, …) instead of"", which MySQL and PostgreSQL refuse.- CCL turns a float into text as plain decimal digits.
'x' & Afor A = 0.0000001 is nowx0.0000001, notx1e-07;LEN(1000000)is 7. UseTOSTR(x, '%g')for the old spelling. - Error text for a cell now counts from zero, the same number
Get(i)takes (row index 2). FactorAnalysiswith oblimin andRestartsabove 1 now really restarts.
Also worth knowing: DataList.Difference, MovingAverage, MovingStdev and WeightedMovingAverage are deprecated and will be removed in 0.4. Their replacements are Diff(1) and Rolling(...).
Upgrade
go get -u github.com/HazelnutParadise/insyra/[email protected]
With Go 1.21 or newer, the go command downloads the 1.26.9 toolchain automatically unless GOTOOLCHAIN=local is set.
Full notes: GitHub release v0.3.5 · CHANGELOG · Docs: https://hazelnutparadise.github.io/insyra/ (DataTable, DataList) · Official site: https://insyra.hazelnut-paradise.com