Skip to content

Commit

Permalink
Merge branch 'feature_risk_metrics'
Browse files Browse the repository at this point in the history
  • Loading branch information
buchen committed Feb 8, 2015
2 parents 7aaf54e + 5eed282 commit 7eff36f
Show file tree
Hide file tree
Showing 18 changed files with 749 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_on_off_tags=true
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
Expand Down Expand Up @@ -99,6 +100,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
Expand Down Expand Up @@ -146,6 +148,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
Expand Down Expand Up @@ -223,6 +226,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
Expand Down Expand Up @@ -285,7 +289,7 @@ org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_on_off_tags=true
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package name.abuchen.portfolio.math;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.number.IsCloseTo.closeTo;
import static org.junit.Assert.assertThat;

import java.util.Arrays;
import java.util.Date;

import name.abuchen.portfolio.math.Risk.Drawdown;
import name.abuchen.portfolio.math.Risk.Volatility;
import name.abuchen.portfolio.util.Dates;

import org.junit.Test;

public class RiskTest
{

private Date[] getDates(int size)
{
Date[] dates = new Date[size];
for (int i = 0; i < size; i++)
dates[i] = Dates.date(2015, 1, i + 1);
return dates;
}

@Test
public void testDrawdown()
{
int size = 10;
Date[] dates = getDates(size);
double[] values = new double[size];
for (int i = 0; i < size; i++)
values[i] = i;

Drawdown drawdown = new Drawdown(values, dates);
// Every new value is a new peak, so there never is a drawdown and
// therefore the magnitude is 0
assertThat(drawdown.getMaxDrawdown(), is(0d));
// Drawdown duration is the longest duration between peaks. Every value
// is a peak, so 1 day is every time the duration. The fact that there
// is never a drawdown does not negate the duration
assertThat(drawdown.getMaxDrawdownDuration().getDays(), is(1l));

drawdown = new Drawdown(new double[] { 1, 1, -0.5, 1, 1, 2, 3, 4, 5, 6 }, dates);
// the drawdown is from 2 to 0.5 which is 1.5 or 75% of 2
assertThat(drawdown.getMaxDrawdown(), is(0.75d));
// the first peak is the first 2. The second 2 is not a peak, the next
// peak is the 3, which is 5 days later
assertThat(drawdown.getMaxDrawdownDuration().getDays(), is(5l));

drawdown = new Drawdown(new double[] { 0, 0.1, 0.2, -1.4 }, getDates(4));
// The drawdown is from 1.2 to -0.4 or 1.6, which is 4/3 from 1.2
assertThat(drawdown.getMaxDrawdown(), closeTo(4d / 3, 0.1e-10));
}

@Test
public void testVolatility()
{
double[] delta = new double[] { 0.5, -1 / 3d, -0.5, 1, 1, -0.5 };
Volatility volatility = new Volatility(getDates(delta.length), delta, 0, d -> true);
// returns are 0.5, -1/3, -0.5, 1, 1, -0.5 with an average of 7/36
// the deviation from the average is 11/36 for 0.5, 19/36 for -1/3 and
// so on each of these deviations is squared and the sum divided by the
// number of returns (6) the resulting division is
// root((121+1250+1682+361)/(1296*6)) or 3414/7776
assertThat(volatility.getStandardDeviation(), closeTo(Math.sqrt(3414d / 7776), 0.1e-10));

// for semi deviation, only the returns lower than the average are
// counted so only the -1/3 and the two times -0.5
// root((361+1250)/(1296*3)) or 1611/3888
assertThat(volatility.getSemiDeviation(), closeTo(Math.sqrt(1611d / 3888), 0.1e-10));
}

@Test
public void testVolatilityWithSkip()
{
double[] delta = new double[] { 0, 0.5, -1 / 3d, -0.5, 1, 1, -0.5 };
Volatility volatility = new Volatility(getDates(delta.length), delta, 1, d -> true);
assertThat(volatility.getStandardDeviation(), closeTo(Math.sqrt(3414d / 7776), 0.1e-10));
assertThat(volatility.getSemiDeviation(), closeTo(Math.sqrt(1611d / 3888), 0.1e-10));
}

@Test
public void testVolatilityWithConstantReturns()
{
double[] returns = new double[20];
Arrays.fill(returns, 0.1);

Volatility volatility = new Volatility(getDates(returns.length), returns, 0, d -> true);
assertThat(volatility.getStandardDeviation(), closeTo(0d, 0.1e-10));
assertThat(volatility.getSemiDeviation(), closeTo(0d, 0.1e-10));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package name.abuchen.portfolio.snapshot;

import static org.hamcrest.number.IsCloseTo.closeTo;
import static org.junit.Assert.assertThat;

import java.util.Date;

import name.abuchen.portfolio.math.RiskTest;
import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.util.Dates;

import org.junit.Test;

@SuppressWarnings("nls")
public class PerformanceIndexTest
{

private final class PerformanceIndexStub extends PerformanceIndex
{
private PerformanceIndexStub(Date[] dates, long[] totals, double[] delta)
{
super(new Client(), new ReportingPeriod.LastX(1, 0));

this.dates = dates;
this.totals = totals;
this.delta = delta;
}
}

/**
* Companion test for basic volatility {@link RiskTest#testVolatility()}
*/
@Test
public void testVolatilityFromPerformanceIndex()
{
Date[] dates = new Date[] { Dates.date("2015-02-02"), Dates.date("2015-02-03"), Dates.date("2015-02-04"),
Dates.date("2015-02-05"), Dates.date("2015-02-06"), Dates.date("2015-02-07") /* weekend */,
Dates.date("2015-02-08") /* weekend */, Dates.date("2015-02-09"), Dates.date("2015-02-10") };
long[] totals = new long[] { 1000, 1500, 1000, 500, 1000, 1000, 1000, 2000, 1000 };
double[] delta = new double[] { 0, 0.5, -1 / 3d, -0.5, 1, 0, 0, 1, -0.5 };

PerformanceIndex index = new PerformanceIndexStub(dates, totals, delta);

assertThat(index.getVolatility().getStandardDeviation(), closeTo(Math.sqrt(3414d / 7776), 0.1e-10));
assertThat(index.getVolatility().getSemiDeviation(), closeTo(Math.sqrt(1611d / 3888), 0.1e-10));
}

@Test
public void testVolatilityWithFirstDataPointLater()
{
Date[] dates = new Date[] { Dates.date("2015-02-02"), Dates.date("2015-02-03"), Dates.date("2015-02-04"),
Dates.date("2015-02-05"), Dates.date("2015-02-06"), Dates.date("2015-02-07") /* weekend */,
Dates.date("2015-02-08") /* weekend */, Dates.date("2015-02-09"), Dates.date("2015-02-10"),
Dates.date("2015-02-11"), Dates.date("2015-02-12") };
long[] totals = new long[] { 0, 0, 1000, 1500, 1000, 1000, 1000, 500, 1000, 2000, 1000 };
double[] delta = new double[] { 0, 0, 0, 0.5, -1 / 3d, 0, 0, -0.5, 1, 1, -0.5 };

PerformanceIndex index = new PerformanceIndexStub(dates, totals, delta);

assertThat(index.getVolatility().getStandardDeviation(), closeTo(Math.sqrt(3414d / 7776), 0.1e-10));
assertThat(index.getVolatility().getSemiDeviation(), closeTo(Math.sqrt(1611d / 3888), 0.1e-10));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package name.abuchen.portfolio.util;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;

@SuppressWarnings("nls")
public class TradeCalendarTest
{

@Test
public void testEasterHolidays()
{
TradeCalendar calendar = new TradeCalendar();

assertThat(calendar.isHoldiay(Dates.date("2015-04-02")), is(false));
assertThat(calendar.isHoldiay(Dates.date("2015-04-03")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-04-04")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-04-05")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-04-06")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-04-07")), is(false));

assertThat(calendar.isHoldiay(Dates.date("2016-03-25")), is(true));
}

@Test
public void testWeekends()
{
TradeCalendar calendar = new TradeCalendar();

assertThat(calendar.isHoldiay(Dates.date("2015-01-31")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-02-01")), is(true));
}

@Test
public void testFixedPublicHolidays()
{
TradeCalendar calendar = new TradeCalendar();

assertThat(calendar.isHoldiay(Dates.date("2015-01-01")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-05-01")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-12-24")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-12-25")), is(true));
assertThat(calendar.isHoldiay(Dates.date("2015-12-26")), is(true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
Expand Down Expand Up @@ -99,6 +100,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
Expand Down Expand Up @@ -146,6 +148,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
Expand Down Expand Up @@ -223,6 +226,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
Expand Down Expand Up @@ -285,7 +289,7 @@ org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_on_off_tags=true
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
Expand Down
1 change: 1 addition & 0 deletions name.abuchen.portfolio.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Import-Package: de.engehausen.treemap,
javax.inject;version="1.0.0",
name.abuchen.portfolio.checks,
name.abuchen.portfolio.datatransfer,
name.abuchen.portfolio.math,
name.abuchen.portfolio.model,
name.abuchen.portfolio.online,
name.abuchen.portfolio.online.impl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,16 @@ public class Messages extends NLS
public static String LabelReportingDialogYears;
public static String LabelReportingYears;
public static String LabelReportInterval;
public static String LabelRiskIndicators;
public static String LabelSampleData;
public static String LabelSearch;
public static String LabelSecurities;
public static String LabelSecurityPerformance;
public static String LabelSemiVolatility;
public static String LabelDividends;
public static String LabelKeyIndicators;
public static String LabelMaxDrawdown;
public static String LabelMaxDrawdownDuration;
public static String LabelStatementOfAssets;
public static String LabelStatementOfAssetsHistory;
public static String LabelStatementOfAssetsHoldings;
Expand All @@ -318,7 +322,9 @@ public class Messages extends NLS
public static String LabelViewStackedChart;
public static String LabelViewTaxonomyDefinition;
public static String LabelViewTreeMap;
public static String LabelVolatility;
public static String LabelWithoutClassification;
public static String LabelXDays;
public static String LabelYes;
public static String MenuAddAll;
public static String MenuChartAdjustRange;
Expand Down Expand Up @@ -474,6 +480,10 @@ public class Messages extends NLS
public static String SystemMenuCheckForUpdates;
public static String TabTransactions;
public static String TitlePasswordDialog;
public static String TooltipMaxDrawdown;
public static String TooltipMaxDrawdownDuration;
public static String TooltipSemiVolatility;
public static String TooltipVolatility;
public static String WatchlistDelete;
public static String WatchlistEditDialog;
public static String WatchlistEditDialogMsg;
Expand Down
Loading

0 comments on commit 7eff36f

Please sign in to comment.