Sortierproblem? "Comparison method violates its general contract!"

Nach Klick auf Berichte / Performance / Wertpapiere, oder nach Klick auf Berichte / Vermögensaufstellung

Comparison method violates its general contract!

java.lang.IllegalArgumentException: Comparison method violates its general contract!
	at java.base/java.util.TimSort.mergeHi(TimSort.java:903)
	at java.base/java.util.TimSort.mergeAt(TimSort.java:520)
	at java.base/java.util.TimSort.mergeForceCollapse(TimSort.java:461)
	at java.base/java.util.TimSort.sort(TimSort.java:254)
	at java.base/java.util.Arrays.sort(Arrays.java:1308)
	at java.base/java.util.ArrayList.sort(ArrayList.java:1804)
	at java.base/java.util.Collections.sort(Collections.java:178)
	at name.abuchen.portfolio.snapshot.security.SecurityPerformanceSnapshotBuilder.lambda$0(SecurityPerformanceSnapshotBuilder.java:50)
	at java.base/java.util.HashMap$Values.forEach(HashMap.java:1073)
	at name.abuchen.portfolio.snapshot.security.SecurityPerformanceSnapshotBuilder.create(SecurityPerformanceSnapshotBuilder.java:50)
	at name.abuchen.portfolio.snapshot.security.LazySecurityPerformanceSnapshot.create(LazySecurityPerformanceSnapshot.java:16)
	at name.abuchen.portfolio.ui.views.SecuritiesPerformanceView.reportingPeriodUpdated(SecuritiesPerformanceView.java:1853)
	at name.abuchen.portfolio.ui.views.SecuritiesPerformanceView.createBody(SecuritiesPerformanceView.java:827)
	at name.abuchen.portfolio.ui.editor.AbstractFinanceView.createViewControl(AbstractFinanceView.java:171)
	at name.abuchen.portfolio.ui.editor.PortfolioPart.createView(PortfolioPart.java:573)
	at name.abuchen.portfolio.ui.editor.PortfolioPart.activateView(PortfolioPart.java:529)
	at name.abuchen.portfolio.ui.editor.PortfolioPart.activateView(PortfolioPart.java:517)
	at name.abuchen.portfolio.ui.editor.ClientEditorSidebar$1.select(ClientEditorSidebar.java:71)
	at name.abuchen.portfolio.ui.editor.ClientEditorSidebar$1.select(ClientEditorSidebar.java:1)
	at name.abuchen.portfolio.ui.editor.Sidebar$Entry.handleMouseDown(Sidebar.java:419)
	at org.eclipse.swt.events.MouseListener$2.mouseDown(MouseListener.java:96)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:209)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5857)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1617)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:5067)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4519)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:165)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1454)

Das Verhalten ist reproduzierbar: Sobald ich dieser Steuerrückerstattung


mittels Editieren ein Wertpapier zuordne, ist der Fehler da, entferne ich das Wertpapier wieder, ist der Fehler wieder weg. Strange.

Berichte/Performance/Wertpapiere und Berichte/Vermögensaufstellung sind beide nach der Spalte Marktwert sortiert.

So ein ähnliches Verhalten gab es schon in Formatting of limit prevents opening of "All securities" view - #10 by OnkelDok
Der Fix fix sorting of limit price column · portfolio-performance/portfolio@d11c6d2 · GitHub bezog sich auf LimitPrice - braucht man für den Marktwert vielleicht etwas ähnliches?

2 Likes

Hey @ProgFriese
Kannst du uns ein Minimalbeispiel zur Verfügung stellen?

@AndreasB @OnkelDok

Ich schau morgen mal ob in einem Minimalbeispiel auch der Fehler auftritt, falls nicht könnte ich auch die ganze Datei bereitstellen. Wie war noch die Adresse dafür?

1 Like

Es sieht für mich danach aus also hätte es was mit der Sortierung von den Buchungen dieses Wertpapiers, wenn bestimmte Kennzahlen berechnet werden.

Ich vermute der Fehler tritt dann noch auf, wenn Du Buchungen aller anderen Wertpapiere löscht.

Die Datei würde mich dann interessieren. Du erreichst mit unter portfolio dot performance dot help at gmail dot com

Im CalculationLineItemCoparator scheint es Widersprüche bei der Sortierung zu geben.

Vll hilft schon die Benutzung von Integer.compareTo an allen Stellen, an denen aktuell zwei integer subtrahiert werden. Der Comparer ist aber auch relativ komplex - gut möglich, dass es an anderen Stellen hakt.

1 Like

Das kann ich versuchen.

Ich könnte mir auch vorstellen, dass es irgendwie an der Logik liegt, wie ich Buchungen nach Datum vergleiche wenn sei eine Uhrzeit haben. Wenn beide Buchungen eine Uhrzeit haben, wird nach Uhrzeit sortiert - ansonsten nach Typ.

Ich bekomme das aber (noch) nicht reproduziert.

1 Like

Du hast Post, mit der ganzen Datei. Ein gebautes Minimalbeispiel schmiss den Fehler nicht.

1 Like

Danke @ProgFriese

Ich kann das Problem nachstellen.

Das Problem is folgendes: Für einige Berechnungen - hier: Trades - sortiere ich die Buchungen erst nach Datum und dann nach Typ. Wenn man z.B. keine Uhrzeit erfasst, will ich trotzdem erst die Käufe und dann die Verkäufe verarbeiten. So vermeide ich, dass unnötig negative Bestände auftauchen.

In Deiner Datei hast Du viele Buchungen zu einem Papier an einem Tag. Und zwar Buchungen mit Uhrzeit. Die werden auch so sortiert. Aber die Steuerrückerstattung hat keine Uhrzeit. Diese Steuerrückerstattung will ich zwischen Käufe und Verkäufe sortieren. Das schlägt hier fehl weil es schon mehre Käufe und Verkäufe nach Uhrzeit sortiert - aber gemischt gibt.

Ich frage in etwa das: [verkauf, kauf, verkauf, kauf] - sortiere die “Steuerrückerstattung” nach allen Käufen und vor allen Verkäufen ein.

Wenn Du der Steuerrückerstattung eine Uhrzeit gibst - sagen wir 07:00 - dann tritt der Fehler nicht mehr auf. Da sind aber mehrere solche Tage in Deiner Datei. Eventuell musst Du mehreren eine Uhrzeit vergeben.

Ich muss mal überlegen wie ich das löse… vielleicht bekommen alle Buchungen ohne Uhrzeit virtuell die “12:00”. Dann funktioniert es für diejenigen die keine Uhrzeit erfassen und für die, die eine Uhrzeit erfassen. Nur Intraday Trades die teilweise mit Uhrzeit und teilweise ohne Uhrzeit sind, könnte es zu unvollständigen Trades führen.

3 Likes

Bingo, der Workaround funktioniert. Besten Dank!

Hallo,
es gehört sicher nicht ursächlich zu der Problemstellung, aber die Uhrzeit macht auch an anderen Stellen gewisse “Probleme”, z.B. bei einem Export der Trade-Daten in eine csv -Datei, in dem die Spalte mit Datum und Uhrzeit manuell “umformatiert” werden muss, wenn man dort nur das Datum ohne Uhrzeit benötigt.
Mit ist klar, das viele die Uhrzeit bei vielen Trades am Tag benötigen. Aber könnte man nicht das Feld aufteilen in “Datum” und “Uhrzeit” und dadurch Beides getrennt nutzbar machen ? Die jeweilige Uhrzeit ist doch an den jeweiligen Trade gekoppelt ?

Das löst dann evtl. auch das Problem, dass nicht in allen Trades (oder Steuerrückerstattungen :grinning_face:) eine Uhrzeit vorhanden ist. Ich z.B. lösche in PP aus allen Trades die Uhrzeit, um die o.g. Probleme beim Export zu vermeiden.

Hoffe, ich mache als Laie kein Durcheinander…

1 Like

Ich habe einige Eclipse-Funktionen getestet und habe diesen Fall in meiner Datei mit der zukünftigen neuen Sortierung gefunden.

Dabei
Capture d’écran 2025-07-14 175746

Ich erhalte den Trade Fehler.

Wenn ich die Uhrzeit entferne, zeigt der Transaktion Reiter zwar den Verkauf vor der Überweisung, aber der Trade existiert nun.
Capture d’écran 2025-07-14 175854

Ich verwende normalerweise keine Zeitangaben, daher habe ich mir angewöhnt, eine falsche 00:01-Zeit einzugeben, um die Transaktionen zu ordnen. Aber vielleicht war das nicht der richtige Weg.

translated with Deepl