Пример #1
0
  @Test
  public void testCandleSeriessClone() {
    try {

      CandleSeries candleSeries = this.tradestrategy.getStrategyData().getBaseCandleSeries();
      CandleSeries series =
          (CandleSeries) this.tradestrategy.getStrategyData().getBaseCandleSeries().clone();
      if (candleSeries.equals(series)) {
        _log.info("CandleSeries: " + series.toString());
      }
      TestCase.assertEquals(series, candleSeries);

    } catch (Exception e) {
      TestCase.fail("Error on testCandleSeriessClone " + e.getMessage());
    }
  }
Пример #2
0
  /**
   * Method updateSeries.
   *
   * @param source CandleSeries
   * @param skip int
   * @param newBar boolean
   */
  public void updateSeries(CandleSeries source, int skip, boolean newBar) {

    if (source == null) {
      throw new IllegalArgumentException("Null source (CandleSeries).");
    }
    if (getFastLength() == null || getFastLength() < 1) {
      throw new IllegalArgumentException("Fast MA must be greater than zero.");
    }

    if (getSlowLength() == null || getSlowLength() < 1) {
      throw new IllegalArgumentException("Slow MA must be greater than zero.");
    }

    if (getSignalSmoothing() == null || getSignalSmoothing() < 1) {
      throw new IllegalArgumentException("Signal Smoothing must be greater than zero.");
    }

    if (getSlowLength() < getFastLength()) {
      throw new IllegalArgumentException("Fast MA must be greater than Slow MA.");
    }

    if (source.getItemCount() > skip) {

      // get the current data item...
      CandleItem candleItem = (CandleItem) source.getDataItem(skip);

      // work out the average for the earlier values...
      Number yy = candleItem.getY();

      if (null != yy) {
        if (this.fastYYValues.size() == getFastLength()) {
          /*
           * If the item does not exist in the series then this is a
           * new time period and so we need to remove the last in the
           * set and add the new periods values. Otherwise we just
           * update the last value in the set. Sum is just used for
           * performance save having to sum the last set of values
           * each time.
           */
          if (newBar) {
            fastSum = fastSum - this.fastYYValues.getLast() + yy.doubleValue();
            this.fastYYValues.removeLast();
            this.fastYYValues.addFirst(yy.doubleValue());

          } else {
            fastSum = fastSum - this.fastYYValues.getFirst() + yy.doubleValue();
            this.fastYYValues.removeFirst();
            this.fastYYValues.addFirst(yy.doubleValue());
          }
        } else {
          if (newBar) {
            fastSum = fastSum + yy.doubleValue();
            this.fastYYValues.addFirst(yy.doubleValue());
          } else {
            fastSum = fastSum + yy.doubleValue() - this.fastYYValues.getFirst();
            this.fastYYValues.removeFirst();
            this.fastYYValues.addFirst(yy.doubleValue());
          }
        }
        if (this.slowYYValues.size() == getSlowLength()) {
          /*
           * If the item does not exist in the series then this is a
           * new time period and so we need to remove the last in the
           * set and add the new periods values. Otherwise we just
           * update the last value in the set. Sum is just used for
           * performance save having to sum the last set of values
           * each time.
           */
          if (newBar) {
            slowSum = slowSum - this.slowYYValues.getLast() + yy.doubleValue();
            this.slowYYValues.removeLast();
            this.slowYYValues.addFirst(yy.doubleValue());

          } else {
            slowSum = slowSum - this.slowYYValues.getFirst() + yy.doubleValue();
            this.slowYYValues.removeFirst();
            this.slowYYValues.addFirst(yy.doubleValue());
          }
        } else {
          if (newBar) {
            slowSum = slowSum + yy.doubleValue();
            this.slowYYValues.addFirst(yy.doubleValue());
          } else {
            slowSum = slowSum + yy.doubleValue() - this.slowYYValues.getFirst();
            this.slowYYValues.removeFirst();
            this.slowYYValues.addFirst(yy.doubleValue());
          }
        }

        if (this.slowYYValues.size() == getSlowLength()) {

          double fastEMA = 0;
          if (fastMultiplyer == Double.MAX_VALUE) {
            fastEMA = fastSum / this.getFastLength();
            fastMultiplyer = 2 / (this.getFastLength() + 1.0d);
          } else {
            fastEMA = ((this.fastYYValues.getFirst() - prevFastEMA) * fastMultiplyer) + prevFastEMA;
          }
          prevFastEMA = fastEMA;
          double slowEMA = 0;
          if (slowMultiplyer == Double.MAX_VALUE) {
            slowEMA = slowSum / this.getSlowLength();
            slowMultiplyer = 2 / (this.getSlowLength() + 1.0d);
          } else {
            slowEMA = ((this.slowYYValues.getFirst() - prevSlowEMA) * slowMultiplyer) + prevSlowEMA;
          }
          prevSlowEMA = slowEMA;
          double MACD = fastEMA - slowEMA;
          if (this.signalSmoothingYYValues.size() == this.getSignalSmoothing()) {
            /*
             * If the item does not exist in the series then this is
             * a new time period and so we need to remove the last
             * in the set and add the new periods values. Otherwise
             * we just update the last value in the set. Sum is just
             * used for performance save having to sum the last set
             * of values each time.
             */

            if (newBar) {
              signalSmoothingSum =
                  signalSmoothingSum - this.signalSmoothingYYValues.getLast() + MACD;
              this.signalSmoothingYYValues.removeLast();
              this.signalSmoothingYYValues.addFirst(MACD);

            } else {
              signalSmoothingSum =
                  signalSmoothingSum - this.signalSmoothingYYValues.getFirst() + MACD;
              this.signalSmoothingYYValues.removeFirst();
              this.signalSmoothingYYValues.addFirst(MACD);
            }

          } else {
            if (newBar) {
              signalSmoothingSum = signalSmoothingSum + MACD;
              this.signalSmoothingYYValues.addFirst(MACD);
            } else {
              signalSmoothingSum =
                  signalSmoothingSum + MACD - this.signalSmoothingYYValues.getFirst();
              this.signalSmoothingYYValues.removeFirst();
              this.signalSmoothingYYValues.addFirst(MACD);
            }
          }
          double signalLine = Double.MAX_VALUE;
          if (this.signalSmoothingYYValues.size() == getSignalSmoothing()) {

            signalLine =
                calculateSmoothingMA(
                    this.signalSmoothingYYValues.getFirst(),
                    this.prevSignalSmoothingEMA,
                    this.signalSmoothingSum);
            this.prevSignalSmoothingEMA = signalLine;
          }
          if (newBar) {
            MACDItem dataItem =
                new MACDItem(
                    candleItem.getPeriod(),
                    new BigDecimal(MACD),
                    (signalLine == Double.MAX_VALUE ? null : new BigDecimal(signalLine)),
                    (signalLine == Double.MAX_VALUE ? null : new BigDecimal(MACD - signalLine)));
            this.add(dataItem, false);

          } else {
            MACDItem dataItem = (MACDItem) this.getDataItem(this.getItemCount() - 1);
            dataItem.setMACD(MACD);
            if (signalLine == Double.MAX_VALUE) {
              dataItem.setSignalLine(signalLine);
              dataItem.setMACDHistogram(MACD - signalLine);
            }
          }
        }
      }
    }
  }
  /**
   * Method updateSeries.
   *
   * @param source CandleSeries
   * @param skip int
   * @param newBar boolean
   */
  public void updateSeries(CandleSeries source, int skip, boolean newBar) {

    if (source == null) {
      throw new IllegalArgumentException("Null source (CandleSeries).");
    }
    if (getLength() == null || getLength() < 1) {
      throw new IllegalArgumentException("SMA period must be greater than zero.");
    }

    if (source.getItemCount() > skip) {
      // get the current data item...
      CandleItem candleItem = (CandleItem) source.getDataItem(skip);
      if (0 != candleItem.getClose()) {
        if (this.yyValues.size() == getLength()) {
          /*
           * If the item does not exist in the series then this is a
           * new time period and so we need to remove the last in the
           * set and add the new periods values. Otherwise we just
           * update the last value in the set. Sum is just used for
           * performance save having to sum the last set of values
           * each time.
           */
          if (newBar) {
            this.yyValues.removeLast();
            this.yyValues.addFirst(candleItem.getClose());
          } else {
            this.yyValues.removeFirst();
            this.yyValues.addFirst(candleItem.getClose());
          }
        } else {
          if (newBar) {
            this.yyValues.addFirst(candleItem.getClose());
          } else {
            this.yyValues.removeFirst();
            this.yyValues.addFirst(candleItem.getClose());
          }
        }

        if (this.yyValues.size() == getLength()) {

          double high = Collections.max(this.yyValues);
          double low = Collections.min(this.yyValues);

          /*
           * %K = (Current Close - Lowest Low)/(Highest High - Lowest
           * Low) * 100
           *
           * %D = 3-day SMA of %K
           *
           * Lowest Low = lowest low for the look-back period Highest
           * High = highest high for the look-back period %K is
           * multiplied by 100 to move the decimal point two places
           */
          double fastKR = 0;
          if ((high - low) > 0) fastKR = ((candleItem.getClose() - low) / (high - low)) * 100;

          if (this.getInverse()) {
            /*
             * %R = (Highest High - Close)/(Highest High - Lowest
             * Low) * -100
             *
             * Lowest Low = lowest low for the look-back period
             * Highest High = highest high for the look-back period
             * %R is multiplied by -100 correct the inversion and
             * move the decimal.
             */
            fastKR = ((high - candleItem.getClose()) / (high - low)) * -100;
          }

          if (this.fullKRValues.size() == this.getKSmoothing()) {
            /*
             * If the item does not exist in the series then this is
             * a new time period and so we need to remove the last
             * in the set and add the new periods values. Otherwise
             * we just update the last value in the set. Sum is just
             * used for performance save having to sum the last set
             * of values each time.
             */
            if (newBar) {
              sumFullKRValues = sumFullKRValues - this.fullKRValues.getLast() + fastKR;
              this.fullKRValues.removeLast();
              this.fullKRValues.addFirst(fastKR);
            } else {
              sumFullKRValues = sumFullKRValues - this.fullKRValues.getFirst() + fastKR;
              this.fullKRValues.removeFirst();
              this.fullKRValues.addFirst(fastKR);
            }
          } else {
            if (newBar) {
              sumFullKRValues = sumFullKRValues + fastKR;
              this.fullKRValues.addFirst(fastKR);
            } else {
              sumFullKRValues = sumFullKRValues + fastKR - this.fullKRValues.getFirst();
              this.fullKRValues.removeFirst();
              this.fullKRValues.addFirst(fastKR);
            }
          }
          if (this.fullKRValues.size() == this.getKSmoothing()) {

            double fullKR = sumFullKRValues / this.getKSmoothing();

            if (this.fullDValues.size() == this.getPercentD()) {
              /*
               * If the item does not exist in the series then
               * this is a new time period and so we need to
               * remove the last in the set and add the new
               * periods values. Otherwise we just update the last
               * value in the set. Sum is just used for
               * performance save having to sum the last set of
               * values each time.
               */
              if (newBar) {
                sumFullDValues = sumFullDValues - this.fullDValues.getLast() + fullKR;
                this.fullDValues.removeLast();
                this.fullDValues.addFirst(fullKR);
              } else {
                sumFullDValues = sumFullDValues - this.fullDValues.getFirst() + fullKR;
                this.fullDValues.removeFirst();
                this.fullDValues.addFirst(fullKR);
              }
            } else {
              if (newBar) {
                sumFullDValues = sumFullDValues + fullKR;
                this.fullDValues.addFirst(fullKR);
              } else {
                sumFullDValues = sumFullDValues + fullKR - this.fullDValues.getFirst();
                this.fullDValues.removeFirst();
                this.fullDValues.addFirst(fullKR);
              }
            }
            if (this.fullDValues.size() == this.getPercentD()) {
              double fullD = sumFullDValues / this.getPercentD();
              if (newBar) {
                StochasticOscillatorItem dataItem =
                    new StochasticOscillatorItem(candleItem.getPeriod(), new BigDecimal(fullD));
                this.add(dataItem, false);

              } else {
                StochasticOscillatorItem dataItem =
                    (StochasticOscillatorItem) this.getDataItem(this.getItemCount() - 1);
                dataItem.setStochasticOscillator(fullD);
              }
            }
          }
        }
      }
    }
  }