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.book;
019
020 import org.otfeed.command.BookDeleteTypeEnum;
021 import org.otfeed.event.IDataDelegate;
022 import org.otfeed.event.OTBookCancel;
023 import org.otfeed.event.OTBookChange;
024 import org.otfeed.event.OTBookDelete;
025 import org.otfeed.event.OTBookExecute;
026 import org.otfeed.event.OTBookOrder;
027 import org.otfeed.event.OTBookPriceLevel;
028 import org.otfeed.event.OTBookPurge;
029 import org.otfeed.event.OTBookReplace;
030 import org.otfeed.event.TradeSideEnum;
031
032 import org.otfeed.protocol.DataEnum;
033 import org.otfeed.protocol.request.Header;
034 import org.otfeed.protocol.request.Util;
035
036 import java.util.Date;
037 import java.nio.ByteBuffer;
038
039 /**
040 * Class that knows how to de-serialise miscellaneous Book events.
041 */
042 public abstract class BookReader {
043
044 private BookReader(DataEnum t) {
045 type = t;
046 this.mask = 1 << (t.code - 1);
047 }
048
049 public final DataEnum type;
050 public final int mask;
051
052 /**
053 * Reads response data frame, parses it and emits events.
054 *
055 * @param header response header.
056 * @param in data frame.
057 */
058 public abstract void read(Header header, ByteBuffer in);
059
060 /**
061 * Creates reader for the BookOrder event.
062 */
063 public static final BookReader orderReader(
064 final IDataDelegate<OTBookOrder> dataDelegate) {
065
066 return new BookReader(DataEnum.BOOK_ORDER) {
067 @Override
068 public void read(Header header, ByteBuffer in) {
069 OTBookOrder data = readOrder(in);
070 dataDelegate.onData(data);
071 }
072 };
073 }
074
075 private final static OTBookOrder readOrder(ByteBuffer in) {
076 Date timestamp = Util.readDate(in);
077 String reference = Util.readString(in, 21).trim();
078 double price = in.getDouble();
079 int size = in.getInt();
080 TradeSideEnum side = Util.readTradeSideEnum(in);
081 boolean display = Util.readBoolean(in);
082
083 return new OTBookOrder(timestamp,
084 reference, price, size, side, display);
085 }
086
087 /**
088 * Creates reader for the BookExecute event.
089 */
090 public static final BookReader executeReader(
091 final IDataDelegate<OTBookExecute> dataDelegate) {
092
093 return new BookReader(DataEnum.BOOK_EXECUTE) {
094 @Override
095 public void read(Header header, ByteBuffer in) {
096 OTBookExecute data = readExecute(in);
097 dataDelegate.onData(data);
098 }
099 };
100 }
101
102 private final static OTBookExecute readExecute(ByteBuffer in) {
103 Date timestamp = Util.readDate(in);
104 String reference = Util.readString(in, 21).trim();
105 int size = in.getInt();
106 int matchNumber = in.getInt();
107
108 return new OTBookExecute(timestamp,
109 reference, size, matchNumber);
110 }
111
112 /**
113 * Creates reader for the BookDelete event.
114 */
115 public static final BookReader deleteReader(
116 final IDataDelegate<OTBookDelete> dataDelegate) {
117
118 return new BookReader(DataEnum.BOOK_DELETE) {
119 @Override
120 public void read(Header header, ByteBuffer in) {
121 OTBookDelete data = readDelete(in);
122 dataDelegate.onData(data);
123 }
124 };
125 }
126
127 private final static OTBookDelete readDelete(ByteBuffer in) {
128 Date timestamp = Util.readDate(in);
129 String reference = Util.readString(in, 21).trim();
130 BookDeleteTypeEnum deleteType = Util.readBookDeleteTypeEnum(in);
131 TradeSideEnum side = Util.readTradeSideEnum(in);
132
133 return new OTBookDelete(timestamp,
134 reference, deleteType, side);
135 }
136
137 /**
138 * Creates reader for the BookCancel event.
139 */
140 public static final BookReader cancelReader(
141 final IDataDelegate<OTBookCancel> dataDelegate) {
142
143 return new BookReader(DataEnum.BOOK_CANCEL) {
144 @Override
145 public void read(Header header, ByteBuffer in) {
146 OTBookCancel data = readCancel(in);
147 dataDelegate.onData(data);
148 }
149 };
150 }
151
152 private final static OTBookCancel readCancel(ByteBuffer in) {
153 Date timestamp = Util.readDate(in);
154 String reference = Util.readString(in, 21).trim();
155 int size = in.getInt();
156
157 return new OTBookCancel(timestamp, reference, size);
158 }
159
160 /**
161 * Creates reader for the BookChange event.
162 */
163 public static final BookReader changeReader(
164 final IDataDelegate<OTBookChange> dataDelegate) {
165
166 return new BookReader(DataEnum.BOOK_CHANGE) {
167 @Override
168 public void read(Header header, ByteBuffer in) {
169 OTBookChange data = readChange(in);
170 dataDelegate.onData(data);
171 }
172 };
173 }
174
175 private final static OTBookChange readChange(ByteBuffer in) {
176 Date timestamp = Util.readDate(in);
177 String reference = Util.readString(in, 21).trim();
178 double price = in.getDouble();
179 int size = in.getInt();
180
181 return new OTBookChange(timestamp, reference, price, size);
182 }
183
184 /**
185 * Creates reader for the BookChange event.
186 */
187 public static final BookReader replaceReader(
188 final IDataDelegate<OTBookReplace> dataDelegate) {
189
190 return new BookReader(DataEnum.BOOK_REPLACE) {
191 @Override
192 public void read(Header header, ByteBuffer in) {
193 OTBookReplace data = readReplace(in);
194 dataDelegate.onData(data);
195 }
196 };
197 }
198
199 private final static OTBookReplace readReplace(ByteBuffer in) {
200 Date timestamp = Util.readDate(in);
201 String reference = Util.readString(in, 21).trim();
202 double price = in.getDouble();
203 int size = in.getInt();
204 TradeSideEnum side = Util.readTradeSideEnum(in);
205
206 return new OTBookReplace(timestamp, reference, price, size, side);
207 }
208
209 /**
210 * Creates reader for the BookPurge event.
211 */
212 public static final BookReader purgeReader(
213 final IDataDelegate<OTBookPurge> dataDelegate) {
214
215 return new BookReader(DataEnum.BOOK_PURGE) {
216 @Override
217 public void read(Header header, ByteBuffer in) {
218 OTBookPurge data = readPurge(in);
219 dataDelegate.onData(data);
220 }
221 };
222 }
223
224 private final static OTBookPurge readPurge(ByteBuffer in) {
225 Date timestamp = Util.readDate(in);
226 String nameRoot = Util.readString(in, 3).trim();
227
228 return new OTBookPurge(timestamp, nameRoot);
229 }
230
231 /**
232 * Creates reader for the BookPriceLevel event.
233 */
234 public static final BookReader priceLevelReader(
235 final IDataDelegate<OTBookPriceLevel> dataDelegate) {
236
237 return new BookReader(DataEnum.BOOK_PRICE_LEVEL) {
238 @Override
239 public void read(Header header, ByteBuffer in) {
240 OTBookPriceLevel data = readPriceLevel(in);
241 dataDelegate.onData(data);
242 }
243 };
244 }
245
246 private final static OTBookPriceLevel readPriceLevel(ByteBuffer in) {
247 Date timestamp = Util.readDate(in);
248 double price = in.getDouble();
249 int size = in.getInt();
250 TradeSideEnum side = Util.readTradeSideEnum(in);
251 String levelID = Util.readString(in, 4).trim();
252
253 return new OTBookPriceLevel(timestamp,
254 price, size, side, levelID);
255 }
256 }
257
258