/** * The MIT License (MIT) * * Copyright (c) 2014-2017 Marc de Verdelhan & respective authors (see AUTHORS) * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package eu.verdelhan.ta4j.analysis; import eu.verdelhan.ta4j.Order; import static eu.verdelhan.ta4j.TATestsUtils.*; import eu.verdelhan.ta4j.Tick; import eu.verdelhan.ta4j.TimeSeries; import eu.verdelhan.ta4j.TradingRecord; import eu.verdelhan.ta4j.mocks.MockTick; import eu.verdelhan.ta4j.mocks.MockTimeSeries; import java.util.Collections; import static org.junit.Assert.*; import org.junit.Test; public class CashFlowTest { @Test public void cashFlowSize() { TimeSeries sampleTimeSeries = new MockTimeSeries(1d, 2d, 3d, 4d, 5d); CashFlow cashFlow = new CashFlow(sampleTimeSeries, new TradingRecord()); assertEquals(5, cashFlow.getSize()); } @Test public void cashFlowBuyWithOnlyOneTrade() { TimeSeries sampleTimeSeries = new MockTimeSeries(1d, 2d); TradingRecord tradingRecord = new TradingRecord(Order.buyAt(0), Order.sellAt(1)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 2); } @Test public void cashFlowWithSellAndBuyOrders() { TimeSeries sampleTimeSeries = new MockTimeSeries(2, 1, 3, 5, 6, 3, 20); TradingRecord tradingRecord = new TradingRecord( Order.buyAt(0), Order.sellAt(1), Order.buyAt(3), Order.sellAt(4), Order.sellAt(5), Order.buyAt(6)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), "0.5"); assertDecimalEquals(cashFlow.getValue(2), "0.5"); assertDecimalEquals(cashFlow.getValue(3), "0.5"); assertDecimalEquals(cashFlow.getValue(4), "0.6"); assertDecimalEquals(cashFlow.getValue(5), "0.6"); assertDecimalEquals(cashFlow.getValue(6), "0.09"); } @Test public void cashFlowSell() { TimeSeries sampleTimeSeries = new MockTimeSeries(1, 2, 4, 8, 16, 32); TradingRecord tradingRecord = new TradingRecord(Order.sellAt(2), Order.buyAt(3)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 1); assertDecimalEquals(cashFlow.getValue(2), 1); assertDecimalEquals(cashFlow.getValue(3), "0.5"); assertDecimalEquals(cashFlow.getValue(4), "0.5"); assertDecimalEquals(cashFlow.getValue(5), "0.5"); } @Test public void cashFlowShortSell() { TimeSeries sampleTimeSeries = new MockTimeSeries(1, 2, 4, 8, 16, 32); TradingRecord tradingRecord = new TradingRecord( Order.buyAt(0), Order.sellAt(2), Order.sellAt(2), Order.buyAt(4), Order.buyAt(4), Order.sellAt(5)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 2); assertDecimalEquals(cashFlow.getValue(2), 4); assertDecimalEquals(cashFlow.getValue(3), 2); assertDecimalEquals(cashFlow.getValue(4), 1); assertDecimalEquals(cashFlow.getValue(5), 2); } @Test public void cashFlowValueWithOnlyOneTradeAndAGapBefore() { TimeSeries sampleTimeSeries = new MockTimeSeries(1d, 1d, 2d); TradingRecord tradingRecord = new TradingRecord(Order.buyAt(1), Order.sellAt(2)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 1); assertDecimalEquals(cashFlow.getValue(2), 2); } @Test public void cashFlowValueWithOnlyOneTradeAndAGapAfter() { TimeSeries sampleTimeSeries = new MockTimeSeries(1d, 2d, 2d); TradingRecord tradingRecord = new TradingRecord(Order.buyAt(0), Order.sellAt(1)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertEquals(3, cashFlow.getSize()); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 2); assertDecimalEquals(cashFlow.getValue(2), 2); } @Test public void cashFlowValueWithTwoTradesAndLongTimeWithoutOrders() { TimeSeries sampleTimeSeries = new MockTimeSeries(1d, 2d, 4d, 8d, 16d, 32d); TradingRecord tradingRecord = new TradingRecord( Order.buyAt(1), Order.sellAt(2), Order.buyAt(4), Order.sellAt(5)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 1); assertDecimalEquals(cashFlow.getValue(2), 2); assertDecimalEquals(cashFlow.getValue(3), 2); assertDecimalEquals(cashFlow.getValue(4), 2); assertDecimalEquals(cashFlow.getValue(5), 4); } @Test public void cashFlowValue() { TimeSeries sampleTimeSeries = new MockTimeSeries(3d, 2d, 5d, 1000d, 5000d, 0.0001d, 4d, 7d, 6d, 7d, 8d, 5d, 6d); TradingRecord tradingRecord = new TradingRecord( Order.buyAt(0), Order.sellAt(2), Order.buyAt(6), Order.sellAt(8), Order.buyAt(9), Order.sellAt(11)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(0), 1); assertDecimalEquals(cashFlow.getValue(1), 2d/3); assertDecimalEquals(cashFlow.getValue(2), 5d/3); assertDecimalEquals(cashFlow.getValue(3), 5d/3); assertDecimalEquals(cashFlow.getValue(4), 5d/3); assertDecimalEquals(cashFlow.getValue(5), 5d/3); assertDecimalEquals(cashFlow.getValue(6), 5d/3); assertDecimalEquals(cashFlow.getValue(7), 5d/3 * 7d/4); assertDecimalEquals(cashFlow.getValue(8), 5d/3 * 6d/4); assertDecimalEquals(cashFlow.getValue(9), 5d/3 * 6d/4); assertDecimalEquals(cashFlow.getValue(10), 5d/3 * 6d/4 * 8d/7); assertDecimalEquals(cashFlow.getValue(11), 5d/3 * 6d/4 * 5d/7); assertDecimalEquals(cashFlow.getValue(12), 5d/3 * 6d/4 * 5d/7); } @Test public void cashFlowValueWithNoTrades() { TimeSeries sampleTimeSeries = new MockTimeSeries(3d, 2d, 5d, 4d, 7d, 6d, 7d, 8d, 5d, 6d); CashFlow cashFlow = new CashFlow(sampleTimeSeries, new TradingRecord()); assertDecimalEquals(cashFlow.getValue(4), 1); assertDecimalEquals(cashFlow.getValue(7), 1); assertDecimalEquals(cashFlow.getValue(9), 1); } @Test public void cashFlowWithConstrainedSeries() { MockTimeSeries series = new MockTimeSeries(5d, 6d, 3d, 7d, 8d, 6d, 10d, 15d, 6d); TimeSeries constrained = series.subseries(4, 8); TradingRecord tradingRecord = new TradingRecord( Order.buyAt(4), Order.sellAt(5), Order.buyAt(6), Order.sellAt(8)); CashFlow flow = new CashFlow(constrained, tradingRecord); assertDecimalEquals(flow.getValue(0), 1); assertDecimalEquals(flow.getValue(1), 1); assertDecimalEquals(flow.getValue(2), 1); assertDecimalEquals(flow.getValue(3), 1); assertDecimalEquals(flow.getValue(4), 1); assertDecimalEquals(flow.getValue(5), "0.75"); assertDecimalEquals(flow.getValue(6), "0.75"); assertDecimalEquals(flow.getValue(7), "1.125"); assertDecimalEquals(flow.getValue(8), "0.45"); } @Test public void reallyLongCashFlow() { int size = 1000000; TimeSeries sampleTimeSeries = new MockTimeSeries(Collections.nCopies(size, (Tick) new MockTick(10))); TradingRecord tradingRecord = new TradingRecord(Order.buyAt(0), Order.sellAt(size - 1)); CashFlow cashFlow = new CashFlow(sampleTimeSeries, tradingRecord); assertDecimalEquals(cashFlow.getValue(size - 1), 1); } }