-
Notifications
You must be signed in to change notification settings - Fork 614
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
moved security timeliness calculations into separate model and added …
…unit tests, added new configuration tab for quotes and moved existing config setting to update quotes on startup there, included list of stale securities into tooltip
- Loading branch information
Showing
8 changed files
with
246 additions
and
24 deletions.
There are no files selected for viewing
120 changes: 120 additions & 0 deletions
120
name.abuchen.portfolio.tests/src/name/abuchen/portfolio/util/SecurityTimelinessTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package name.abuchen.portfolio.util; | ||
|
||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import java.time.Clock; | ||
import java.time.LocalDate; | ||
import java.time.ZoneId; | ||
|
||
import org.junit.Test; | ||
|
||
import name.abuchen.portfolio.model.LatestSecurityPrice; | ||
import name.abuchen.portfolio.model.Security; | ||
|
||
@SuppressWarnings("nls") | ||
public class SecurityTimelinessTest | ||
{ | ||
private static final LocalDate LOCAL_DATE = LocalDate.of(2020, 5, 6); | ||
private Clock clock; | ||
|
||
public SecurityTimelinessTest() | ||
{ | ||
this.clock = Clock.fixed(LOCAL_DATE.atStartOfDay(ZoneId.systemDefault()).toInstant(), ZoneId.systemDefault()); | ||
} | ||
|
||
@Test | ||
public void testStaleIfNoLatestFeed() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertTrue(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testNotStaleIfRetired() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(true); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertFalse(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testStaleIfNotUpdatedWithin8DaysWith1HolidayAndWeekend() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 4, 23), 10)); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertTrue(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testNotStaleIfNotUpdatedWithin7DaysWith1HolidayAndWeekend() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 4, 24), 10)); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertFalse(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testNotStaleIfUpdatedToday() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 5, 6), 10)); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertFalse(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testNotStaleIfUpdatedYesterday() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 5, 5), 10)); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertFalse(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testStaleIfUpdatedYesterdayAndInterval0() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 5, 5), 10)); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 0, this.clock); | ||
|
||
assertTrue(st.isStale()); | ||
} | ||
|
||
@Test | ||
public void testNoHolidaysOrWeekendsIfSecurityHasNoCalendar() | ||
{ | ||
Security security = new Security(); | ||
security.setRetired(false); | ||
security.setLatest(new LatestSecurityPrice(LocalDate.of(2020, 4, 28), 10)); | ||
security.setCalendar("empty"); | ||
|
||
SecurityTimeliness st = new SecurityTimeliness(security, 7, this.clock); | ||
|
||
assertTrue(st.isStale()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
....abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/preferences/QuotesPreferencePage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package name.abuchen.portfolio.ui.preferences; | ||
|
||
import org.eclipse.jface.preference.BooleanFieldEditor; | ||
import org.eclipse.jface.preference.FieldEditorPreferencePage; | ||
import org.eclipse.jface.preference.IntegerFieldEditor; | ||
|
||
import name.abuchen.portfolio.ui.Messages; | ||
import name.abuchen.portfolio.ui.UIConstants; | ||
|
||
public class QuotesPreferencePage extends FieldEditorPreferencePage | ||
{ | ||
public QuotesPreferencePage() | ||
{ | ||
super(GRID); | ||
setTitle("Quotes"); | ||
} | ||
|
||
@Override | ||
public void createFieldEditors() | ||
{ | ||
addField(new BooleanFieldEditor(UIConstants.Preferences.UPDATE_QUOTES_AFTER_FILE_OPEN, // | ||
Messages.PrefUpdateQuotesAfterFileOpen, getFieldEditorParent())); | ||
|
||
addField(new IntegerFieldEditor(UIConstants.Preferences.QUOTES_STALE_AFTER_DAYS_PATH, | ||
"Number of days after a security price is not up-to-date anymore", | ||
getFieldEditorParent())); | ||
|
||
createNoteComposite(getFieldEditorParent().getFont(), getFieldEditorParent(), // | ||
Messages.PrefLabelNote, | ||
"After this amount of days a security price is marked as not up-to-date.\nPlease note that only days with open trade markets are considered\n(depends on the configured calendar for each security)"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
name.abuchen.portfolio/src/name/abuchen/portfolio/util/SecurityTimeliness.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package name.abuchen.portfolio.util; | ||
|
||
import java.time.Clock; | ||
import java.time.LocalDate; | ||
|
||
import name.abuchen.portfolio.model.Security; | ||
|
||
public final class SecurityTimeliness | ||
{ | ||
private Security security; | ||
private TradeCalendar tradeCalendar; | ||
private Clock clock; | ||
private int numberOfTradeDaysToLookBack; | ||
|
||
public SecurityTimeliness(Security security, int numberOfTradeDaysToLookBack, Clock clock) | ||
{ | ||
this.security = security; | ||
this.numberOfTradeDaysToLookBack = numberOfTradeDaysToLookBack; | ||
this.clock = clock; | ||
this.tradeCalendar = TradeCalendarManager.getInstance(security); | ||
} | ||
|
||
public boolean isStale() | ||
{ | ||
final LocalDate daysAgo = this.getStartDate(); | ||
|
||
return !this.security.isRetired() | ||
&& (this.security.getLatest() == null || this.security.getLatest().getDate().isBefore(daysAgo)); | ||
} | ||
|
||
private LocalDate getStartDate() | ||
{ | ||
LocalDate currentDay = LocalDate.now(this.clock); | ||
while (this.numberOfTradeDaysToLookBack > 0) | ||
{ | ||
currentDay = currentDay.minusDays(1); | ||
|
||
if (this.tradeCalendar.isHoliday(currentDay) || this.tradeCalendar.isWeekend(currentDay)) | ||
{ | ||
continue; | ||
} | ||
|
||
numberOfTradeDaysToLookBack--; | ||
} | ||
|
||
return currentDay; | ||
} | ||
} |