From 0308f485b1152dabc8d14b175ff584c4f8e10a58 Mon Sep 17 00:00:00 2001 From: Roman Langrehr Date: Thu, 10 Nov 2022 23:02:39 +0100 Subject: [PATCH] Added Widget for performance-based all time high (and clarify that the existing one works based on prices). --- .../math/AllTimeHighPerformanceTest.java | 137 ++++++++++++++++++ ...ighTest.java => AllTimeHighPriceTest.java} | 18 +-- .../name/abuchen/portfolio/ui/Messages.java | 6 +- .../abuchen/portfolio/ui/messages.properties | 14 +- .../portfolio/ui/messages_cs.properties | 14 +- .../portfolio/ui/messages_de.properties | 14 +- .../portfolio/ui/messages_es.properties | 14 +- .../portfolio/ui/messages_fr.properties | 14 +- .../portfolio/ui/messages_it.properties | 14 +- .../portfolio/ui/messages_nl.properties | 14 +- .../portfolio/ui/messages_pt.properties | 14 +- .../portfolio/ui/messages_ru.properties | 14 +- .../portfolio/ui/messages_sk.properties | 14 +- .../DistanceFromAllTimeHighColumn.java | 4 +- .../ui/views/dashboard/WidgetFactory.java | 43 +++++- .../math/AllTimeHighPerformance.java | 60 ++++++++ .../portfolio/math/AllTimeHighPrice.java | 61 ++++++++ 17 files changed, 404 insertions(+), 65 deletions(-) create mode 100644 name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPerformanceTest.java rename name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/{AllTimeHighTest.java => AllTimeHighPriceTest.java} (85%) create mode 100644 name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPerformance.java create mode 100644 name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPrice.java diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPerformanceTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPerformanceTest.java new file mode 100644 index 0000000000..41fcaa87ea --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPerformanceTest.java @@ -0,0 +1,137 @@ +package name.abuchen.portfolio.math; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.OptionalDouble; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import name.abuchen.portfolio.snapshot.PerformanceIndex; + +public class AllTimeHighPerformanceTest +{ + private PerformanceIndex emptyIndex; + private PerformanceIndex oneEntryIndex; + private PerformanceIndex athAtTheEndIndex; + private PerformanceIndex athAtTheBeginnigIndex; + private PerformanceIndex athInTheMiddle; + private PerformanceIndex bankruptcy; + private PerformanceIndex worseThanBankruptcy; // Asset that looses more than 100% + + @Before + public void setUp() + { + emptyIndex = Mockito.mock(PerformanceIndex.class); + when(emptyIndex.getAccumulatedPercentage()).thenReturn(new double[] {}); + when(emptyIndex.getDates()).thenReturn(new LocalDate[] {}); + + oneEntryIndex = Mockito.mock(PerformanceIndex.class); + when(oneEntryIndex.getAccumulatedPercentage()).thenReturn(new double[] { 0d }); + when(oneEntryIndex.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 10) }); + + athAtTheEndIndex = Mockito.mock(PerformanceIndex.class); + when(athAtTheEndIndex.getAccumulatedPercentage()).thenReturn(new double[] { 0d, -.1d, -.1d, -.05d, .1d, .15d}); + when(athAtTheEndIndex.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 2), + LocalDate.of(2022, 11, 3), LocalDate.of(2022, 11, 4), LocalDate.of(2022, 11, 6), + LocalDate.of(2022, 11, 8), LocalDate.of(2022, 11, 11) }); + + athAtTheBeginnigIndex = Mockito.mock(PerformanceIndex.class); + when(athAtTheBeginnigIndex.getAccumulatedPercentage()).thenReturn(new double[] { 0d, -.1d, -.1d, -.05d, -.2d, -.15d}); + when(athAtTheBeginnigIndex.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 2), + LocalDate.of(2022, 11, 3), LocalDate.of(2022, 11, 4), LocalDate.of(2022, 11, 6), + LocalDate.of(2022, 11, 8), LocalDate.of(2022, 11, 11) }); + + athInTheMiddle = Mockito.mock(PerformanceIndex.class); + when(athInTheMiddle.getAccumulatedPercentage()).thenReturn(new double[] { 0d, -.1d, -.2d, 1d, .5d, 0d}); + when(athInTheMiddle.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 2), + LocalDate.of(2022, 11, 3), LocalDate.of(2022, 11, 4), LocalDate.of(2022, 11, 6), + LocalDate.of(2022, 11, 8), LocalDate.of(2022, 11, 11) }); + + bankruptcy = Mockito.mock(PerformanceIndex.class); + when(bankruptcy.getAccumulatedPercentage()).thenReturn(new double[] { 0d, .1d, .23d, -.9d, -1d, -1d}); + when(bankruptcy.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 2), + LocalDate.of(2022, 11, 3), LocalDate.of(2022, 11, 4), LocalDate.of(2022, 11, 6), + LocalDate.of(2022, 11, 8), LocalDate.of(2022, 11, 11) }); + + worseThanBankruptcy = Mockito.mock(PerformanceIndex.class); + when(worseThanBankruptcy.getAccumulatedPercentage()).thenReturn(new double[] { 0d, -.1d, -.23d, -.9d, -1d, -1.5d}); + when(worseThanBankruptcy.getDates()).thenReturn(new LocalDate[] { LocalDate.of(2022, 11, 2), + LocalDate.of(2022, 11, 3), LocalDate.of(2022, 11, 4), LocalDate.of(2022, 11, 6), + LocalDate.of(2022, 11, 8), LocalDate.of(2022, 11, 11) }); + } + + @Test + public void testEmptyIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(emptyIndex); + + assertTrue(ath.getDistance().isEmpty()); + assertTrue(ath.getDate().isEmpty()); + } + + @Test + public void testOneEntryIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(oneEntryIndex); + + assertApproximatelyEquals(OptionalDouble.of(0d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 10)), ath.getDate()); + } + + @Test + public void testATHAtTheEndIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(athAtTheEndIndex); + + assertApproximatelyEquals(OptionalDouble.of(0d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 11)), ath.getDate()); + } + + @Test + public void testATHAtTheBeginningIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(athAtTheBeginnigIndex); + + assertApproximatelyEquals(OptionalDouble.of(-.15d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 2)), ath.getDate()); + } + + @Test + public void testATHInTheMiddleIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(athInTheMiddle); + + assertApproximatelyEquals(OptionalDouble.of(-.5d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 6)), ath.getDate()); + } + + @Test + public void testBankruptcyIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(bankruptcy); + + assertApproximatelyEquals(OptionalDouble.of(-1d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 4)), ath.getDate()); + } + + @Test + public void testWorseThanBankruptcyIndex() + { + AllTimeHighPerformance ath = new AllTimeHighPerformance(worseThanBankruptcy); + + assertApproximatelyEquals(OptionalDouble.of(-1.5d), ath.getDistance()); + assertEquals(Optional.of(LocalDate.of(2022, 11, 2)), ath.getDate()); + } + + private static void assertApproximatelyEquals(OptionalDouble double1, OptionalDouble double2) + { + assertTrue(double1.isPresent() == double2.isPresent()); + assertEquals(double1.getAsDouble(), double2.getAsDouble(), 0.00001d); + } +} diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPriceTest.java similarity index 85% rename from name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighTest.java rename to name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPriceTest.java index 90a8ebaf1d..0a2e03d033 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/math/AllTimeHighPriceTest.java @@ -13,7 +13,7 @@ import name.abuchen.portfolio.util.Interval; @SuppressWarnings("nls") -public class AllTimeHighTest +public class AllTimeHighPriceTest { private Security securityOnePrice; private Security securityTenPrices; @@ -57,7 +57,7 @@ private void buildPrices(Security security, Long[] prices) public void testSecurityIsNull() { Interval interval = Interval.of(securityOnePrice.getPrices().get(0).getDate(), LocalDate.now()); - AllTimeHigh ath = new AllTimeHigh(null, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(null, interval); assertNull(ath.getDistance()); assertNull(ath.getValue()); @@ -68,7 +68,7 @@ public void testSecurityIsNull() public void testSecurityHasOnlyOnePrice() { Interval interval = Interval.of(securityOnePrice.getPrices().get(0).getDate(), LocalDate.now()); - AllTimeHigh ath = new AllTimeHigh(this.securityOnePrice, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityOnePrice, interval); assertNull(ath.getValue()); assertNull(ath.getDistance()); @@ -79,7 +79,7 @@ public void testSecurityHasOnlyOnePrice() public void testAthValueFor10Prices() { Interval interval = Interval.of(securityTenPrices.getPrices().get(0).getDate(), LocalDate.now()); - AllTimeHigh ath = new AllTimeHigh(this.securityTenPrices, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityTenPrices, interval); assertEquals(Long.valueOf(2133L), ath.getValue()); assertEquals(-0.47444, ath.getDistance(), 0.00001); @@ -90,7 +90,7 @@ public void testAthValueFor10Prices() public void testAthValueFor7PricesWithDateGaps() { Interval interval = Interval.of(this.securitySevenPricesWithGaps.getPrices().get(0).getDate(), LocalDate.now()); - AllTimeHigh ath = new AllTimeHigh(this.securitySevenPricesWithGaps, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securitySevenPricesWithGaps, interval); assertEquals(Long.valueOf(2062L), ath.getValue()); assertEquals(-0.24005, ath.getDistance(), 0.00001); @@ -101,7 +101,7 @@ public void testAthValueFor7PricesWithDateGaps() public void testAthValueFor10PricesForLargerInterval() { Interval interval = Interval.of(LocalDate.of(2021, 1, 1), LocalDate.of(2023, 12, 31)); - AllTimeHigh ath = new AllTimeHigh(this.securityTenPrices, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityTenPrices, interval); assertEquals(Long.valueOf(2133L), ath.getValue()); assertEquals(-0.47444, ath.getDistance(), 0.00001); @@ -112,7 +112,7 @@ public void testAthValueFor10PricesForLargerInterval() public void testAthValueFor10PricesForLast2DaysInterval() { Interval interval = Interval.of(LocalDate.of(2022, 6, 10), LocalDate.of(2022, 6, 11)); - AllTimeHigh ath = new AllTimeHigh(this.securityTenPrices, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityTenPrices, interval); assertEquals(Long.valueOf(1121L), ath.getValue()); assertEquals(0, ath.getDistance(), 0.00001); @@ -123,7 +123,7 @@ public void testAthValueFor10PricesForLast2DaysInterval() public void testAthValueFor10PricesFor5DaysInterval() { Interval interval = Interval.of(LocalDate.of(2022, 6, 7), LocalDate.of(2022, 6, 10)); - AllTimeHigh ath = new AllTimeHigh(this.securityTenPrices, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityTenPrices, interval); assertEquals(Long.valueOf(1500L), ath.getValue()); assertEquals(-0.4, ath.getDistance(), 0.00001); @@ -134,7 +134,7 @@ public void testAthValueFor10PricesFor5DaysInterval() public void testAthValueFor10PricesForFirst3DaysInterval() { Interval interval = Interval.of(LocalDate.of(2022, 1, 31), LocalDate.of(2022, 6, 4)); - AllTimeHigh ath = new AllTimeHigh(this.securityTenPrices, interval); + AllTimeHighPrice ath = new AllTimeHighPrice(this.securityTenPrices, interval); assertEquals(Long.valueOf(699L), ath.getValue()); assertEquals(0, ath.getDistance(), 0.00001); diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java index d05b53c1d0..38e3617ad0 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java @@ -595,6 +595,8 @@ public class Messages extends NLS public static String LabelDefaultReferenceAccountName; public static String LabelDelta; public static String LabelDescription; + public static String LabelDistanceFromATHPrice; + public static String LabelDistanceFromATHPerformance; public static String LabelDoImport; public static String LabelDoNotImport; public static String LabelEarnings; @@ -1089,7 +1091,6 @@ public class Messages extends NLS public static String SecurityFilterSharesHeldNotZero; public static String SecurityListFilter; public static String SecurityListFilterDateReached; - public static String SecurityListFilterDistanceFromAth; public static String SecurityListFilterHideInactive; public static String SecurityListFilterLimitPriceExceeded; public static String SecurityListFilterOnlyExchangeRates; @@ -1186,7 +1187,8 @@ public class Messages extends NLS public static String TabAccountBalanceChart; public static String TabTransactions; public static String TitlePasswordDialog; - public static String TooltipAllTimeHigh; + public static String TooltipAllTimeHighPrice; + public static String TooltipAllTimeHighPerformance; public static String TooltipAverageHoldingPeriod; public static String TooltipDateOfExchangeRate; public static String TooltipHintPressAlt; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties index 19ed3c1c0d..8d8d367a4a 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties @@ -594,9 +594,9 @@ ColumnQuoteChange_Description = Percentage change of the quote within the given ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Distance from ATH +ColumnQuoteDistanceFromAthPercent = Distance from ATH (price) -ColumnQuoteDistanceFromAthPercent_Description = Percentage distance from the last All Time High (ATH) in the chosen period. +ColumnQuoteDistanceFromAthPercent_Description = Percentage distance from the last price-based All Time High (ATH) in the chosen period. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1202,6 +1202,10 @@ LabelDelta = Delta (for reporting period) LabelDescription = Description +LabelDistanceFromATHPrice = Security: Distance from ATH (Price) + +LabelDistanceFromATHPerformance = Distance from ATH (Performance) + LabelDividendPerShare = dividend payment per shares LabelDividends = Dividends @@ -2206,8 +2210,6 @@ SecurityListFilter = Filter securities SecurityListFilterDateReached = Securities: Date reached -SecurityListFilterDistanceFromAth = Security: Distance from ATH - SecurityListFilterHideInactive = Only active instruments SecurityListFilterLimitPriceExceeded = Securities: Limit price exceeded @@ -2394,7 +2396,9 @@ TabTransactions = Transactions TitlePasswordDialog = Assign password -TooltipAllTimeHigh = All-Time High (ATH) in the last {0} days: {2} ({1})\nCurrent security price: {3} ({4}) +TooltipAllTimeHighPrice = Price-based All-Time High (ATH) in the last {0} days: {3} ({1} days ago, on {2})\nCurrent security price: {4} ({5}) + +TooltipAllTimeHighPerformance = Performance-based All-Time High (ATH) in the last {0} days: {1} days ago, on {2} TooltipAverageHoldingPeriod = The average holding period is calculated as follows:\n\n* All trades are included that were in the portfolio at some point within the selected reporting period.\n\n* The holding period of each security results from the time of purchase and sale. Immediate sales are assumed for positions currently held.\n\n* The position weight is calculated from the purchase price of the position relative to the total number of all purchase prices.\n\n* Result "average holding period of all positions" is the sum of the products "holding period * percentage position weight" across all positions. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties index 3029fb2b7d..a48dd9a117 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties @@ -584,9 +584,9 @@ ColumnQuoteChange_Description = Procentu\u00E1ln\u00ED zm\u011Bna kotace v dan\u ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Vzd\u00E1lenost od ATH +ColumnQuoteDistanceFromAthPercent = Vzd\u00E1lenost od ATH (cena) -ColumnQuoteDistanceFromAthPercent_Description = Procentu\u00E1ln\u00ED vzd\u00E1lenost od posledn\u00EDho All Time High (ATH) ve zvolen\u00E9m obdob\u00ED. +ColumnQuoteDistanceFromAthPercent_Description = Procentu\u00E1ln\u00ED vzd\u00E1lenost od posledn\u00EDho cenov\u00E9ho maxima (ATH) ve zvolen\u00E9m obdob\u00ED. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1188,6 +1188,10 @@ LabelDelta = Delta (za sledovan\u00E9 obdob\u00ED) LabelDescription = Popis +LabelDistanceFromATHPrice = Zabezpe\u010Den\u00ED: Vzd\u00E1lenost od ATH (Cena) + +LabelDistanceFromATHPerformance = Vzd\u00E1lenost od ATH (v\u00FDkon) + LabelDividendPerShare = v\u00FDplata dividendy na akcii LabelDividends = Dividendy @@ -2190,8 +2194,6 @@ SecurityListFilter = Filtrovat cenn\u00E9 pap\u00EDry SecurityListFilterDateReached = Cenn\u00E9 pap\u00EDry: dosa\u017Een\u00FD datum -SecurityListFilterDistanceFromAth = Zabezpe\u010Den\u00ED: Vzd\u00E1lenost od ATH - SecurityListFilterHideInactive = Pouze aktivn\u00ED cenn\u00E9 pap\u00EDry SecurityListFilterLimitPriceExceeded = P\u0159ekro\u010Den\u00ED limitn\u00ED ceny @@ -2378,7 +2380,9 @@ TabTransactions = Transakce TitlePasswordDialog = P\u0159i\u0159adit heslo -TooltipAllTimeHigh = All-Time High (ATH) za posledn\u00EDch {0} dn\u00ED: {2} ({1})\nAktu\u00E1ln\u00ED cena cenn\u00E9ho pap\u00EDru: {3} ({4}) +TooltipAllTimeHighPrice = Cenov\u00E9 maximum (ATH) za posledn\u00EDch {0} dn\u00ED: {3} (p\u0159ed {1} dny, dne {2})\nAktu\u00E1ln\u00ED cena cenn\u00E9ho pap\u00EDru: {4} ({5}) + +TooltipAllTimeHighPerformance = V\u00FDkonnostn\u00ED maximum (ATH) za posledn\u00EDch {0} dn\u00ED: p\u0159ed {1} dny, dne {2}. TooltipAverageHoldingPeriod = Pr\u016Fm\u011Brn\u00E1 doba dr\u017Een\u00ED se vypo\u010D\u00EDt\u00E1 takto:\n\n* Zahrnuty jsou v\u0161echny obchody, kter\u00E9 byly v portfoliu v ur\u010Dit\u00E9m okam\u017Eiku v r\u00E1mci zvolen\u00E9ho vykazovan\u00E9ho obdob\u00ED.\n\n* Doba dr\u017Eby ka\u017Ed\u00E9ho cenn\u00E9ho pap\u00EDru vypl\u00FDv\u00E1 z okam\u017Eiku n\u00E1kupu a prodeje. U aktu\u00E1ln\u011B dr\u017Een\u00FDch pozic se p\u0159edpokl\u00E1d\u00E1 okam\u017Eit\u00FD prodej.\n\n* V\u00E1ha pozice se vypo\u010D\u00EDt\u00E1 z n\u00E1kupn\u00ED ceny pozice vzhledem k celkov\u00E9mu po\u010Dtu v\u0161ech n\u00E1kupn\u00EDch cen.\n\n* V\u00FDsledek "pr\u016Fm\u011Brn\u00E1 doba dr\u017Een\u00ED v\u0161ech pozic" je sou\u010Dtem sou\u010Din\u016F "doba dr\u017Een\u00ED * procentn\u00ED v\u00E1ha pozice" ve v\u0161ech pozic\u00EDch. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties index 92c1a84e28..5a0b0967b8 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = Prozentuale Kurs\u00E4nderung bezogen auf den Ze ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Abstand vom ATH +ColumnQuoteDistanceFromAthPercent = Abstand vom ATH (Preis) -ColumnQuoteDistanceFromAthPercent_Description = Prozentualer Abstand zum letzten All Time High (ATH) in dem gew\u00E4hlten Zeitraum. +ColumnQuoteDistanceFromAthPercent_Description = Prozentualer Abstand zum letzten preis-basierten All Time High (ATH) in dem gew\u00E4hlten Zeitraum. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1187,6 +1187,10 @@ LabelDelta = Delta (im Berichtszeitraum) LabelDescription = Beschreibung +LabelDistanceFromATHPrice = Wertpapier: Abstand vom ATH (Preis) + +LabelDistanceFromATHPerformance = Abstand vom ATH (Performance) + LabelDividendPerShare = Dividende pro St\u00FCck LabelDividends = Dividenden @@ -2189,8 +2193,6 @@ SecurityListFilter = Wertpapiere filtern SecurityListFilterDateReached = Wertpapiere: Termin erreicht -SecurityListFilterDistanceFromAth = Wertpapier: Abstand vom ATH - SecurityListFilterHideInactive = Nur aktive Instrumente SecurityListFilterLimitPriceExceeded = Wertpapiere: Limit \u00FCberschritten @@ -2377,7 +2379,9 @@ TabTransactions = Ums\u00E4tze TitlePasswordDialog = Passwort vergeben -TooltipAllTimeHigh = All-Time-High (ATH) in den letzten {0} Tagen: {2} ({1})\nAktueller Kurs: {3} ({4}) +TooltipAllTimeHighPrice = Preis-basiertes All-Time-High (ATH) in den letzten {0} Tagen: {3} (vor {1} Tagen, am {2})\nAktueller Kurs: {4} ({5}) + +TooltipAllTimeHighPerformance = Performance-basiertes All-Time-High (ATH) in den letzten {0} Tagen: Vor {1} Tagen, am {2} TooltipAverageHoldingPeriod = Die mittlere Haltedauer errechnet sich wie folgt:\n\n* Es werden alle Trades einbezogen die irgendwann innerhalb des gew\u00E4hlten Berichtszeitraums im Depot waren.\n\n* Die Haltedauer jedes Wertpapiers ergibt sich aus Kauf- und Verkaufszeitpunkt. F\u00FCr aktuell gehaltene Positionen wird ein sofortiger Verkauf unterstellt.\n\n* Das Positionsgewicht errechnet sich aus Kaufpreis der Position relativ zu der Gesamtsumme aller Kaufpreise.\n\n* Ergebnis "mittlere Haltedauer aller Positionen" ergibt sich als Summe der Produkte "Haltedauer * prozentuales Positionsgewicht" \u00FCber alle Positionen. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties index 050fed4ee4..d520e1665c 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = cambio porcentual de la cotizaci\u00F3n dentro d ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Distancia desde ATH +ColumnQuoteDistanceFromAthPercent = Distancia desde ATH (precio) -ColumnQuoteDistanceFromAthPercent_Description = Distancia porcentual desde el \u00FAltimo All Time High (ATH) en el periodo elegido. +ColumnQuoteDistanceFromAthPercent_Description = Distancia porcentual desde el \u00FAltimo All Time High (ATH) basado en el precio en el periodo elegido. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1185,6 +1185,10 @@ LabelDelta = Delta (por per\u00EDodo de reporte) LabelDescription = Descripci\u00F3n +LabelDistanceFromATHPrice = Seguridad: Distancia de ATH (Precio) + +LabelDistanceFromATHPerformance = Distancia de ATH (Rendimiento) + LabelDividendPerShare = pago de dividendos por acci\u00F3n LabelDividends = Dividendos @@ -2181,8 +2185,6 @@ SecurityListFilter = Filtrar valores SecurityListFilterDateReached = Valores: fecha alcanzada -SecurityListFilterDistanceFromAth = Seguridad: Distancia de ATH - SecurityListFilterHideInactive = Solo instrumentos activos SecurityListFilterLimitPriceExceeded = Valores: Se excedi\u00F3 el precio l\u00EDmite @@ -2369,7 +2371,9 @@ TabTransactions = Transacciones TitlePasswordDialog = Asignar una contrase\u00F1a -TooltipAllTimeHigh = M\u00E1ximo hist\u00F3rico (ATH) en los \u00FAltimos {0} d\u00EDas: {2} ({1})\nPrecio actual del valor: {3} ({4}) +TooltipAllTimeHighPrice = Precio M\u00E1ximo hist\u00F3rico (ATH) en los \u00FAltimos {0} d\u00EDas: {3} (hace {1} d\u00EDas, en {2})\nPrecio actual del valor: {4} ({5}) + +TooltipAllTimeHighPerformance = M\u00E1ximo hist\u00F3rico (ATH) en los \u00FAltimos {0} d\u00EDas: Hace {1} d\u00EDas, el {2}. TooltipAverageHoldingPeriod = El per\u00EDodo de mantenimiento promedio se calcula de la siguiente manera:\n\n* Se incluyen todas las operaciones que estaban en la cartera en alg\u00FAn momento dentro del per\u00EDodo de informe seleccionado.\n\n* El per\u00EDodo de tenencia de cada valor de seguridad es el momento de la compra y venta. Se asumen ventas inmediatas para los puestos actualmente ocupados.\n\n* El peso de la posici\u00F3n se calcula a partir del precio de compra de la posici\u00F3n en relaci\u00F3n con el n\u00FAmero total de todos los precios de compra.\n\n* El resultado "per\u00EDodo de mantenimiento promedio de todas las posiciones" es la suma de los productos "per\u00EDodo de mantenimiento * peso porcentual de la posici\u00F3n" en todas las posiciones. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties index 12e96c52f4..dfaab3ed4e 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties @@ -582,9 +582,9 @@ ColumnQuoteChange_Description = Variation de cotation en pourcentage dans la p\u ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Distance de l'ATH +ColumnQuoteDistanceFromAthPercent = Distance de l'ATH (prix) -ColumnQuoteDistanceFromAthPercent_Description = Distance en pourcentage par rapport au dernier All Time High (ATH) de la p\u00E9riode choisie. +ColumnQuoteDistanceFromAthPercent_Description = Distance en pourcentage par rapport au dernier All Time High (ATH) bas\u00E9 sur le prix de la p\u00E9riode choisie. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1190,6 +1190,10 @@ LabelDelta = Delta (pour p\u00E9riode en cours) LabelDescription = Description +LabelDistanceFromATHPrice = S\u00E9curit\u00E9 : Distance de l'ATH (Prix) + +LabelDistanceFromATHPerformance = Distance de l'ATH (Performance) + LabelDividendPerShare = dividendes par parts LabelDividends = Dividendes @@ -2188,8 +2192,6 @@ SecurityListFilter = Filtrer titres SecurityListFilterDateReached = Titres : date atteinte -SecurityListFilterDistanceFromAth = S\u00E9curit\u00E9 : Distance de l'ATH - SecurityListFilterHideInactive = Seulement instruments actifs SecurityListFilterLimitPriceExceeded = Titres : Prix limite d\u00E9pass\u00E9 @@ -2376,7 +2378,9 @@ TabTransactions = Op\u00E9rations TitlePasswordDialog = Assigner mot de passe -TooltipAllTimeHigh = Plus haut historique (ATH) au cours des {0} derniers jours : {2} ({1})\nPrix actuel du titre : {3} ({4}) +TooltipAllTimeHighPrice = Prix bas\u00E9 plus haut historique (ATH) au cours des {0} derniers jours : {3} (il y a {1} jours, le {2})\nPrix actuel du titre : {4} ({5}) + +TooltipAllTimeHighPerformance = Performance bas\u00E9 plus haut historique (ATH) au cours des {0} derniers jours : il y a {1} jours, le {2} TooltipAverageHoldingPeriod = La dur\u00E9e moyenne de d\u00E9tention est calcul\u00E9e comme suit:\n\n* Toutes les op\u00E9rations qui \u00E9taient dans le portefeuille \u00E0 un moment donn\u00E9 au cours de la p\u00E9riode s\u00E9lectionn\u00E9e sont incluses.\n\n* La p\u00E9riode de d\u00E9tention de chaque titre d\u00E9coule du moment de l'achat et de la vente. Des ventes imm\u00E9diates sont suppos\u00E9es pour les positions actuellement d\u00E9tenues.\n\n* Le poids de la position est calcul\u00E9 \u00E0 partir du prix d'achat de la position par rapport au nombre total de tous les prix d'achat.\n\n* Le r\u00E9sultat \u00AB p\u00E9riode de d\u00E9tention moyenne de toutes les positions \u00BB est la somme des produits de \u00AB p\u00E9riode de d\u00E9tention * poids de position en pourcentage \u00BB pour toutes les positions. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties index ca8758ebe1..9dd3dbbd6a 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = Variazione percentuale della quotazione entro il ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Distanza da ATH +ColumnQuoteDistanceFromAthPercent = Distanza da ATH (prezzo) -ColumnQuoteDistanceFromAthPercent_Description = Distanza percentuale dall'ultimo All Time High (ATH) nel periodo scelto. +ColumnQuoteDistanceFromAthPercent_Description = Distanza percentuale dall'ultimo All Time High (ATH) basato sul prezzo nel periodo scelto. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1189,6 +1189,10 @@ LabelDelta = Delta (per periodo di riferimento) LabelDescription = Descrizione +LabelDistanceFromATHPrice = Sicurezza: Distanza da ATH (Prezzo) + +LabelDistanceFromATHPerformance = Distanza da ATH (prestazioni) + LabelDividendPerShare = dividendo pagato per azione LabelDividends = Dividendi @@ -2193,8 +2197,6 @@ SecurityListFilter = Filtra titoli SecurityListFilterDateReached = Titoli: data raggiunta -SecurityListFilterDistanceFromAth = Sicurezza: Distanza da ATH - SecurityListFilterHideInactive = Solo strumenti attivi SecurityListFilterLimitPriceExceeded = Titoli: Prezzo limite superato @@ -2381,7 +2383,9 @@ TabTransactions = Operazioni TitlePasswordDialog = Assegna password -TooltipAllTimeHigh = Massimo storico (ATH) negli ultimi {0} giorni: {2} ({1})\nPrezzo attuale del titolo: {3} ({4}) +TooltipAllTimeHighPrice = Prezzo basato sul Massimo storico (ATH) negli ultimi {0} giorni: {3} ({1} giorni fa, il {2})\nPrezzo attuale del titolo: {4} ({5}) + +TooltipAllTimeHighPerformance = Prestazioni basato sul Massimo storico (ATH) negli ultimi {0} giorni: {1} giorni fa, il {2} TooltipAverageHoldingPeriod = Il periodo medio di detenzione \u00E8 calcolato come segue:\n\n* Sono incluse tutte le operazioni che erano in portafoglio in un certo momento durante il periodo di riferimento selezionato.\n\n* Il periodo di detenzione di ciascun titolo risulta dal momento dell'acquisto e la vendita. Per le posizioni attualmente ricoperte si ipotizzano vendite immediate.\n\n* Il peso della posizione viene calcolato dal prezzo d'acquisto della posizione rispetto al numero totale di tutti i prezzi d'acquisto.\n\n* Risultato "periodo di detenzione medio di tutte le posizioni" \u00E8 la somma dei prodotti "periodo di detenzione * peso posizione percentuale" in tutte le posizioni. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties index b5d034556e..84537b2838 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = Percentageverandering van de koers binnen de geg ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Afstand van ATH +ColumnQuoteDistanceFromAthPercent = Afstand van ATH (prijs) -ColumnQuoteDistanceFromAthPercent_Description = Percentage afstand tot de laatste All Time High (ATH) in de gekozen periode. +ColumnQuoteDistanceFromAthPercent_Description = Percentage afstand tot de laatste koersgebaseerde All Time High (ATH) in de gekozen periode. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1185,6 +1185,10 @@ LabelDelta = Delta (voor rapportageperiode) LabelDescription = Beschrijving +LabelDistanceFromATHPrice = Veiligheid: Afstand van ATH (Prijs) + +LabelDistanceFromATHPerformance = Afstand van ATH (Prestaties) + LabelDividendPerShare = dividendbetaling per aandeel LabelDividends = Dividenden @@ -2183,8 +2187,6 @@ SecurityListFilter = Effecten filteren SecurityListFilterDateReached = Effecten: datum bereikt -SecurityListFilterDistanceFromAth = Veiligheid: Afstand van ATH - SecurityListFilterHideInactive = Alleen actieve instrumenten SecurityListFilterLimitPriceExceeded = Effecten: Limietprijs overschreden @@ -2371,7 +2373,9 @@ TabTransactions = Transacties TitlePasswordDialog = Wachtwoord toewijzen -TooltipAllTimeHigh = All-Time High (ATH) in de laatste {0} dagen: {2} ({1})\nHuidige effectenprijs: {3} ({4}) +TooltipAllTimeHighPrice = Koers gebaseerd op All-Time High (ATH) in de laatste {0} dagen: {3} ({1} dagen geleden, op {2})\nHuidige effectenprijs: {4} ({5}) + +TooltipAllTimeHighPerformance = Prestaties gebaseerd op All-Time High (ATH) in de laatste {0} dagen: {1} dagen geleden, op {2} TooltipAverageHoldingPeriod = De gemiddelde bewaarperiode wordt als volgt berekend:\n\n* Alle transacties zijn opgenomen die op enig moment in de portefeuille waren binnen de geselecteerde rapportageperiode.\n\n* De bewaartermijn van elk effect vloeit voort uit het moment van aankoop en verkoop. Onmiddellijke verkopen worden verondersteld voor de huidige posities.\n\n* Het positiegewicht wordt berekend op basis van de inkoopprijs van de positie ten opzichte van het totale aantal van alle inkoopprijzen.\n\n* Resultaat "gemiddelde bewaarperiode van alle posities" is de som van de producten "bewaarperiode * percentage positiegewicht" voor alle posities. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties index 0df886cbc8..da30e6ec17 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = Altera\u00E7\u00E3o percentual da cota\u00E7\u00 ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = Dist\u00E2ncia da ATH +ColumnQuoteDistanceFromAthPercent = Dist\u00E2ncia da ATH (pre\u00E7o) -ColumnQuoteDistanceFromAthPercent_Description = Percentagem da dist\u00E2ncia do \u00FAltimo "All Time High" (ATH) no per\u00EDodo escolhido. +ColumnQuoteDistanceFromAthPercent_Description = Percentagem da dist\u00E2ncia do \u00FAltimo pre\u00E7o baseado no All Time High (ATH) no per\u00EDodo escolhido. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1187,6 +1187,10 @@ LabelDelta = Delta (para o per\u00EDodo do relat\u00F3rio) LabelDescription = Descri\u00E7\u00E3o +LabelDistanceFromATHPrice = Seguran\u00E7a: Dist\u00E2ncia da ATH (Pre\u00E7o) + +LabelDistanceFromATHPerformance = Seguran\u00E7a: Dist\u00E2ncia da ATH (Performance) + LabelDividendPerShare = pagamento de dividendos por a\u00E7\u00E3o LabelDividends = Dividendos @@ -2189,8 +2193,6 @@ SecurityListFilter = Filtrar ativos SecurityListFilterDateReached = T\u00EDtulos: data alcan\u00E7ada -SecurityListFilterDistanceFromAth = Seguran\u00E7a: Dist\u00E2ncia da ATH - SecurityListFilterHideInactive = Apenas instrumentos ativos SecurityListFilterLimitPriceExceeded = T\u00EDtulos: Limite de pre\u00E7o excedido @@ -2377,7 +2379,9 @@ TabTransactions = Transa\u00E7\u00F5es TitlePasswordDialog = Atribuir senha -TooltipAllTimeHigh = All-Time High (ATH) nos \u00FAltimos {0} dias: {2} ({1})\nPre\u00E7o actual dos t\u00EDtulos: {3} ({4}) +TooltipAllTimeHighPrice = Pre\u00E7o com base no tempo todo (ATH) nos \u00FAltimos {0} dias: {3} ({1} dias atr\u00E1s, em {2})\nPre\u00E7o actual dos t\u00EDtulos: {4} ({5}) + +TooltipAllTimeHighPerformance = Desempenho com base no tempo todo (ATH) nos \u00FAltimos {0} dias: {1} dias atr\u00E1s, em {2} TooltipAverageHoldingPeriod = O per\u00EDodo m\u00E9dio de cust\u00F3dia \u00E9 calculado da seguinte forma:\n\n* Todas as negocia\u00E7\u00F5es inclu\u00EDdas no portf\u00F3lio em algum momento do per\u00EDodo de relat\u00F3rio selecionado.\n\n* O per\u00EDodo de reten\u00E7\u00E3o de cada ativo resulta do momento da compra e venda. Vendas imediatas s\u00E3o assumidas para as posi\u00E7\u00F5es atualmente custodiadas.\n\n* O peso da posi\u00E7\u00E3o \u00E9 calculado a partir do pre\u00E7o de compra da posi\u00E7\u00E3o em rela\u00E7\u00E3o ao n\u00FAmero total de todos os pre\u00E7os de compra.\n\n* O resultado "per\u00EDodo m\u00E9dio de cust\u00F3dia de todas as posi\u00E7\u00F5es" \u00E9 a soma do produto "per\u00EDodo de cust\u00F3dia * peso percentual da posi\u00E7\u00E3o" em todas as posi\u00E7\u00F5es. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties index 19ba5dd298..eec71ab007 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties @@ -581,9 +581,9 @@ ColumnQuoteChange_Description = \u041F\u0440\u043E\u0446\u0435\u043D\u0442\u043D ColumnQuoteChange_Option = \u0394 {0} -ColumnQuoteDistanceFromAthPercent = \u0420\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 ATH +ColumnQuoteDistanceFromAthPercent = \u0420\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 ATH (\u0446\u0435\u043D\u0430) -ColumnQuoteDistanceFromAthPercent_Description = \u041F\u0440\u043E\u0446\u0435\u043D\u0442\u043D\u043E\u0435 \u0440\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E All Time High (ATH) \u0437\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043F\u0435\u0440\u0438\u043E\u0434. +ColumnQuoteDistanceFromAthPercent_Description = \u041F\u0440\u043E\u0446\u0435\u043D\u0442\u043D\u043E\u0435 \u0440\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0446\u0435\u043D\u043E\u0432\u043E\u0433\u043E \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C\u0430 All Time High (ATH) \u0437\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043F\u0435\u0440\u0438\u043E\u0434. ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % @@ -1189,6 +1189,10 @@ LabelDelta = \u0414\u0435\u043B\u044C\u0442\u0430 (\u0437\u0430 \u043E\u0442\u04 LabelDescription = \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 +LabelDistanceFromATHPrice = \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C: \u0420\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 ATH (\u0446\u0435\u043D\u0430) + +LabelDistanceFromATHPerformance = \u0420\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 ATH (\u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C) + LabelDividendPerShare = \u0432\u044B\u043F\u043B\u0430\u0442\u0430 \u0434\u0438\u0432\u0438\u0434\u0435\u043D\u0434\u043E\u0432 \u043F\u043E \u0430\u043A\u0446\u0438\u044F\u043C LabelDividends = \u0414\u0438\u0432\u0438\u0434\u0435\u043D\u0434\u044B @@ -2191,8 +2195,6 @@ SecurityListFilter = \u0424\u0438\u043B\u044C\u0442\u0440 \u0446\u0435\u043D\u04 SecurityListFilterDateReached = \u0410\u043A\u0442\u0438\u0432\u044B: \u0434\u0430\u0442\u0430 \u0434\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442\u0430 -SecurityListFilterDistanceFromAth = \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C: \u0420\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043E\u0442 ATH - SecurityListFilterHideInactive = \u0422\u043E\u043B\u044C\u043A\u043E \u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B SecurityListFilterLimitPriceExceeded = \u0426\u0435\u043D\u043D\u044B\u0435 \u0431\u0443\u043C\u0430\u0433\u0438: \u043F\u0440\u0435\u0432\u044B\u0448\u0435\u043D\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044C\u043D\u0430\u044F \u0446\u0435\u043D\u0430 @@ -2379,7 +2381,9 @@ TabTransactions = \u0422\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0438 TitlePasswordDialog = \u041D\u0430\u0437\u043D\u0430\u0447\u0438\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C -TooltipAllTimeHigh = All-Time High (ATH) \u0437\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 {0} \u0434\u043D\u0435\u0439: {2} ({1})\n\u0422\u0435\u043A\u0443\u0449\u0430\u044F \u0446\u0435\u043D\u0430 \u0446\u0435\u043D\u043D\u043E\u0439 \u0431\u0443\u043C\u0430\u0433\u0438: {3} ({4}) +TooltipAllTimeHighPrice = \u0426\u0435\u043D\u0430 \u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0435 All-Time High (ATH) \u0437\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 {0} \u0434\u043D\u0435\u0439: {3} ({1} \u0434\u043D\u0435\u0439 \u043D\u0430\u0437\u0430\u0434, \u043D\u0430 {2})\n\u0422\u0435\u043A\u0443\u0449\u0430\u044F \u0446\u0435\u043D\u0430 \u0446\u0435\u043D\u043D\u043E\u0439 \u0431\u0443\u043C\u0430\u0433\u0438: {4} ({5}) + +TooltipAllTimeHighPerformance = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0435\u043B\u044C All-Time High (ATH) \u0437\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 {0} \u0434\u043D\u0435\u0439: {1} \u0434\u043D\u0435\u0439 \u043D\u0430\u0437\u0430\u0434, \u043D\u0430 {2} TooltipAverageHoldingPeriod = \u0421\u0440\u0435\u0434\u043D\u0438\u0439 \u043F\u0435\u0440\u0438\u043E\u0434 \u0432\u043B\u0430\u0434\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u043C \u043E\u0431\u0440\u0430\u0437\u043E\u043C:\n\n* \u0412\u043A\u043B\u044E\u0447\u0430\u044E\u0442\u0441\u044F \u0432\u0441\u0435 \u0441\u0434\u0435\u043B\u043A\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0431\u044B\u043B\u0438 \u0432 \u043F\u043E\u0440\u0442\u0444\u0435\u043B\u0435 \u0432 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0439 \u043C\u043E\u043C\u0435\u043D\u0442 \u0432 \u0442\u0435\u0447\u0435\u043D\u0438\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u043E\u0442\u0447\u0435\u0442\u043D\u043E\u0433\u043E \u043F\u0435\u0440\u0438\u043E\u0434\u0430.\n\n* \u041F\u0435\u0440\u0438\u043E\u0434 \u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F \u043A\u0430\u0436\u0434\u043E\u0439 \u0446\u0435\u043D\u043D\u043E\u0439 \u0431\u0443\u043C\u0430\u0433\u0438 \u043D\u0430\u0447\u0438\u043D\u0430\u0435\u0442\u0441\u044F \u0441 \u043C\u043E\u043C\u0435\u043D\u0442\u0430 \u043F\u043E\u043A\u0443\u043F\u043A\u0438 \u0438 \u0434\u043E \u0435\u0451 \u043F\u0440\u043E\u0434\u0430\u0436\u0438. \u041F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u044E\u0442\u0441\u044F \u043D\u0435\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0435 \u043F\u0440\u043E\u0434\u0430\u0436\u0438 \u043F\u043E \u043F\u043E\u0437\u0438\u0446\u0438\u044F\u043C, \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u043C\u044B\u043C \u0432 \u043D\u0430\u0441\u0442\u043E\u044F\u0449\u0435\u0435 \u0432\u0440\u0435\u043C\u044F.\n\n* \u0412\u0435\u0441 \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0438\u0441\u0445\u043E\u0434\u044F \u0438\u0437 \u0446\u0435\u043D\u044B \u043F\u043E\u043A\u0443\u043F\u043A\u0438 \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043E\u0431\u0449\u0435\u0433\u043E \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0441\u0435\u0445 \u0446\u0435\u043D \u043F\u043E\u043A\u0443\u043F\u043A\u0438.\n\n* \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 "\u0441\u0440\u0435\u0434\u043D\u0438\u0439 \u043F\u0435\u0440\u0438\u043E\u0434 \u0443\u0434\u0435\u0440\u0436\u0430\u043D\u0438\u044F \u0432\u0441\u0435\u0445 \u043F\u043E\u0437\u0438\u0446\u0438\u0439" - \u044D\u0442\u043E \u0441\u0443\u043C\u043C\u0430 \u043F\u0440\u043E\u0434\u0443\u043A\u0442\u043E\u0432 "\u043F\u0435\u0440\u0438\u043E\u0434 \u0443\u0434\u0435\u0440\u0436\u0430\u043D\u0438\u044F * \u043F\u0440\u043E\u0446\u0435\u043D\u0442\u043D\u044B\u0439 \u0432\u0435\u0441 \u043F\u043E\u0437\u0438\u0446\u0438\u0438" \u043F\u043E \u0432\u0441\u0435\u043C \u043F\u043E\u0437\u0438\u0446\u0438\u044F\u043C. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties index 74d57d0230..292e500014 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties @@ -579,6 +579,12 @@ ColumnQuoteChange_Description = Percentu\u00E1lna zmena kot\u00E1cie v danom obd ColumnQuoteChange_Option = \u0394 {0} +ColumnQuoteDistanceFromAthPercent = Vzdialenos\u0165 od ATH (cena) + +ColumnQuoteDistanceFromAthPercent_Description = Percentu\u00E1lna vzdialenos\u0165 od posledn\u00E9ho cenov\u00E9ho All Time High (ATH) vo zvolenom obdob\u00ED. + +ColumnQuoteDistanceFromAthPercent_Option = \u0394 ATH {0} % + ColumnQuoteFeedHistoric = Poskytovate\u013E kurzov (historick\u00E9) ColumnQuoteFeedLatest = Poskytovate\u013E kurzov (najnov\u0161ie) @@ -825,6 +831,10 @@ GroupLabelAttributes = Atrib\u00FAty GroupLabelDataQuality = Kvalita \u00FAdajov +LabelDistanceFromATHPrice = Bezpe\u010Dnos\u0165: Vzdialenos\u0165 od ATH (cena) + +LabelDistanceFromATHPerformance = Vzdialenos\u0165 od ATH (v\u00FDkon) + GroupLabelDividends = Dividendy GroupLabelPerformance = V\u00FDkon @@ -2353,7 +2363,9 @@ TabTransactions = Transakcie TitlePasswordDialog = Priradenie hesla -TooltipAllTimeHigh = All-Time High (ATH) za posledn\u00FDch {0} dn\u00ED: {2} ({1})\nAktu\u00E1lna cena cenn\u00E9ho papiera: {3} ({4}) +TooltipAllTimeHighPrice = Cenov\u00E9 maximum (ATH) za posledn\u00FDch {0} dn\u00ED: {3} (pred {1} d\u0148ami, d\u0148a {2})\nAktu\u00E1lna cena cenn\u00E9ho papiera: {4} ({5}) + +TooltipAllTimeHighPerformance = V\u00FDkonnostn\u00E9 maximum (ATH) za posledn\u00FDch {0} dn\u00ED: pred {1} d\u0148ami, d\u0148a {2} TooltipAverageHoldingPeriod = Priemern\u00E1 doba dr\u017Eby sa vypo\u010D\u00EDta takto:\n\n* Zahrnut\u00E9 s\u00FA v\u0161etky obchody, ktor\u00E9 boli v portf\u00F3liu v ur\u010Ditom okamihu v r\u00E1mci vybran\u00E9ho vykazovan\u00E9ho obdobia.\n\n* Doba dr\u017Eby ka\u017Ed\u00E9ho cenn\u00E9ho papiera vypl\u00FDva z \u010Dasu n\u00E1kupu a predaja. Pri aktu\u00E1lne dr\u017Ean\u00FDch poz\u00EDci\u00E1ch sa predpoklad\u00E1 okam\u017Eit\u00FD predaj.\n\n* V\u00E1ha poz\u00EDcie sa vypo\u010D\u00EDta z n\u00E1kupnej ceny poz\u00EDcie vzh\u013Eadom na celkov\u00FD po\u010Det v\u0161etk\u00FDch n\u00E1kupn\u00FDch cien.\n\n* V\u00FDsledok "priemern\u00E1 doba dr\u017Eby v\u0161etk\u00FDch poz\u00EDci\u00ED" je s\u00FA\u010Dtom s\u00FA\u010Dinov "doba dr\u017Eby * percentu\u00E1lna v\u00E1ha poz\u00EDcie" vo v\u0161etk\u00FDch poz\u00EDci\u00E1ch. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/columns/DistanceFromAllTimeHighColumn.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/columns/DistanceFromAllTimeHighColumn.java index 744e42684e..15aab61502 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/columns/DistanceFromAllTimeHighColumn.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/columns/DistanceFromAllTimeHighColumn.java @@ -7,7 +7,7 @@ import org.eclipse.swt.SWT; -import name.abuchen.portfolio.math.AllTimeHigh; +import name.abuchen.portfolio.math.AllTimeHighPrice; import name.abuchen.portfolio.model.Adaptor; import name.abuchen.portfolio.model.Security; import name.abuchen.portfolio.snapshot.ReportingPeriod; @@ -51,7 +51,7 @@ public DistanceFromAllTimeHighColumn(Supplier dateProvider, List IndicatorWidget.create(widget, data) // .with(Values.Percent2) // .with((ds, period) -> { @@ -297,7 +302,7 @@ public enum WidgetFactory Security security = (Security) ds.getInstance(); - Double distance = new AllTimeHigh(security, period).getDistance(); + Double distance = new AllTimeHighPrice(security, period).getDistance(); if (distance == null) return (double) 0; @@ -311,12 +316,14 @@ public enum WidgetFactory return null; Security security = (Security) ds.getInstance(); - AllTimeHigh ath = new AllTimeHigh(security, period); + AllTimeHighPrice ath = new AllTimeHighPrice(security, period); if (ath.getValue() == null) return null; - return MessageFormat.format(Messages.TooltipAllTimeHigh, - period.getDays(), Values.Date.format(ath.getDate()), + return MessageFormat.format(Messages.TooltipAllTimeHighPrice, + period.getDays(), + ChronoUnit.DAYS.between(ath.getDate(), LocalDate.now()), + Values.Date.format(ath.getDate()), ath.getValue() / Values.Quote.divider(), security.getSecurityPrice(LocalDate.now()).getValue() / Values.Quote.divider(), @@ -325,6 +332,30 @@ public enum WidgetFactory }) // .build()), + DISTANCE_TO_ATH_PERFORMANCE(Messages.LabelDistanceFromATHPerformance, Messages.ClientEditorLabelPerformance, // + (widget, data) -> IndicatorWidget.create(widget, data) // + .with(Values.Percent2) // + .with((ds, period) -> { + PerformanceIndex index = data.calculate(ds, period); + OptionalDouble distance = new AllTimeHighPerformance(index).getDistance(); + return distance.orElse(0); + }) // + .withBenchmarkDataSeries(false) // + .withColoredValues(false) // + .withTooltip((ds, period) -> { + PerformanceIndex index = data.calculate(ds, period); + AllTimeHighPerformance ath = new AllTimeHighPerformance(index); + Optional optionalDate = ath.getDate(); + if (optionalDate.isEmpty()) + return null; + + return MessageFormat.format(Messages.TooltipAllTimeHighPerformance, + period.getDays(), + ChronoUnit.DAYS.between(optionalDate.get(), LocalDate.now()), + Values.Date.format(optionalDate.get())); + }) // + .build()), + // typo is API now!! VERTICAL_SPACEER(Messages.LabelVerticalSpacer, Messages.LabelCommon, VerticalSpacerWidget::new); diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPerformance.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPerformance.java new file mode 100644 index 0000000000..ef62965693 --- /dev/null +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPerformance.java @@ -0,0 +1,60 @@ +package name.abuchen.portfolio.math; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.OptionalDouble; + +import name.abuchen.portfolio.snapshot.PerformanceIndex; + +public class AllTimeHighPerformance +{ + private PerformanceIndex performanceIndex; + private OptionalDouble athDistanceInPercent; + private Optional athDate; + + public AllTimeHighPerformance(PerformanceIndex index) + { + this.performanceIndex = index; + athDistanceInPercent = OptionalDouble.empty(); + athDate = Optional.empty(); + + this.calculate(); + } + + private void calculate() + { + if (performanceIndex == null) + return; + + double[] accumulatedPercentage = performanceIndex.getAccumulatedPercentage(); + LocalDate[] dates = performanceIndex.getDates(); + OptionalDouble max = OptionalDouble.empty(); + + for(int i = 0; i < accumulatedPercentage.length; i++) + { + accumulatedPercentage[i] += 1d; + if(max.isEmpty() || accumulatedPercentage[i] >= max.getAsDouble()) + { + max = OptionalDouble.of(accumulatedPercentage[i]); + athDate = Optional.of(dates[i]); + } + } + + if (max.isEmpty()) + return; + + double latest = accumulatedPercentage[accumulatedPercentage.length - 1]; + + this.athDistanceInPercent = OptionalDouble.of((latest - max.getAsDouble()) / max.getAsDouble()); + } + + public OptionalDouble getDistance() + { + return this.athDistanceInPercent; + } + + public Optional getDate() + { + return athDate; + } +} diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPrice.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPrice.java new file mode 100644 index 0000000000..79bc4549a6 --- /dev/null +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/math/AllTimeHighPrice.java @@ -0,0 +1,61 @@ +package name.abuchen.portfolio.math; + +import java.time.LocalDate; +import java.util.Comparator; +import java.util.Objects; +import java.util.Optional; + +import name.abuchen.portfolio.model.Security; +import name.abuchen.portfolio.model.SecurityPrice; +import name.abuchen.portfolio.util.Interval; + +public class AllTimeHighPrice +{ + private Security security; + private Interval interval; + private Long athValue; + private LocalDate athDate; + private Double athDistanceInPercent; + + public AllTimeHighPrice(Security security, Interval interval) + { + this.security = security; + this.interval = Objects.requireNonNull(interval); + + this.calculate(); + } + + private void calculate() + { + if (security == null || interval == null) + return; + + Optional max = security.getPricesIncludingLatest().stream() // + .filter(p -> interval.contains(p.getDate())) // + .max(Comparator.comparing(SecurityPrice::getValue)); + + if (!max.isPresent()) + return; + + SecurityPrice latest = security.getSecurityPrice(interval.getEnd()); + + this.athValue = max.get().getValue(); + this.athDate = max.get().getDate(); + this.athDistanceInPercent = (latest.getValue() - max.get().getValue()) / (double) max.get().getValue(); + } + + public Long getValue() + { + return this.athValue; + } + + public Double getDistance() + { + return this.athDistanceInPercent; + } + + public LocalDate getDate() + { + return this.athDate; + } +}