eu.verdelhan.ta4j.Decimal Maven / Gradle / Ivy
Show all versions of ta4j Show documentation
/**
* 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;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Objects;
/**
* Immutable, arbitrary-precision signed decimal numbers designed for technical analysis.
*
* A {@code Decimal} consists of a {@code BigDecimal} with arbitrary {@link MathContext} (precision and rounding mode).
*
* @see BigDecimal
* @see MathContext
* @see RoundingMode
*/
public final class Decimal implements Comparable, Serializable {
private static final long serialVersionUID = 2225130444465033658L;
public static final MathContext MATH_CONTEXT = new MathContext(32, RoundingMode.HALF_UP);
/** Not-a-Number instance (infinite error) */
public static final Decimal NaN = new Decimal();
public static final Decimal ZERO = valueOf(0);
public static final Decimal ONE = valueOf(1);
public static final Decimal TWO = valueOf(2);
public static final Decimal THREE = valueOf(3);
public static final Decimal TEN = valueOf(10);
public static final Decimal HUNDRED = valueOf(100);
public static final Decimal THOUSAND = valueOf(1000);
private final BigDecimal delegate;
/**
* Constructor.
* Only used for NaN instance.
*/
private Decimal() {
delegate = null;
}
/**
* Constructor.
* @param val the string representation of the decimal value
*/
private Decimal(String val) {
delegate = new BigDecimal(val, MATH_CONTEXT);
}
/**
* Constructor.
* @param val the double value
*/
private Decimal(double val) {
delegate = new BigDecimal(val, MATH_CONTEXT);
}
private Decimal(int val) {
delegate = new BigDecimal(val, MATH_CONTEXT);
}
private Decimal(long val) {
delegate = new BigDecimal(val, MATH_CONTEXT);
}
private Decimal(BigDecimal val) {
delegate = val;
}
/**
* Returns a {@code Decimal} whose value is {@code (this + augend)},
* with rounding according to the context settings.
* @param augend value to be added to this {@code Decimal}.
* @return {@code this + augend}, rounded as necessary
* @see BigDecimal#add(java.math.BigDecimal, java.math.MathContext)
*/
public Decimal plus(Decimal augend) {
if ((this == NaN) || (augend == NaN)) {
return NaN;
}
return new Decimal(delegate.add(augend.delegate, MATH_CONTEXT));
}
/**
* Returns a {@code Decimal} whose value is {@code (this - augend)},
* with rounding according to the context settings.
* @param subtrahend value to be subtracted from this {@code Decimal}.
* @return {@code this - subtrahend}, rounded as necessary
* @see BigDecimal#subtract(java.math.BigDecimal, java.math.MathContext)
*/
public Decimal minus(Decimal subtrahend) {
if ((this == NaN) || (subtrahend == NaN)) {
return NaN;
}
return new Decimal(delegate.subtract(subtrahend.delegate, MATH_CONTEXT));
}
/**
* Returns a {@code Decimal} whose value is {@code this * multiplicand},
* with rounding according to the context settings.
* @param multiplicand value to be multiplied by this {@code Decimal}.
* @return {@code this * multiplicand}, rounded as necessary
* @see BigDecimal#multiply(java.math.BigDecimal, java.math.MathContext)
*/
public Decimal multipliedBy(Decimal multiplicand) {
if ((this == NaN) || (multiplicand == NaN)) {
return NaN;
}
return new Decimal(delegate.multiply(multiplicand.delegate, MATH_CONTEXT));
}
/**
* Returns a {@code Decimal} whose value is {@code (this / divisor)},
* with rounding according to the context settings.
* @param divisor value by which this {@code Decimal} is to be divided.
* @return {@code this / divisor}, rounded as necessary
* @see BigDecimal#divide(java.math.BigDecimal, java.math.MathContext)
*/
public Decimal dividedBy(Decimal divisor) {
if ((this == NaN) || (divisor == NaN) || divisor.isZero()) {
return NaN;
}
return new Decimal(delegate.divide(divisor.delegate, MATH_CONTEXT));
}
/**
* Returns a {@code Decimal} whose value is {@code (this % divisor)},
* with rounding according to the context settings.
* @param divisor value by which this {@code Decimal} is to be divided.
* @return {@code this % divisor}, rounded as necessary.
* @see BigDecimal#remainder(java.math.BigDecimal, java.math.MathContext)
*/
public Decimal remainder(Decimal divisor) {
if ((this == NaN) || (divisor == NaN) || divisor.isZero()) {
return NaN;
}
return new Decimal(delegate.remainder(divisor.delegate, MATH_CONTEXT));
}
/**
* Returns a {@code Decimal} whose value is (thisn).
* @param n power to raise this {@code Decimal} to.
* @return thisn
* @see BigDecimal#pow(int, java.math.MathContext)
*/
public Decimal pow(int n) {
if (this == NaN) {
return NaN;
}
return new Decimal(delegate.pow(n, MATH_CONTEXT));
}
/**
* Returns the correctly rounded natural logarithm (base e) of the double
value of this {@code Decimal}.
* /!\ Warning! Uses the {@code StrictMath#log(double)} method under the hood.
* @return the natural logarithm (base e) of {@code this}
* @see StrictMath#log(double)
*/
public Decimal log() {
if (this == NaN) {
return NaN;
}
return new Decimal(StrictMath.log(delegate.doubleValue()));
}
/**
* Returns the correctly rounded positive square root of the double
value of this {@code Decimal}.
* /!\ Warning! Uses the {@code StrictMath#sqrt(double)} method under the hood.
* @return the positive square root of {@code this}
* @see StrictMath#sqrt(double)
*/
public Decimal sqrt() {
if (this == NaN) {
return NaN;
}
return new Decimal(StrictMath.sqrt(delegate.doubleValue()));
}
/**
* Returns a {@code Decimal} whose value is the absolute value
* of this {@code Decimal}.
* @return {@code abs(this)}
*/
public Decimal abs() {
if (this == NaN) {
return NaN;
}
return new Decimal(delegate.abs());
}
/**
* Checks if the value is zero.
* @return true if the value is zero, false otherwise
*/
public boolean isZero() {
if (this == NaN) {
return false;
}
return compareTo(ZERO) == 0;
}
/**
* Checks if the value is greater than zero.
* @return true if the value is greater than zero, false otherwise
*/
public boolean isPositive() {
if (this == NaN) {
return false;
}
return compareTo(ZERO) > 0;
}
/**
* Checks if the value is zero or greater.
* @return true if the value is zero or greater, false otherwise
*/
public boolean isPositiveOrZero() {
if (this == NaN) {
return false;
}
return compareTo(ZERO) >= 0;
}
/**
* Checks if the value is Not-a-Number.
* @return true if the value is Not-a-Number (NaN), false otherwise
*/
public boolean isNaN() {
return this == NaN;
}
/**
* Checks if the value is less than zero.
* @return true if the value is less than zero, false otherwise
*/
public boolean isNegative() {
if (this == NaN) {
return false;
}
return compareTo(ZERO) < 0;
}
/**
* Checks if the value is zero or less.
* @return true if the value is zero or less, false otherwise
*/
public boolean isNegativeOrZero() {
if (this == NaN) {
return false;
}
return compareTo(ZERO) <= 0;
}
/**
* Checks if this value is equal to another.
* @param other the other value, not null
* @return true is this is greater than the specified value, false otherwise
*/
public boolean isEqual(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return false;
}
return compareTo(other) == 0;
}
/**
* Checks if this value is greater than another.
* @param other the other value, not null
* @return true is this is greater than the specified value, false otherwise
*/
public boolean isGreaterThan(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return false;
}
return compareTo(other) > 0;
}
/**
* Checks if this value is greater than or equal to another.
* @param other the other value, not null
* @return true is this is greater than or equal to the specified value, false otherwise
*/
public boolean isGreaterThanOrEqual(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return false;
}
return compareTo(other) > -1;
}
/**
* Checks if this value is less than another.
* @param other the other value, not null
* @return true is this is less than the specified value, false otherwise
*/
public boolean isLessThan(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return false;
}
return compareTo(other) < 0;
}
/**
* Checks if this value is less than or equal to another.
* @param other the other value, not null
* @return true is this is less than or equal to the specified value, false otherwise
*/
public boolean isLessThanOrEqual(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return false;
}
return compareTo(other) < 1;
}
@Override
public int compareTo(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return 0;
}
return delegate.compareTo(other.delegate);
}
/**
* Returns the minimum of this {@code Decimal} and {@code other}.
* @param other value with which the minimum is to be computed
* @return the {@code Decimal} whose value is the lesser of this
* {@code Decimal} and {@code other}. If they are equal,
* as defined by the {@link #compareTo(Decimal) compareTo}
* method, {@code this} is returned.
*/
public Decimal min(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return NaN;
}
return (compareTo(other) <= 0 ? this : other);
}
/**
* Returns the maximum of this {@code Decimal} and {@code other}.
* @param other value with which the maximum is to be computed
* @return the {@code Decimal} whose value is the greater of this
* {@code Decimal} and {@code other}. If they are equal,
* as defined by the {@link #compareTo(Decimal) compareTo}
* method, {@code this} is returned.
*/
public Decimal max(Decimal other) {
if ((this == NaN) || (other == NaN)) {
return NaN;
}
return (compareTo(other) >= 0 ? this : other);
}
/**
* Converts this {@code Decimal} to a {@code double}.
* @return this {@code Decimal} converted to a {@code double}
* @see BigDecimal#doubleValue()
*/
public double toDouble() {
if (this == NaN) {
return Double.NaN;
}
return delegate.doubleValue();
}
@Override
public String toString() {
if (this == NaN) {
return "NaN";
}
return delegate.toString();
}
@Override
public int hashCode() {
return Objects.hash(delegate);
}
/**
* {@inheritDoc}
* Warning: This method returns true if `this` and `obj` are both NaN.
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Decimal)) {
return false;
}
final Decimal other = (Decimal) obj;
if (this.delegate != other.delegate
&& (this.delegate == null || (this.delegate.compareTo(other.delegate) != 0))) {
return false;
}
return true;
}
public static Decimal valueOf(String val) {
if ("NaN".equals(val)) {
return NaN;
}
return new Decimal(val);
}
public static Decimal valueOf(double val) {
if (Double.isNaN(val)) {
return NaN;
}
return new Decimal(val);
}
public static Decimal valueOf(int val) {
return new Decimal(val);
}
public static Decimal valueOf(long val) {
return new Decimal(val);
}
}