001    /**
002     * Copyright 2007 Mike Kroutikov.
003     *
004     * This program is free software; you can redistribute it and/or modify
005     *   it under the terms of the Lesser GNU General Public License as 
006     *   published by the Free Software Foundation; either version 3 of
007     *   the License, or (at your option) any later version.
008     *
009     *   This program is distributed in the hope that it will be useful,
010     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
011     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012     *   Lesser GNU General Public License for more details.
013     *
014     *   You should have received a copy of the Lesser GNU General Public License
015     *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
016     */
017    
018    package org.otfeed.protocol.request;
019    
020    import org.otfeed.command.MonthAndYear;
021    import org.otfeed.command.OptionTypeEnum;
022    import org.otfeed.command.PriceRange;
023    import org.otfeed.event.ICompletionDelegate;
024    import org.otfeed.event.IDataDelegate;
025    import org.otfeed.event.OTOptionInit;
026    
027    import org.otfeed.protocol.CommandEnum;
028    import org.otfeed.protocol.DataEnum;
029    import org.otfeed.protocol.ParamTypeEnum;
030    import org.otfeed.protocol.ProtocolException;
031    
032    import java.nio.ByteBuffer;
033    
034    /**
035     * Request to receive information on option.
036     */
037    public final class OptionInitRequest extends AbstractSessionRequest {
038    
039            private final String exchangeCode;
040            private final String symbolCode;
041            private final MonthAndYear expiration;
042            private final PriceRange   strikeRange;
043    
044            private final IDataDelegate<OTOptionInit> dataDelegate;
045    
046            public String getExchangeCode()  { return exchangeCode; }
047            public String getSymbolCode()    { return symbolCode; }
048    
049            public OptionInitRequest(
050                            int requestId, 
051                            String exchangeCode,
052                            String symbolCode,
053                            MonthAndYear expiration,
054                            PriceRange strikeRange,
055                            IDataDelegate<OTOptionInit> dataDelegate,
056                            ICompletionDelegate completionDelegate) {
057    
058                    super(CommandEnum.REQUEST_OPTION_INIT, 
059                                    requestId, completionDelegate);
060    
061                    Check.notNull(exchangeCode,  "exchangeCode");
062                    Check.notNull(symbolCode,  "symbolCode");
063                    Check.notNull(dataDelegate,  "dataDelegate");
064    
065                    this.exchangeCode    = exchangeCode;
066                    this.symbolCode      = symbolCode;
067                    this.expiration      = expiration; // optional
068                    this.strikeRange     = strikeRange; // optional
069    
070                    this.dataDelegate    = dataDelegate;
071            }
072    
073            @Override
074            public void writeRequest(ByteBuffer out) {
075                    super.writeRequest(out);
076    
077                    int paramMask = 0;
078                    if(expiration != null) {
079                            paramMask |= ParamTypeEnum.BY_DATE.code;
080                    }
081    
082                    if(strikeRange != null) {
083                            paramMask |= ParamTypeEnum.BY_PRICE.code;
084                    }
085    
086                    Util.writeString(out, exchangeCode, 15);
087                    Util.writeString(out, symbolCode, 15);
088                    if(expiration != null) {
089                            out.putShort((short) expiration.month);
090                            out.putInt(expiration.year);
091                    } else {
092                            out.putShort((short) 0);
093                            out.putInt(0);
094                    }
095    
096                    if(strikeRange != null) {
097                            out.putDouble(strikeRange.min); // ??? endianess
098                            out.putDouble(strikeRange.max); // ??? endianess
099                    } else {
100                            out.putDouble(0.0); // ??? endianess
101                            out.putDouble(0.0); // ??? endianess
102                    }
103    
104                    out.putInt(paramMask);         // ??? endianess
105            }
106    
107            @Override
108            public JobStatus handleMessage(Header header, ByteBuffer in) {
109                    super.handleMessage(header, in);
110    
111                    int typeCode = in.get();
112                    if(typeCode == DataEnum.EOD.code) {
113                            return JobStatus.FINISHED;
114                    }
115    
116                    if(typeCode != DataEnum.OPTION_INIT.code) {
117                            throw new ProtocolException("unexpected data code: " + typeCode, in);
118                    }
119    
120                    String underlyerSymbol = Util.readString(in, 12);
121                    String symbol          = Util.readString(in, 12);
122                    double strikePrice     = in.getDouble();
123                    int contractSize       = in.getInt();
124    
125                    // some confusion exists between ot drivers as
126                    // to whether its binary or textual.
127                    int expirationYear     = Integer.parseInt(
128                                    Util.readString(in, 4));
129                    short expirationMonth  = Short.parseShort(
130                                    Util.readString(in, 2)); 
131                    short expirationDay    = Short.parseShort(
132                                    Util.readString(in, 2));
133    
134                    OptionTypeEnum exersizeStyle = Util.readOptionTypeEnum(in);
135                    String underlyerCusip        = Util.readString(in, 9);
136                    String currency              = Util.readString(in, 3);
137                    char optionMarker            = (char) in.get();
138    
139                    OTOptionInit optionInit = new OTOptionInit(
140                            underlyerSymbol,
141                            symbol,
142                            strikePrice,
143                            contractSize,
144                            expirationYear,
145                            expirationMonth,
146                            expirationDay,
147                            exersizeStyle,
148                            underlyerCusip,
149                            currency,
150                            optionMarker);
151    
152                    dataDelegate.onData(optionInit);
153    
154                    return JobStatus.ACTIVE;
155            }
156    }