1 /*
2 * Oceanus: Java Utilities
3 * Copyright 2012-2026. Tony Washer
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 * use this file except in compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17 package io.github.tonywasher.joceanus.oceanus.decimal;
18
19 import java.math.BigDecimal;
20 import java.math.RoundingMode;
21
22 /**
23 * Represents a Ratio object.
24 */
25 public class OceanusRatio
26 extends OceanusDecimal {
27 /**
28 * Standard number of decimals for Ratio.
29 */
30 protected static final int NUM_DECIMALS = 6;
31
32 /**
33 * Ratio of one.
34 */
35 public static final OceanusRatio ONE = new OceanusRatio("1");
36
37 /**
38 * Number of days in a standard year.
39 */
40 private static final int DAYS_IN_YEAR = 365;
41
42 /**
43 * Constructor.
44 */
45 protected OceanusRatio() {
46 }
47
48 /**
49 * Construct a new Ratio by copying another ratio.
50 *
51 * @param pRatio the Ratio to copy
52 */
53 public OceanusRatio(final OceanusRatio pRatio) {
54 super(pRatio.unscaledValue(), pRatio.scale());
55 }
56
57 /**
58 * Constructor for ratio from a decimal string.
59 *
60 * @param pSource The source decimal string
61 * @throws IllegalArgumentException on invalidly formatted argument
62 */
63 public OceanusRatio(final String pSource) {
64 /* Parse the string and correct the scale */
65 OceanusDecimalParser.parseDecimalValue(pSource, this);
66 adjustToScale(NUM_DECIMALS);
67 }
68
69 /**
70 * Construct a new Ratio by the ratio between two decimals.
71 *
72 * @param pFirst the first decimal
73 * @param pSecond the second decimal
74 */
75 public OceanusRatio(final OceanusDecimal pFirst,
76 final OceanusDecimal pSecond) {
77 recordScale(NUM_DECIMALS);
78 calculateQuotient(pFirst, pSecond);
79 }
80
81 /**
82 * Create the ratio from a byte array.
83 *
84 * @param pBuffer the buffer
85 */
86 public OceanusRatio(final byte[] pBuffer) {
87 super(pBuffer);
88 }
89
90 /**
91 * Obtain inverse ratio of this ratio (i.e. 100%/this rate).
92 *
93 * @return the inverse ratio
94 */
95 public OceanusRatio getInverseRatio() {
96 return new OceanusRatio(OceanusRate.RATE_ONEHUNDREDPERCENT, this);
97 }
98
99 /**
100 * Multiply by ratio.
101 *
102 * @param pRatio the multiplying ratio
103 * @return the new ratio
104 */
105 public OceanusRatio multiplyBy(final OceanusRatio pRatio) {
106 final OceanusRatio myRatio = new OceanusRatio();
107 myRatio.recordScale(NUM_DECIMALS);
108 myRatio.calculateProduct(this, pRatio);
109 return myRatio;
110 }
111
112 /**
113 * Obtain annualised ratio.
114 *
115 * @param pDays the number of days in the period
116 * @return the annualised ratio
117 */
118 public OceanusRate annualise(final long pDays) {
119 /* Calculate the annualised value and convert to rate */
120 double myValue = Math.pow(doubleValue(), ((double) DAYS_IN_YEAR) / pDays);
121 myValue -= 1;
122 BigDecimal myDecimal = BigDecimal.valueOf(myValue);
123 myDecimal = myDecimal.setScale(OceanusRate.NUM_DECIMALS, RoundingMode.HALF_UP);
124 return new OceanusRate(myDecimal.toString());
125 }
126
127 @Override
128 public void addValue(final OceanusDecimal pValue) {
129 throw new UnsupportedOperationException();
130 }
131
132 @Override
133 public void subtractValue(final OceanusDecimal pValue) {
134 throw new UnsupportedOperationException();
135 }
136 }