From 6fc3ef1c6c659325c42bcc103466b4ddc764d144 Mon Sep 17 00:00:00 2001 From: Natercio Moniz Date: Sun, 6 Sep 2026 21:42:34 +0100 Subject: [PATCH] skip spin off actions --- internal/trading212/record.go | 23 +++++++++++++++++----- internal/trading212/record_test.go | 31 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/internal/trading212/record.go b/internal/trading212/record.go index 1c3c5f6..2e109fb 100644 --- a/internal/trading212/record.go +++ b/internal/trading212/record.go @@ -89,6 +89,7 @@ const ( StockSplitOpen = "stock split open" StockSplitClose = "stock split close" StokDistribution = "stock distribution" + SpinOff = "spin off" ) func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) { @@ -104,6 +105,8 @@ func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) continue } + symbol := raw[2] + qant, err := parseDecimal(raw[6]) if err != nil { return Record{}, fmt.Errorf("parse record quantity: %w", err) @@ -147,14 +150,14 @@ func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) splitRec = &splitRecord{ Record: Record{ - symbol: raw[2], + symbol: symbol, kind: internal.KindSplit, quantity: qant, price: price, fees: conversionFee, taxes: stampDutyTax.Add(frenchTxTax), timestamp: ts, - natureGetter: figiNatureGetter(ctx, rr.figi, raw[2]), + natureGetter: figiNatureGetter(ctx, rr.figi, symbol), }, } @@ -168,7 +171,17 @@ func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) return splitRec, nil case StokDistribution: - slog.Warn("Found stock distribution but can't handle it") + slog.Warn("Skipping 'stock distribution' event!", + slog.Any("ISIN", symbol), + slog.Any("Quantity", qant), + ) + continue + + case SpinOff: + slog.Warn("Skipping 'spin off' event!", + slog.Any("ISIN", symbol), + slog.Any("Quantity", qant), + ) continue default: @@ -176,14 +189,14 @@ func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) } return Record{ - symbol: raw[2], + symbol: symbol, kind: kind, quantity: qant, price: price, fees: conversionFee, taxes: stampDutyTax.Add(frenchTxTax), timestamp: ts, - natureGetter: figiNatureGetter(ctx, rr.figi, raw[2]), + natureGetter: figiNatureGetter(ctx, rr.figi, symbol), }, nil } } diff --git a/internal/trading212/record_test.go b/internal/trading212/record_test.go index b0d4fd0..2f4f513 100644 --- a/internal/trading212/record_test.go +++ b/internal/trading212/record_test.go @@ -2,6 +2,7 @@ package trading212 import ( "bytes" + "errors" "fmt" "io" "net/http" @@ -371,6 +372,36 @@ func ShouldParseDecimal(t testing.TB, sf string) decimal.Decimal { return bf } +func TestRecordReader_ReadRecord_SkipsCorporateActions(t *testing.T) { + tests := []struct { + name string + row string + }{ + { + name: "spin off", + row: `Spin off,2026-02-11 13:41:43+00:00,US9418481035,WAT,"Waters",EOF46451921527,0.0406450000,0E-10,USD,,,,0.00,"EUR",,,,,,`, + }, + { + name: "stock distribution", + row: `Stock distribution,2025-08-04 11:45:30,XX1234567890,ABXY,"Aspargus Broccoli",EOF987654321,2.4387014200,7.9999999999,USD,1.17995999,,"EUR",15.25,"EUR",,,0.02,"EUR",,`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rr := NewRecordReader( + bytes.NewBufferString(tt.row), + NewFigiClientSecurityTypeStub(t, "Common Stock"), + ) + + _, err := rr.ReadRecord(t.Context()) + if !errors.Is(err, io.EOF) { + t.Fatalf("want EOF after skipping %s, got: %v", tt.name, err) + } + }) + } +} + type RoundTripFunc func(req *http.Request) (*http.Response, error) func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {