@Override
    public List<Bar> aggregate(List<Bar> bars) {
        final List<Bar> aggregated = new ArrayList<>();
        if (bars.isEmpty()) {
            return aggregated;
        }
        final Bar firstBar = bars.get(0);
        // get the actual time period
        final Duration actualDur = firstBar.getTimePeriod();
        // check if new timePeriod is a multiplication of actual time period
        final boolean isMultiplication = timePeriod.getSeconds() % actualDur.getSeconds() == 0;
        if (!isMultiplication) {
            throw new IllegalArgumentException(
                    "Cannot aggregate bars: the new timePeriod must be a multiplication of the actual timePeriod.");
        }

        int i = 0;
        final Num zero = firstBar.getOpenPrice().zero();
        while (i < bars.size()) {
            Bar bar = bars.get(i);
            final ZonedDateTime beginTime = bar.getBeginTime();
            final Num open = bar.getOpenPrice();
            Num high = bar.getHighPrice();
            Num low = bar.getLowPrice();

            Num close = null;
            Num volume = zero;
            Num amount = zero;
            long trades = 0;
            Duration sumDur = Duration.ZERO;

            while (isInDuration(sumDur)) {
                if (i < bars.size()) {
                    if (!beginTimesInDuration(beginTime, bars.get(i).getBeginTime())) {
                        break;
                    }
                    bar = bars.get(i);
                    if (high == null || bar.getHighPrice().isGreaterThan(high)) {
                        high = bar.getHighPrice();
                    }
                    if (low == null || bar.getLowPrice().isLessThan(low)) {
                        low = bar.getLowPrice();
                    }
                    close = bar.getClosePrice();

                    if (bar.getVolume() != null) {
                        volume = volume.plus(bar.getVolume());
                    }
                    if (bar.getAmount() != null) {
                        amount = amount.plus(bar.getAmount());
                    }
                    if (bar.getTrades() != 0) {
                        trades = trades + bar.getTrades();
                    }
                }

                sumDur = sumDur.plus(actualDur);
                i++;
            }

            if (!onlyFinalBars || i <= bars.size()) {
                final Bar aggregatedBar = new BaseBar(timePeriod, beginTime.plus(timePeriod), open, high, low, close,
                        volume, amount, trades);
                aggregated.add(aggregatedBar);
            }
        }

        return aggregated;
    }
@Test
    public void upscaledTo10DayBarsNotOnlyFinalBars() {
        final DurationBarAggregator barAggregator = new DurationBarAggregator(Duration.ofDays(10), false);
        final List<Bar> bars = barAggregator.aggregate(getOneDayBars());

        // must be 2 bars
        assertEquals(2, bars.size());
    }