001    package data;
002    
003    /**
004     * A QuoteValue consists of two values: A {@link #getBid bid} and an {@link #getOffer offer}.
005     *
006     * <p>QuoteValues usually represent prices. The bid is the price to be paid if someone wants to buy something
007     * from the Shop. The offer is the price paid when the Shop bought the product.</p>
008     *
009     * <p>QuoteValues have two more attributes: the {@link #getSpread spread} and the {@link #getMid mid}. While
010     * the mid is the mean value of bid and offer, the spread is defined as <code>bid - offer</code>.</p>
011     *
012     * @author Steffen Zschaler
013     * @version 2.0 19/08/1999
014     * @since v2.0
015     */
016    public class QuoteValue extends Object implements Value {
017    
018        /**
019             * ID for serialization.
020             */
021            private static final long serialVersionUID = -4966079030451874073L;
022    
023            /**
024         * The bid.
025         *
026         * @serial
027         */
028        protected Value m_vBid;
029    
030        /**
031         * The offer.
032         *
033         * @serial
034         */
035        protected Value m_vOffer;
036    
037        /**
038         * Create a new QuoteValue.
039         *
040         * @param vBid the bid
041         * @param vOffer the offer
042         *
043         * @exception IllegalArgumentException if <code>(vBid.getClass() != vOffer.getClass())</code>.
044         */
045        public QuoteValue(Value vBid, Value vOffer) {
046            super();
047    
048            if (vBid.getClass() != vOffer.getClass()) {
049                throw new IllegalArgumentException("QuoteValue: Classes of bid and offer must be identical.");
050            }
051    
052            m_vBid = vBid;
053            m_vOffer = vOffer;
054        }
055    
056        /**
057         * Get the current bid of this QuoteValue.
058         *
059         * @override Never
060         */
061        public Value getBid() {
062            return m_vBid;
063        }
064    
065        /**
066         * Get the current offer of this QuoteValue.
067         *
068         * @override Never
069         */
070        public Value getOffer() {
071            return m_vOffer;
072        }
073    
074        /**
075         * Create and return a deep clone of the QuoteValue. {@link #getBid Bid} and {@link #getOffer offer} are
076         * cloned and the clones become bid and offer of the new Value.
077         *
078         * @override Never
079         */
080        public Object clone() {
081            return new QuoteValue((Value)m_vBid.clone(), (Value)m_vOffer.clone());
082        }
083    
084        /**
085         * If the given value is a QuoteValue, its bid and offer get added to this value's bid and offer, resp.
086         * Otherwise, the value is added to both, bid and offer. An analogous algorithm is used for all other
087         * operations.
088         *
089         * @param v the value to be added.
090         *
091         * @override Never
092         */
093        public void addAccumulating(Value v) {
094            Value vBidAdd;
095            Value vOfferAdd;
096    
097            if (v instanceof QuoteValue) {
098                QuoteValue qv = (QuoteValue)v;
099    
100                vBidAdd = qv.getBid();
101                vOfferAdd = qv.getOffer();
102            } else {
103                vBidAdd = v;
104                vOfferAdd = v;
105            }
106    
107            getBid().addAccumulating(vBidAdd);
108            getOffer().addAccumulating(vOfferAdd);
109        }
110    
111        /**
112         * If the given value is a QuoteValue, its bid and offer get subtracted from this value's bid and offer,
113         * resp. Otherwise, the value is subtracted from both, bid and offer. An analogous algorithm is used for all
114         * other operations.
115         *
116         * @param v the value to be subtracted.
117         *
118         * @override Never
119         */
120        public void subtractAccumulating(Value v) {
121            Value vBidSub;
122            Value vOfferSub;
123    
124            if (v instanceof QuoteValue) {
125                QuoteValue qv = (QuoteValue)v;
126    
127                vBidSub = qv.getBid();
128                vOfferSub = qv.getOffer();
129            } else {
130                vBidSub = v;
131                vOfferSub = v;
132            }
133    
134            getBid().subtractAccumulating(vBidSub);
135            getOffer().subtractAccumulating(vOfferSub);
136        }
137    
138        /**
139         * If the given value is a QuoteValue, its bid and offer get multiplied by this value's bid and offer, resp.
140         * Otherwise, both bid and offer are multiplied by the given value. An analogous algorithm is used for all
141         * other operations.
142         *
143         * @param v the value to multiply by.
144         *
145         * @override Never
146         */
147        public void multiplyAccumulating(Value v) {
148            Value vBidMul;
149            Value vOfferMul;
150    
151            if (v instanceof QuoteValue) {
152                QuoteValue qv = (QuoteValue)v;
153    
154                vBidMul = qv.getBid();
155                vOfferMul = qv.getOffer();
156            } else {
157                vBidMul = v;
158                vOfferMul = v;
159            }
160    
161            getBid().multiplyAccumulating(vBidMul);
162            getOffer().multiplyAccumulating(vOfferMul);
163        }
164    
165        /**
166         * Both bid and offer get multiplied by the given 'scalar'.
167         *
168         * @param dl the 'scalar' to multiply by.
169         *
170         * @override Never
171         */
172        public void multiplyAccumulating(double dl) {
173            getBid().multiplyAccumulating(dl);
174            getOffer().multiplyAccumulating(dl);
175        }
176    
177        /**
178         * Both bid and offer get multiplied by the given 'scalar'.
179         *
180         * @param fl the 'scalar' to multiply by.
181         *
182         * @override Never
183         */
184        public void multiplyAccumulating(float fl) {
185            getBid().multiplyAccumulating(fl);
186            getOffer().multiplyAccumulating(fl);
187        }
188    
189        /**
190         * Both bid and offer get multiplied by the given 'scalar'.
191         *
192         * @param l the 'scalar' to multiply by.
193         *
194         * @override Never
195         */
196        public void multiplyAccumulating(long l) {
197            getBid().multiplyAccumulating(l);
198            getOffer().multiplyAccumulating(l);
199        }
200    
201        /**
202         * Both bid and offer get multiplied by the given 'scalar'.
203         *
204         * @param n the 'scalar' to multiply by.
205         *
206         * @override Never
207         */
208        public void multiplyAccumulating(int n) {
209            getBid().multiplyAccumulating(n);
210            getOffer().multiplyAccumulating(n);
211        }
212    
213        /**
214         * If the given value is a QuoteValue, this value's bid and offer get divided by its bid and offer, resp.
215         * Otherwise, both bid and offer are divided by the given value. An analogous algorithm is used for all
216         * other operations.
217         *
218         * @param v the value to divide by.
219         *
220         * @override Never
221         */
222        public void divideAccumulating(Value v) {
223            Value vBidDiv;
224            Value vOfferDiv;
225    
226            if (v instanceof QuoteValue) {
227                QuoteValue qv = (QuoteValue)v;
228    
229                vBidDiv = qv.getBid();
230                vOfferDiv = qv.getOffer();
231            } else {
232                vBidDiv = v;
233                vOfferDiv = v;
234            }
235    
236            getBid().divideAccumulating(vBidDiv);
237            getOffer().divideAccumulating(vOfferDiv);
238        }
239    
240        /**
241         * @see #addAccumulating
242         *
243         * @override Never
244         */
245        public Value add(Value v) {
246            Value vBidAdd;
247            Value vOfferAdd;
248    
249            if (v instanceof QuoteValue) {
250                QuoteValue qv = (QuoteValue)v;
251    
252                vBidAdd = qv.getBid();
253                vOfferAdd = qv.getOffer();
254            } else {
255                vBidAdd = v;
256                vOfferAdd = v;
257            }
258    
259            return new QuoteValue(getBid().add(vBidAdd), getOffer().add(vOfferAdd));
260        }
261    
262        /**
263         * @see #subtractAccumulating
264         *
265         * @override Never
266         */
267        public Value subtract(Value v) {
268            Value vBidSub;
269            Value vOfferSub;
270    
271            if (v instanceof QuoteValue) {
272                QuoteValue qv = (QuoteValue)v;
273    
274                vBidSub = qv.getBid();
275                vOfferSub = qv.getOffer();
276            } else {
277                vBidSub = v;
278                vOfferSub = v;
279            }
280    
281            return new QuoteValue(getBid().subtract(vBidSub), getOffer().subtract(vOfferSub));
282        }
283    
284        /**
285         * @see #multiplyAccumulating(data.Value)
286         *
287         * @override Never
288         */
289        public Value multiply(Value v) {
290            Value vBidMul;
291            Value vOfferMul;
292    
293            if (v instanceof QuoteValue) {
294                QuoteValue qv = (QuoteValue)v;
295    
296                vBidMul = qv.getBid();
297                vOfferMul = qv.getOffer();
298            } else {
299                vBidMul = v;
300                vOfferMul = v;
301            }
302    
303            return new QuoteValue(getBid().multiply(vBidMul), getOffer().multiply(vOfferMul));
304        }
305    
306        /**
307         * @see #multiplyAccumulating(double)
308         *
309         * @override Never
310         */
311        public Value multiply(double dl) {
312            return new QuoteValue(getBid().multiply(dl), getOffer().multiply(dl));
313        }
314    
315        /**
316         * @see #multiplyAccumulating(float)
317         *
318         * @override Never
319         */
320        public Value multiply(float fl) {
321            return new QuoteValue(getBid().multiply(fl), getOffer().multiply(fl));
322        }
323    
324        /**
325         * @see #multiplyAccumulating(long)
326         *
327         * @override Never
328         */
329        public Value multiply(long l) {
330            return new QuoteValue(getBid().multiply(l), getOffer().multiply(l));
331        }
332    
333        /**
334         * @see #multiplyAccumulating(int)
335         *
336         * @override Never
337         */
338        public Value multiply(int n) {
339            return new QuoteValue(getBid().multiply(n), getOffer().multiply(n));
340        }
341    
342        /**
343         * @see #divideAccumulating
344         *
345         * @override Never
346         */
347        public Value divide(Value v) {
348            Value vBidDiv;
349            Value vOfferDiv;
350    
351            if (v instanceof QuoteValue) {
352                QuoteValue qv = (QuoteValue)v;
353    
354                vBidDiv = qv.getBid();
355                vOfferDiv = qv.getOffer();
356            } else {
357                vBidDiv = v;
358                vOfferDiv = v;
359            }
360    
361            return new QuoteValue(getBid().divide(vBidDiv), getOffer().divide(vOfferDiv));
362        }
363    
364        /**
365         * Get the spread of this value. The spread is defined as
366         * <code>{@link #getBid bid} - {@link #getOffer offer}</code>.
367         *
368         * @override Never
369         */
370        public Value getSpread() {
371            return getBid().subtract(getOffer());
372        }
373    
374        /**
375         * Get the mid of this value. The mid is defined as
376         * <code>({@link #getBid bid} + {@link #getOffer offer}) / 2</code>.
377         *
378         * @override Never
379         */
380        public Value getMid() {
381            Value vReturn = getBid().add(getOffer());
382            vReturn.divideAccumulating(new IntegerValue(2));
383            return vReturn;
384        }
385    
386        /**
387         * Compare this value to the given one. This will compare the {@link #getMid mids}.
388         *
389         * @override Sometimes
390         *
391         * @exception ClassCastException if the given object could not be cast into a QuoteValue.
392         */
393        public int compareTo(Value v) {
394            QuoteValue qvCompare = (QuoteValue)v;
395    
396            return getMid().compareTo(qvCompare.getMid());
397        }
398    
399        /**
400         * True, iff both {@link #getBid bid} and {@link #getOffer offer} are zero elements with respect to addition.
401         *
402         * @override Sometimes
403         */
404        public boolean isAddZero() {
405            return ((getBid().isAddZero()) && (getOffer().isAddZero()));
406        }
407    
408        /**
409         * True, iff both {@link #getBid bid} and {@link #getOffer offer} are zero elements with respect to
410         * multiplication.
411         *
412         * @override Sometimes
413         */
414        public boolean isMulZero() {
415            return ((getBid().isMulZero()) && (getOffer().isMulZero()));
416        }
417    
418        /**
419         * True, iff both {@link #getBid bid} and {@link #getOffer offer} are one elements with respect to
420         * multiplication.
421         *
422         * @override Sometimes
423         */
424        public boolean isMulOne() {
425            return ((getBid().isMulOne()) && (getOffer().isMulOne()));
426        }
427    }