Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ type Position struct {
Size float64 `json:"size"`
AvgPrice float64 `json:"avgPrice"`
CurPrice float64 `json:"curPrice"`
Redeemable bool `json:"redeemable"`
CashPnl float64 `json:"cashPnl"`
PercentPnl float64 `json:"percentPnl"`
CurrentValue float64 `json:"currentValue"`
Expand Down Expand Up @@ -553,6 +554,14 @@ func fetchPositions(wallet string) ([]Position, error) {
"&sizeThreshold=0.1&limit=100&sortBy=CURRENT&sortDirection=DESC"
var out []Position
err := getJSON(url, &out, nil)
open := out[:0]
for _, p := range out {
if p.Redeemable && p.CurPrice == 0 {
continue
}
open = append(open, p)
}
out = open
fillEndTimes(out)
// Soonest resolution first; undated last. ISO timestamps sort as strings.
sort.SliceStable(out, func(i, j int) bool {
Expand Down
38 changes: 38 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,44 @@ func TestRefreshFastBacksOffAndKeepsLastPositions(t *testing.T) {
}
}

func TestFetchPositionsFiltersResolvedLosses(t *testing.T) {
cases := []struct {
name string
body string
want int
}{
{"resolved loss", `[{"size":15,"curPrice":0,"currentValue":0,"percentPnl":-99.9991,"redeemable":true}]`, 0},
{"unresolved zero price", `[{"curPrice":0,"redeemable":false}]`, 1},
{"winner awaiting redemption", `[{"curPrice":1,"redeemable":true}]`, 1},
{"missing resolution flag", `[{"curPrice":0}]`, 1},
{"mixed positions", `[{"curPrice":0,"redeemable":true},{"curPrice":0.68,"redeemable":false},{"curPrice":1,"redeemable":true}]`, 2},
{"empty portfolio", `[]`, 0},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(tc.body))
}))
defer srv.Close()
origBase := polyBase
polyBase = srv.URL
t.Cleanup(func() { polyBase = origBase })
positions, err := fetchPositions("0xtest")
if err != nil {
t.Fatal(err)
}
if len(positions) != tc.want {
t.Fatalf("got %d positions, want %d", len(positions), tc.want)
}
for _, p := range positions {
if p.Redeemable && p.CurPrice == 0 {
t.Error("resolved loss remains visible")
}
}
})
}
}

func TestFetchPositionsSortsByEndTime(t *testing.T) {
// Same calendar day for noon/evening: only gamma's timestamp separates them.
poly := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down