Skip spin off actions #32
@@ -89,6 +89,7 @@ const (
|
|||||||
StockSplitOpen = "stock split open"
|
StockSplitOpen = "stock split open"
|
||||||
StockSplitClose = "stock split close"
|
StockSplitClose = "stock split close"
|
||||||
StokDistribution = "stock distribution"
|
StokDistribution = "stock distribution"
|
||||||
|
SpinOff = "spin off"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error) {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbol := raw[2]
|
||||||
|
|
||||||
qant, err := parseDecimal(raw[6])
|
qant, err := parseDecimal(raw[6])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Record{}, fmt.Errorf("parse record quantity: %w", err)
|
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{
|
splitRec = &splitRecord{
|
||||||
Record: Record{
|
Record: Record{
|
||||||
symbol: raw[2],
|
symbol: symbol,
|
||||||
kind: internal.KindSplit,
|
kind: internal.KindSplit,
|
||||||
quantity: qant,
|
quantity: qant,
|
||||||
price: price,
|
price: price,
|
||||||
fees: conversionFee,
|
fees: conversionFee,
|
||||||
taxes: stampDutyTax.Add(frenchTxTax),
|
taxes: stampDutyTax.Add(frenchTxTax),
|
||||||
timestamp: ts,
|
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
|
return splitRec, nil
|
||||||
|
|
||||||
case StokDistribution:
|
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
|
continue
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -176,14 +189,14 @@ func (rr RecordReader) ReadRecord(ctx context.Context) (internal.Record, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Record{
|
return Record{
|
||||||
symbol: raw[2],
|
symbol: symbol,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
quantity: qant,
|
quantity: qant,
|
||||||
price: price,
|
price: price,
|
||||||
fees: conversionFee,
|
fees: conversionFee,
|
||||||
taxes: stampDutyTax.Add(frenchTxTax),
|
taxes: stampDutyTax.Add(frenchTxTax),
|
||||||
timestamp: ts,
|
timestamp: ts,
|
||||||
natureGetter: figiNatureGetter(ctx, rr.figi, raw[2]),
|
natureGetter: figiNatureGetter(ctx, rr.figi, symbol),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package trading212
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -371,6 +372,36 @@ func ShouldParseDecimal(t testing.TB, sf string) decimal.Decimal {
|
|||||||
return bf
|
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)
|
type RoundTripFunc func(req *http.Request) (*http.Response, error)
|
||||||
|
|
||||||
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user