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.AggregationSpan;
021 import org.otfeed.event.ICompletionDelegate;
022 import org.otfeed.event.IDataDelegate;
023 import org.otfeed.event.OTOHLC;
024 import org.otfeed.protocol.CommandEnum;
025 import org.otfeed.protocol.DataEnum;
026 import org.otfeed.protocol.ProtocolException;
027
028 import java.nio.ByteBuffer;
029 import java.util.Date;
030
031 /**
032 * Request to receive aggregated historical data.
033 */
034 public final class HistDataRequest extends AbstractSessionRequest {
035
036 private final String exchangeCode;
037 private final String symbolCode;
038 private final Date startDate;
039 private final Date endDate;
040 private final AggregationSpan aggregationSpan;
041
042 private final IDataDelegate<OTOHLC> dataDelegate;
043
044 public String getExchangeCode() { return exchangeCode; }
045 public String getSymbolCode() { return symbolCode; }
046 public Date getStartDate() { return startDate; }
047 public Date getEndDate() { return endDate; }
048 public AggregationSpan getAggregationSpan() { return aggregationSpan; }
049
050 public HistDataRequest(int requestId,
051 String exchangeCode,
052 String symbolCode,
053 Date startDate,
054 Date endDate,
055 AggregationSpan aggregationSpan,
056 final IDataDelegate<OTOHLC> dataDelegate,
057 ICompletionDelegate completionDelegate) {
058
059 super(CommandEnum.REQUEST_HIST_DATA,
060 requestId, completionDelegate);
061
062 Check.notNull(exchangeCode, "exchangeCode");
063 Check.notNull(symbolCode, "symbolCode");
064 Check.notNull(startDate, "startDate");
065 Check.notNull(endDate, "endDate");
066 Check.notNull(aggregationSpan, "aggreagationSpan");
067
068 Check.notNull(dataDelegate, "dataDelegate");
069
070 this.exchangeCode = exchangeCode;
071 this.symbolCode = symbolCode;
072 this.startDate = startDate;
073 this.endDate = endDate;
074 this.aggregationSpan = aggregationSpan;
075 this.dataDelegate = dataDelegate;
076
077 }
078
079 @Override
080 public void writeRequest(ByteBuffer out) {
081 super.writeRequest(out);
082
083 Util.writeString(out, exchangeCode, 15);
084 Util.writeString(out, symbolCode, 15);
085 out.put((byte) 0);
086 out.put((byte) 0);
087 Util.writeDate(out, startDate);
088 Util.writeDate(out, endDate);
089 Util.writeAggreagationSpan(out, aggregationSpan);
090 }
091
092 private final static OTOHLC readOHLC(ByteBuffer in) {
093 Date ohlc_timestamp = Util.readDate(in);
094 double ohlc_openPrice = in.getDouble();
095 double ohlc_highPrice = in.getDouble();
096 double ohlc_lowPrice = in.getDouble();
097 double ohlc_closePrice = in.getDouble();
098 long ohlc_volume = in.getLong();
099
100 return new OTOHLC(ohlc_timestamp,
101 ohlc_openPrice, ohlc_highPrice, ohlc_lowPrice,
102 ohlc_closePrice, ohlc_volume);
103 }
104
105 @Override
106 public JobStatus handleMessage(Header header, ByteBuffer in) {
107 super.handleMessage(header, in);
108
109 int count = in.getInt();
110
111 while( count-- > 0) {
112
113 int typeCode = in.get();
114
115 if(typeCode == DataEnum.EOD.code) {
116 return JobStatus.FINISHED;
117 }
118
119 if(typeCode != DataEnum.OHLC.code) {
120 throw new ProtocolException("unexpected historical data code: " + typeCode, in);
121 }
122
123 OTOHLC ohlc = readOHLC(in);
124 dataDelegate.onData(ohlc);
125 }
126
127 return JobStatus.ACTIVE;
128 }
129
130 @Override
131 public final CommandEnum getCancelCommand() {
132 return CommandEnum.CANCEL_HIST_DATA; // fixme??
133 }
134 }