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