File Coverage

blib/lib/POE/Component/Client/opentick/Constants.pm
Criterion Covered Total %
statement 113 124 91.1
branch 21 32 65.6
condition 11 18 61.1
subroutine 31 32 96.8
pod 23 23 100.0
total 199 229 86.9


line stmt bran cond sub pod time code
1             package POE::Component::Client::opentick::Constants;
2             #
3             # opentick.com POE client
4             #
5             # Protocol constants
6             #
7             # infi/2008
8             #
9             # $Id: Constants.pm 56 2009-01-08 16:51:14Z infidel $
10             #
11             # Full POD documentation after __END__
12             #
13             # NOTE: This is deep hackery, and thus ugly. But, I'm trying to do
14             # the Right Thing(tm).
15             #
16              
17 6     6   104838 use strict;
  6         31  
  6         202  
18 6     6   32 use warnings;
  6         12  
  6         220  
19 6     6   35 use Carp qw( carp );
  6         9  
  6         449  
20             $Carp::CarpLevel = 1;
21 6     6   33 use Data::Dumper;
  6         9  
  6         509  
22              
23 6     6   32 use vars qw( $VERSION $TRUE $FALSE );
  6         17  
  6         1260  
24              
25             BEGIN {
26 6     6   36 require Exporter;
27 6         110 our @ISA = qw( Exporter );
28 6         36 our @EXPORT = qw( OTConstant OTCommand OTDefault OTCancel OTTemplate
29             OTResponses OTCmdStatus OTMsgType OTEvent OTEventList
30             OTEventByEvent OTEventByCommand OTAPItoCommand OTeod
31             OTCommandList OTDatatype OTCommandtoAPI OT64bit
32             OTCanceller OTTradeIndicator OTQuoteIndicator
33             has_otlib );
34 6         4379 ($VERSION) = q$Revision: 56 $ =~ /(\d+)/;
35             }
36              
37             ###
38             ### Variables
39             ###
40              
41             *TRUE = \1;
42             *FALSE = \0;
43              
44             my $OTLIB_FOUND; # Boolean, TRUE if official library is found
45             my $PERL_64BIT_INT; # Boolean, TRUE if we have 64 bit integers
46             my $OTConstants; # Most of the constants from the library
47             my $OTTemplates; # pack/unpack templates
48             my $OTResponses; # Counts of responses to various requests
49             my $OTDefaults; # Default settings for the main client
50             our $OTCommands; # Command number => name mapping
51             our $OTDatatypes; # Datatype number => name mapping
52             my $OTCancels; # Cancellation command mapping
53             my $OTEvents; # Event alias => name mapping
54             my $OTCommandEvents; # Command => event mapping
55             my $OTAPItoCommands; # API => command mapping
56             my $OTTradeIndicators; # Trade Indicator mapping
57             my $OTQuoteIndicators; # Quote Indicator mapping
58             my $OTDeprecated; # Deprecated method -> replacement mapping
59             my $OT64bit; # COMPLETE HACK; simulate 64bit on 32bit
60              
61             # Check for 64-bit support in our perl.
62             BEGIN {
63 6     6   15 eval{
64 6         111 my $foo = unpack("D","");
65             };
66 6 50       1183 $PERL_64BIT_INT = $@ ? 0 : 1;
67             }
68              
69             # Try to find the official library to use its constants.
70             BEGIN {
71             # Check if the OPENTICK_LIB envvar is set, and prepend it to @INC.
72 6 0 33 6   63 if( defined( $ENV{OPENTICK_LIB} ) && length( $ENV{OPENTICK_LIB} )
      33        
73             && ( -d $ENV{OPENTICK_LIB} ) )
74             {
75 0         0 unshift( @INC, $ENV{OPENTICK_LIB} );
76             }
77             # Check @INC
78             eval
79 6         12 {
80 6     6   45 no warnings;
  6         9  
  6         5573  
81 6         3578 require opentick::OTConstants;
82             };
83 6 50       36 unless( $@ )
84             {
85             # Official lib is present in @INC, snarf its constants.
86 0         0 for( keys( %opentick::OTConstants:: ) )
87             {
88 0 0       0 next unless /^OT_/;
89 0         0 $OTConstants->{ $_ } = ${ $opentick::OTConstants::{ $_ } };
  0         0  
90             }
91 0         0 $OTLIB_FOUND = 1;
92             }
93             else
94             {
95             # Official lib not found in @INC. Seed with our own values.
96 6         11 $OTLIB_FOUND = 0;
97             # carp( "OT:WARN: Official opentick lib not found; using built-in constants.\n" );
98 6         585 $OTConstants = {
99             OT_CANCEL_MESSAGE => 'Request cancelled',
100              
101             # Force protocol version 4 later.
102             # OT_PROTOCOL_VER => 4,
103              
104             OT_MES_REQUEST => 1,
105             OT_MES_RESPONSE => 2,
106              
107             OT_MSG_END_OF_DATA => 10,
108             OT_MSG_END_OF_REQUEST => 20,
109             OT_MSG_END_OF_SNAPSHOT => 30,
110              
111             OT_STATUS_OK => 1,
112             OT_STATUS_ERROR => 2,
113              
114             OT_STATUS_INACTIVE => 1,
115             OT_STATUS_CONNECTING => 2,
116             OT_STATUS_CONNECTED => 3,
117             OT_STATUS_LOGGED_IN => 4,
118              
119             OT_INSTRUMENT_STOCK => 1,
120             OT_INSTRUMENT_INDEX => 2,
121             OT_INSTRUMENT_FUTURE => 4,
122             OT_INSTRUMENT_OPTION => 3,
123              
124             OT_TICK_TYPE_QUOTE => 1,
125             OT_TICK_TYPE_MMQUOTE => 2,
126             OT_TICK_TYPE_TRADE => 3,
127             OT_TICK_TYPE_BBO => 4,
128              
129             OT_MASK_TYPE_QUOTE => 1,
130             OT_MASK_TYPE_MMQUOTE => 2,
131             OT_MASK_TYPE_TRADE => 4,
132             OT_MASK_TYPE_BBO => 8,
133             OT_MASK_TYPE_LEVEL1 => 13,
134             OT_MASK_TYPE_LEVEL2 => 2,
135             OT_MASK_TYPE_BOTH => 15,
136             OT_MASK_TYPE_ALL => 15,
137              
138             OT_BOOK_TYPE_CANCEL => 5,
139             OT_BOOK_TYPE_CHANGE => 6,
140             OT_BOOK_TYPE_DELETE => 7,
141             OT_BOOK_TYPE_EXECUTE => 8,
142             OT_BOOK_TYPE_ORDER => 9,
143             OT_BOOK_TYPE_LEVEL => 10,
144             OT_BOOK_TYPE_PURGE => 11,
145             OT_BOOK_TYPE_REPLACE => 12,
146            
147             OT_DELETE_TYPE_ORDER => '1',
148             OT_DELETE_TYPE_PREVIOUS => '2',
149             OT_DELETE_TYPE_ALL => '3',
150             OT_DELETE_TYPE_AFTER => 'A',
151              
152             OT_FLAG_OPEN => 1,
153             OT_FLAG_HIGH => 2,
154             OT_FLAG_LOW => 4,
155             OT_FLAG_CLOSE => 8,
156             OT_FLAG_UPDATE_LAST => 16,
157             OT_FLAG_UPDATE_VOLUME => 32,
158             OT_FLAG_CANCEL => 64,
159             OT_FLAG_FROM_BOOK => 128,
160              
161             OT_HIST_RAW_TICKS => 1,
162             OT_HIST_OHLC_TICK_BASED => 2,
163             OT_HIST_OHLC_MINUTELY => 3,
164             OT_HIST_OHLC_HOURLY => 4,
165             OT_HIST_OHLC_DAILY => 5,
166             OT_HIST_OHLC_WEEKLY => 6,
167             OT_HIST_OHLC_MONTHLY => 7,
168             OT_HIST_OHLC_YEARLY => 8,
169             OT_HIST_OHL_TODAY => 9,
170              
171             OT_HIST_CODE_EOD => 0,
172             OT_HIST_CODE_TICK_QUOTE => 1,
173             OT_HIST_CODE_TICK_MMQUOTE => 2,
174             OT_HIST_CODE_TICK_TRADE => 3,
175             OT_HIST_CODE_TICK_BBO => 4,
176             OT_HIST_CODE_OHLC => 50,
177             OT_HIST_CODE_OHL_TODAY => 51,
178              
179             OT_INT_UNKNOWN => 0,
180             OT_LOGIN => 1,
181             OT_LOGOUT => 2,
182             OT_REQUEST_TICK_STREAM => 3, # Deprecated, use _EX
183             OT_REQUEST_TICK_STREAM_EX => 15,
184             OT_CANCEL_TICK_STREAM => 4,
185             OT_REQUEST_HIST_DATA => 5,
186             OT_REQUEST_HIST_TICKS => 17,
187             OT_CANCEL_HIST_DATA => 6,
188             OT_REQUEST_LIST_EXCHANGES => 7,
189             OT_REQUEST_LIST_SYMBOLS => 8,
190             OT_HEARTBEAT => 9,
191             OT_REQUEST_EQUITY_INIT => 10,
192             OT_REQUEST_OPTION_CHAIN => 11, # Deprecated, use _EX
193             OT_REQUEST_OPTION_CHAIN_EX => 16,
194             OT_CANCEL_OPTION_CHAIN => 12,
195             OT_REQUEST_BOOK_STREAM => 13,
196             OT_CANCEL_BOOK_STREAM => 14,
197              
198             OT_ERR_OPENTICK => 1000,
199             OT_ERR_SYSTEM => 2000,
200             OT_ERR_SOCK => 3000,
201              
202             OT_ERR_BAD_LOGIN => 1001,
203             OT_ERR_NOT_LOGGED_IN => 1002,
204             OT_ERR_NO_DATA => 1003,
205             OT_ERR_INVALID_CANCEL_ID => 1004,
206             OT_ERR_INVALID_INTERVAL => 1005,
207             OT_ERR_NO_LICENSE => 1006,
208             OT_ERR_LIMIT_EXCEEDED => 1007,
209             OT_ERR_DUPLICATE_REQUEST => 1008,
210             OT_ERR_INACTIVE_ACCOUNT => 1009,
211             OT_ERR_LOGGED_IN => 1010,
212             OT_ERR_BAD_REQUEST => 1011,
213             OT_ERR_NO_HIST_PACKAGE => 1012,
214             OT_ERR_SERVER_ERROR => 2002,
215             OT_ERR_CANNOT_CONNECT => 2003,
216             OT_ERR_BROKEN_CONNECTION => 2004,
217             OT_ERR_NO_THREAD => 2005,
218             OT_ERR_NO_SOCKET => 2006,
219              
220             OT_OS_UNKNOWN => 1,
221             OT_OS_WIN95 => 2,
222             OT_OS_WIN98 => 3,
223             OT_OS_WIN98SE => 4,
224             OT_OS_WINME => 5,
225             OT_OS_WINNT => 6,
226             OT_OS_WIN2000 => 7,
227             OT_OS_WINXP => 8,
228             OT_OS_LINUX => 20,
229              
230             OT_PLATFORM_OT => 1,
231             OT_PLATFORM_WEALTHLAB => 3,
232             OT_PLATFORM_QUANTSTUDIO => 2,
233             OT_PLATFORM_JAVA => 7,
234             };
235             } # END otlib parsing
236              
237             # Newer constants -- not included in perl otFeed OTConstants.pm distro
238             # So we'll set them regardless of constant source.
239 6         18 $OTConstants->{OT_ERR_RECEIVE} = 3001;
240 6         11 $OTConstants->{OT_REQUEST_SPLITS} = 18;
241 6         12 $OTConstants->{OT_REQUEST_DIVIDENDS} = 19;
242 6         19 $OTConstants->{OT_REQUEST_HIST_BOOKS} = 20;
243 6         11 $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} = 21;
244 6         18 $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} = 22;
245 6         10 $OTConstants->{OT_REQUEST_OPTION_INIT} = 23;
246 6         10 $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} = 24;
247 6         18 $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} = 25;
248 6         13 $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} = 26;
249              
250             # Force this to 4, overriding the built-in constant values.
251 6         10 $OTConstants->{OT_PROTOCOL_VER} = 4;
252              
253             ####### My own extensions #######
254             ### Response counts
255 6         17 $OTConstants->{OT_RESPONSES_NONE} = 0;
256 6         69 $OTConstants->{OT_RESPONSES_ONE} = 1;
257 6         16 $OTConstants->{OT_RESPONSES_FINITE} = 2;
258 6         11 $OTConstants->{OT_RESPONSES_CONTINUOUS} = 3;
259             ### Data types
260 6         12 $OTConstants->{OT_DATATYPE_EOD} = 0;
261             # Misc
262 6         12 $OTConstants->{OT_DATATYPE_QUOTE} = 1;
263 6         8 $OTConstants->{OT_DATATYPE_MMQUOTE} = 2;
264 6         13 $OTConstants->{OT_DATATYPE_TRADE} = 3;
265 6         11 $OTConstants->{OT_DATATYPE_BBO} = 4;
266             # RequestBook*, RequestOption*, RequestTick*
267 6         9 $OTConstants->{OT_DATATYPE_CANCEL} = 5;
268 6         10 $OTConstants->{OT_DATATYPE_CHANGE} = 6;
269 6         13 $OTConstants->{OT_DATATYPE_DELETE} = 7;
270 6         8 $OTConstants->{OT_DATATYPE_EXECUTE} = 8;
271 6         17 $OTConstants->{OT_DATATYPE_ORDER} = 9;
272 6         11 $OTConstants->{OT_DATATYPE_PRICELEVEL} = 10;
273 6         15 $OTConstants->{OT_DATATYPE_PURGE} = 11;
274 6         11 $OTConstants->{OT_DATATYPE_REPLACE} = 12;
275 6         10 $OTConstants->{OT_DATATYPE_HALT} = 13;
276 6         10 $OTConstants->{OT_DATATYPE_SPLIT} = 14;
277 6         15 $OTConstants->{OT_DATATYPE_DIVIDEND} = 15;
278 6         9 $OTConstants->{OT_DATATYPE_EQ_INIT} = 17;
279 6         10 $OTConstants->{OT_DATATYPE_EQUITY_INIT} = 17; # Alias
280 6         14 $OTConstants->{OT_DATATYPE_OPTION_INIT} = 18;
281 6         44 $OTConstants->{OT_DATATYPE_OHLC} = 50;
282 6         14 $OTConstants->{OT_DATATYPE_OHL_TODAY} = 51;
283              
284             # Fill the reverse command map early for other modules.
285 6         44 my @cmds = qw( OT_INT_UNKNOWN OT_LOGIN OT_LOGOUT OT_HEARTBEAT
286             OT_REQUEST_TICK_STREAM OT_REQUEST_TICK_STREAM_EX
287             OT_CANCEL_TICK_STREAM OT_REQUEST_HIST_DATA
288             OT_REQUEST_HIST_TICKS OT_CANCEL_HIST_DATA
289             OT_REQUEST_LIST_EXCHANGES OT_REQUEST_LIST_SYMBOLS
290             OT_REQUEST_EQUITY_INIT OT_REQUEST_OPTION_CHAIN
291             OT_REQUEST_OPTION_CHAIN_EX OT_CANCEL_OPTION_CHAIN
292             OT_REQUEST_BOOK_STREAM OT_CANCEL_BOOK_STREAM
293             OT_REQUEST_SPLITS OT_REQUEST_DIVIDENDS
294             OT_REQUEST_HIST_BOOKS OT_REQUEST_BOOK_STREAM_EX
295             OT_REQUEST_OPTION_CHAIN_U OT_REQUEST_OPTION_INIT
296             OT_REQUEST_LIST_SYMBOLS_EX OT_REQUEST_TICK_SNAPSHOT
297             OT_REQUEST_OPTION_CHAIN_SNAPSHOT );
298 6         302 $OTCommands->{ $OTConstants->{$_} } = $_ for( @cmds );
299              
300             # Fill in the reverse datatype map
301 6         49 my @dts = qw( OT_DATATYPE_EOD OT_DATATYPE_QUOTE
302             OT_DATATYPE_MMQUOTE OT_DATATYPE_TRADE
303             OT_DATATYPE_BBO OT_DATATYPE_SPLIT
304             OT_DATATYPE_DIVIDEND OT_DATATYPE_OPTION_INIT
305             OT_DATATYPE_OHLC OT_DATATYPE_OHL_TODAY
306             OT_DATATYPE_CANCEL OT_DATATYPE_CHANGE
307             OT_DATATYPE_DELETE OT_DATATYPE_EXECUTE
308             OT_DATATYPE_ORDER OT_DATATYPE_PRICELEVEL
309             OT_DATATYPE_PURGE OT_DATATYPE_REPLACE );
310 6         17687 $OTDatatypes->{ $OTConstants->{$_} } = $_ for( @dts );
311              
312             # Commands that cancel other requests.
313 6         16067 $OTCancels = {
314             $OTConstants->{OT_CANCEL_TICK_STREAM} => {
315             $OTConstants->{OT_REQUEST_TICK_STREAM} => 1,
316             $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => 1,
317             },
318             $OTConstants->{OT_CANCEL_HIST_DATA} => {
319             $OTConstants->{OT_REQUEST_HIST_DATA} => 1,
320             $OTConstants->{OT_REQUEST_HIST_TICKS} => 1,
321             },
322             $OTConstants->{OT_CANCEL_OPTION_CHAIN} => {
323             $OTConstants->{OT_REQUEST_OPTION_CHAIN} => 1,
324             $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => 1,
325             },
326             $OTConstants->{OT_CANCEL_BOOK_STREAM} => {
327             $OTConstants->{OT_REQUEST_BOOK_STREAM} => 1,
328             $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => 1,
329             },
330             };
331              
332             } # /BEGIN
333              
334              
335             # Templates for pack() and unpack()
336             $OTTemplates = {
337             # basic templates
338             MSG_LENGTH => 'V',
339             HEADER => 'C C x x V V',
340             ERROR => 'v v a*',
341             # templates for command message bodies
342             cmds => {
343             $OTConstants->{OT_LOGIN} => 'v C C a16 a6 a64 a64',
344             $OTConstants->{OT_LOGOUT} => 'a64',
345             $OTConstants->{OT_REQUEST_TICK_STREAM} => 'a64 a15 a15',
346             $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => 'a64 a15 a15 x x V',
347             $OTConstants->{OT_REQUEST_HIST_DATA} => 'a64 a15 a15 x x V V C x v',
348             $OTConstants->{OT_REQUEST_HIST_TICKS} => 'a64 a15 a15 V V V',
349             $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => 'a64',
350             $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => 'a64 a15',
351             $OTConstants->{OT_REQUEST_EQUITY_INIT} => 'a64 a15 a15',
352             $OTConstants->{OT_REQUEST_OPTION_CHAIN} => 'a64 a15 a15 v V',
353             $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => 'a64 a15 a15 v V V',
354             $OTConstants->{OT_REQUEST_BOOK_STREAM} => 'a64 a15 a15',
355             $OTConstants->{OT_HEARTBEAT} => '', # none
356             $OTConstants->{OT_CANCEL_TICK_STREAM} => 'a64 V',
357             $OTConstants->{OT_CANCEL_HIST_DATA} => 'a64 V',
358             $OTConstants->{OT_CANCEL_OPTION_CHAIN} => 'a64 V',
359             $OTConstants->{OT_CANCEL_BOOK_STREAM} => 'a64 V',
360             # NEW!
361             $OTConstants->{OT_REQUEST_SPLITS} => 'a64 a15 a15 V V',
362             $OTConstants->{OT_REQUEST_DIVIDENDS} => 'a64 a15 a15 V V',
363             $OTConstants->{OT_REQUEST_HIST_BOOKS} => 'a64 a15 a15 V V V',
364             $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => 'a64 a15 a15 x x V',
365             $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => 'a64 a15 a15 v V V d d V',
366             $OTConstants->{OT_REQUEST_OPTION_INIT} => 'a64 a15 a15 v V d d V',
367             $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => 'a64 a15 a15 V',
368             $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => 'a64 a15 a15 x x V',
369             $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => 'a64 a15 a15 v V V d d V',
370             },
371             # templates for command response bodies
372             resp => {
373             $OTConstants->{OT_LOGIN} => 'a64 C Z64 v',
374             $OTConstants->{OT_LOGOUT} => '', # none
375             $OTConstants->{OT_REQUEST_TICK_STREAM} => '', # unneeded
376             $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => '', # unneeded
377             $OTConstants->{OT_REQUEST_HIST_DATA} => 'V', # + datatype
378             $OTConstants->{OT_REQUEST_HIST_TICKS} => 'V', # + datatype
379             $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => 'v/Z',
380             $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => 'Z4 Z15 C v/Z',
381             # Requires 64-bit int support built into Perl, but we'll simulate it.
382             $OTConstants->{OT_REQUEST_EQUITY_INIT} =>
383             $PERL_64BIT_INT
384             ? 'C a3 C Z80 d a8 d a8 d a8 d a8 D D a9 a12 C C C'
385             : 'C a3 C Z80 d a8 d a8 d a8 d a8 a8 a8 a9 a12 C C C',
386             $OTConstants->{OT_REQUEST_OPTION_CHAIN} => '',
387             $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => '',
388             $OTConstants->{OT_REQUEST_BOOK_STREAM} => '',
389             $OTConstants->{OT_HEARTBEAT} => '', # none
390             $OTConstants->{OT_CANCEL_TICK_STREAM} => '',
391             $OTConstants->{OT_CANCEL_HIST_DATA} => '',
392             $OTConstants->{OT_CANCEL_OPTION_CHAIN} => '',
393             $OTConstants->{OT_CANCEL_BOOK_STREAM} => '',
394             # NEW!
395             $OTConstants->{OT_REQUEST_SPLITS} => 'C V V V V V V',
396             $OTConstants->{OT_REQUEST_DIVIDENDS} => 'C d V V V V a a',
397             $OTConstants->{OT_REQUEST_HIST_BOOKS} => '',
398             $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => '',
399             $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => '',
400             $OTConstants->{OT_REQUEST_OPTION_INIT} => 'C Z12 Z12 d V a4 a2 a2 a a9 a3 a',
401             $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => '',
402             $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => '',
403             $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => '',
404             },
405             datatype => {
406             $OTConstants->{OT_DATATYPE_EOD} => 'C',
407             $OTConstants->{OT_DATATYPE_QUOTE} => 'C V V V d d a2 a a',
408             $OTConstants->{OT_DATATYPE_MMQUOTE} => 'C V V V d d a4 a',
409             # XXX: The 'a8' in the next line should actually be a D.
410             # Requires 64-bit int support built into Perl, but we'll simulate it.
411             $OTConstants->{OT_DATATYPE_TRADE} =>
412             $PERL_64BIT_INT
413             ? 'C V d V D V a a C'
414             : 'C V d V a8 V a a C',
415             $OTConstants->{OT_DATATYPE_BBO} => 'C V d V a',
416             $OTConstants->{OT_DATATYPE_OHLC} =>
417             $PERL_64BIT_INT
418             ? 'C V d d d d D'
419             : 'C V d d d d a8',
420             $OTConstants->{OT_DATATYPE_OHL_TODAY} => 'C d d d',
421             # requestBookStream*, requestOptionChain*, requestHistBooks
422             $OTConstants->{OT_DATATYPE_CANCEL} => 'C V Z21 V',
423             $OTConstants->{OT_DATATYPE_CHANGE} => 'C V Z21 d V',
424             $OTConstants->{OT_DATATYPE_DELETE} => 'C V Z21 C C',
425             $OTConstants->{OT_DATATYPE_EXECUTE} => 'C V Z21 V V',
426             $OTConstants->{OT_DATATYPE_ORDER} => 'C V Z21 d V C C',
427             $OTConstants->{OT_DATATYPE_PRICELEVEL} => 'C V d V C a4',
428             $OTConstants->{OT_DATATYPE_PURGE} => 'C V a3',
429             $OTConstants->{OT_DATATYPE_REPLACE} => 'C V Z21 d V C',
430             },
431             };
432              
433             # A complete hack. Needed to simulate 64-bit integers in 32-bits.
434             $OT64bit = {
435             $OTConstants->{OT_DATATYPE_TRADE} => [ 4 ],
436             $OTConstants->{OT_DATATYPE_OHLC} => [ 6 ],
437             # This next key seems odd, but is actually correctly numbered.
438             $OTConstants->{OT_DATATYPE_EQUITY_INIT} => [ 12, 13 ],
439             };
440              
441             # Number of response packets to this request
442             $OTResponses = {
443             $OTConstants->{OT_LOGIN} => $OTConstants->{OT_RESPONSES_ONE},
444             $OTConstants->{OT_LOGOUT} => $OTConstants->{OT_RESPONSES_ONE},
445             $OTConstants->{OT_REQUEST_TICK_STREAM} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
446             $OTConstants->{OT_CANCEL_TICK_STREAM} => $OTConstants->{OT_RESPONSES_ONE},
447             $OTConstants->{OT_REQUEST_HIST_DATA} => $OTConstants->{OT_RESPONSES_FINITE},
448             $OTConstants->{OT_CANCEL_HIST_DATA} => $OTConstants->{OT_RESPONSES_ONE},
449             $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => $OTConstants->{OT_RESPONSES_FINITE},
450             $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => $OTConstants->{OT_RESPONSES_FINITE},
451             $OTConstants->{OT_HEARTBEAT} => $OTConstants->{OT_RESPONSES_NONE},
452             $OTConstants->{OT_REQUEST_EQUITY_INIT} => $OTConstants->{OT_RESPONSES_ONE},
453             $OTConstants->{OT_REQUEST_OPTION_CHAIN} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
454             $OTConstants->{OT_CANCEL_OPTION_CHAIN} => $OTConstants->{OT_RESPONSES_ONE},
455             $OTConstants->{OT_REQUEST_BOOK_STREAM} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
456             $OTConstants->{OT_CANCEL_BOOK_STREAM} => $OTConstants->{OT_RESPONSES_ONE},
457             $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
458             $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
459             $OTConstants->{OT_REQUEST_HIST_TICKS} => $OTConstants->{OT_RESPONSES_FINITE},
460             # NEW!
461             $OTConstants->{OT_REQUEST_SPLITS} => $OTConstants->{OT_RESPONSES_FINITE},
462             $OTConstants->{OT_REQUEST_DIVIDENDS} => $OTConstants->{OT_RESPONSES_FINITE},
463             $OTConstants->{OT_REQUEST_HIST_BOOKS} => $OTConstants->{OT_RESPONSES_FINITE},
464             $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
465             $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
466             $OTConstants->{OT_REQUEST_OPTION_INIT} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
467             $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => $OTConstants->{OT_RESPONSES_FINITE},
468             $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
469             $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => $OTConstants->{OT_RESPONSES_CONTINUOUS},
470             };
471              
472             # opentick client defaults, most can be overridden.
473             $OTDefaults = {
474             # POE defaults
475             alias => 'opentick', # default POE alias
476             # network/socket defaults
477             servers_realtime => [ qw( feed1.opentick.com feed2.opentick.com ) ],
478             servers_delayed => [ qw( delayed1.opentick.com delayed2.opentick.com ) ],
479             port_realtime => 10010, # port for realtime data
480             port_delayed => 10015, # port for delayed data
481             realtime => $FALSE, # request realtime data
482             # Connection defaults
483             autologin => $TRUE, # Automatically log in?
484             conntimeout => 30, # Timeout for connect()
485             autoreconnect => $TRUE, # Automatically reconnect?
486             reconninterval => 60, # Reconn interval in seconds
487             reconnretries => 5, # Retries before giving up
488             # Protocol defaults
489             heartbeat => 15, # delay in seconds for beats
490             protocolver => $OTConstants->{ 'OT_PROTOCOL_VER' },
491             platform => $OTConstants->{ 'OT_PLATFORM_OT' },
492             platformpass => '',
493             os => $OTConstants->{ 'OT_OS_LINUX' },
494             macaddr => '08:00:02:01:02:03', # 3Com, heh
495             apitimeout => 30, # Time out for API commands
496             # LAME
497             request_timeout => 30, # Time before expunging
498             # ListSymbols or ListExch*
499             };
500              
501             # symbolic event name to actual POE event name map.
502             $OTEvents = {
503             OT_ON_LOGIN => 'ot_on_login',
504             OT_ON_ERROR => 'ot_on_error',
505             OT_ON_DATA => 'ot_on_data',
506             OT_ON_LOGOUT => 'ot_on_logout',
507             OT_REQUEST_COMPLETE => 'ot_request_complete',
508             OT_REQUEST_CANCELLED => 'ot_request_cancelled',
509             OT_CONNECT_FAILED => 'ot_connect_failed',
510             OT_STATUS_CHANGED => 'ot_status_changed',
511             };
512              
513             # integral command number to POE event name map.
514             $OTCommandEvents = {
515             $OTConstants->{OT_INT_UNKNOWN} => $OTEvents->{OT_ON_ERROR},
516             $OTConstants->{OT_LOGIN} => $OTEvents->{OT_ON_LOGIN},
517             $OTConstants->{OT_LOGOUT} => $OTEvents->{OT_ON_LOGOUT},
518             $OTConstants->{OT_REQUEST_TICK_STREAM} => $OTEvents->{OT_ON_DATA},
519             $OTConstants->{OT_CANCEL_TICK_STREAM} => $OTEvents->{OT_REQUEST_CANCELLED},
520             $OTConstants->{OT_REQUEST_HIST_DATA} => $OTEvents->{OT_ON_DATA},
521             $OTConstants->{OT_CANCEL_HIST_DATA} => $OTEvents->{OT_REQUEST_CANCELLED},
522             $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => $OTEvents->{OT_ON_DATA},
523             $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => $OTEvents->{OT_ON_DATA},
524             $OTConstants->{OT_HEARTBEAT} => undef,
525             $OTConstants->{OT_REQUEST_EQUITY_INIT} => $OTEvents->{OT_ON_DATA},
526             $OTConstants->{OT_REQUEST_OPTION_CHAIN} => $OTEvents->{OT_ON_DATA},
527             $OTConstants->{OT_CANCEL_OPTION_CHAIN} => $OTEvents->{OT_REQUEST_CANCELLED},
528             $OTConstants->{OT_REQUEST_BOOK_STREAM} => $OTEvents->{OT_ON_DATA},
529             $OTConstants->{OT_CANCEL_BOOK_STREAM} => $OTEvents->{OT_REQUEST_CANCELLED},
530             $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => $OTEvents->{OT_ON_DATA},
531             $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => $OTEvents->{OT_ON_DATA},
532             $OTConstants->{OT_REQUEST_HIST_TICKS} => $OTEvents->{OT_ON_DATA},
533             $OTConstants->{OT_REQUEST_SPLITS} => $OTEvents->{OT_ON_DATA},
534             $OTConstants->{OT_REQUEST_DIVIDENDS} => $OTEvents->{OT_ON_DATA},
535             $OTConstants->{OT_REQUEST_HIST_BOOKS} => $OTEvents->{OT_ON_DATA},
536             $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => $OTEvents->{OT_ON_DATA},
537             $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => $OTEvents->{OT_ON_DATA},
538             $OTConstants->{OT_REQUEST_OPTION_INIT} => $OTEvents->{OT_ON_DATA},
539             $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => $OTEvents->{OT_ON_DATA},
540             $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => $OTEvents->{OT_ON_DATA},
541             $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => $OTEvents->{OT_ON_DATA},
542             };
543              
544             # API method name to command number map
545             $OTAPItoCommands = {
546             'requestSplits' => $OTConstants->{OT_REQUEST_SPLITS},
547             'requestDividends' => $OTConstants->{OT_REQUEST_DIVIDENDS},
548             'requestOptionInit' => $OTConstants->{OT_REQUEST_OPTION_INIT},
549             'requestHistData' => $OTConstants->{OT_REQUEST_HIST_DATA},
550             'requestHistTicks' => $OTConstants->{OT_REQUEST_HIST_TICKS},
551             'requestTickStream' => $OTConstants->{OT_REQUEST_TICK_STREAM},
552             'requestTickStreamEx' => $OTConstants->{OT_REQUEST_TICK_STREAM_EX},
553             'requestTickSnapshot' => $OTConstants->{OT_REQUEST_TICK_SNAPSHOT},
554             'requestOptionChain' => $OTConstants->{OT_REQUEST_OPTION_CHAIN},
555             'requestOptionChainEx' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX},
556             'requestOptionChainU' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_U},
557             'requestOptionChainSnapshot' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT},
558             'requestEqInit' => $OTConstants->{OT_REQUEST_EQUITY_INIT},
559             'requestEquityInit' => $OTConstants->{OT_REQUEST_EQUITY_INIT},
560             'requestBookStream' => $OTConstants->{OT_REQUEST_BOOK_STREAM},
561             'requestBookStreamEx' => $OTConstants->{OT_REQUEST_BOOK_STREAM_EX},
562             'requestHistBooks' => $OTConstants->{OT_REQUEST_HIST_BOOKS},
563             'requestListSymbols' => $OTConstants->{OT_REQUEST_LIST_SYMBOLS},
564             'requestListSymbolsEx' => $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX},
565             'requestListExchanges' => $OTConstants->{OT_REQUEST_LIST_EXCHANGES},
566             'cancelTickStream' => $OTConstants->{OT_CANCEL_TICK_STREAM},
567             'cancelHistData' => $OTConstants->{OT_CANCEL_HIST_DATA},
568             'cancelOptionChain' => $OTConstants->{OT_CANCEL_OPTION_CHAIN},
569             'cancelBookStream' => $OTConstants->{OT_CANCEL_BOOK_STREAM},
570             };
571              
572             # Deprecated methods and their suggested replacements
573             $OTDeprecated = {
574             $OTConstants->{OT_REQUEST_TICK_STREAM}
575             => $OTConstants->{OT_REQUEST_TICK_STREAM_EX},
576             $OTConstants->{OT_REQUEST_OPTION_CHAIN}
577             => $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX},
578             };
579              
580             $OTTradeIndicators = {
581             '@' => 'Regular Trade',
582             A => 'Acquisition - Cash',
583             B => 'Bunched Trade - Average Price',
584             C => 'Cash Trade',
585             D => 'Distribution - Next Day Market',
586             E => 'Automatic Execution',
587             F => 'Intermarket Sweep Order',
588             G => 'Bunched Sold Trade - Opening/Reopening Trade Detail',
589             H => 'Intraday Trade Detail',
590             I => 'Basket Index on Close Transaction',
591             J => 'Rule 127 Trade (NYSE only)',
592             K => 'Rule 155 Trade (AMEX only)',
593             L => 'Sold Last',
594             N => 'Next Day',
595             O => 'Opened',
596             P => 'Prior Reference Price',
597             R => 'Seller',
598             S => 'Split Trade',
599             T => 'Form-T Trade - Pre/Post Market Trade',
600             W => 'Average Price Trade',
601             Z => 'Sold (Out of Sequence)',
602             };
603              
604             $OTQuoteIndicators = {
605             A => 'Depth on Ask side',
606             B => 'Depth on Bid side',
607             C => 'Closing',
608             D => 'News Dissemination',
609             E => 'Order Influx',
610             F => 'Fast Trading',
611             G => 'Trading Range Indication',
612             H => 'Depth on Bid and Ask',
613             I => 'Order Imbalance',
614             J => 'Due to Related Security-news Dissemination',
615             K => 'Due to Related Security-news Pending',
616             L => 'Closed Market Maker (NASDAQ)',
617             M => 'No Eligible Market Participant Quotes in Issue at Market Close',
618             N => 'Non-Firm Quote',
619             O => 'Opening Quote',
620             P => 'News Pending',
621             Q => 'Additional Information-Due To Related Security',
622             R => 'Regular (NASDAQ Open)',
623             S => 'Due To Related Security',
624             T => 'Resume',
625             V => 'In View of Common',
626             X => 'Equipment Changeover',
627             Y => 'Regular One Sided',
628             Z => 'No Open/No Resume',
629             ' ' => 'No Special Condition Exists', # space
630             };
631              
632             ########################################################################
633             ### Functions ###
634             ########################################################################
635              
636             sub has_otlib
637             {
638 2 50   2 1 14 return( $OTLIB_FOUND ? $TRUE : $FALSE );
639             }
640              
641             sub OTConstant
642             {
643 370     370 1 1923 return( $OTConstants->{ $_[0] } );
644             }
645              
646             sub OTCommand
647             {
648 18   66 18 1 164 return( $OTCommands->{ $_[0] } || $OTCommands->{ 0 } );
649             }
650              
651             # NUMBER => DT_SYMBOL
652             sub OTDatatype
653             {
654 3     3 1 19 return( $OTDatatypes->{ $_[0] } );
655             }
656              
657             sub OTCommandList
658             {
659 1     1 1 3 return( values( %{ $OTCommands } ) );
  1         6  
660             }
661              
662             sub OTDefault
663             {
664 22     22 1 179 return( $OTDefaults->{ $_[0] } );
665             }
666              
667             # Return which request command_ids can be cancelled by a cancel command_id
668             sub OTCancel
669             {
670 17     17 1 91 return( $OTCancels->{ $_[0] } );
671             }
672              
673             # Return the cancel command_id for a request command_id
674             sub OTCanceller
675             {
676 8     8 1 642 my( $command_id ) = @_;
677              
678 8         23 for my $cancel_id ( keys( %$OTCancels ) )
679             {
680 20 100       182 return( $cancel_id ) if( $OTCancels->{$cancel_id}->{$command_id} );
681             }
682              
683 0         0 return;
684             }
685              
686             sub OTEvent
687             {
688 32     32 1 247 return( $OTEvents->{ $_[0] } );
689             }
690              
691             sub OTEventByEvent
692             {
693 12     12 1 90 my %OTEventNames = reverse( %$OTEvents );
694 12         71 return( $OTEventNames{ $_[0] } );
695             }
696              
697             sub OTEventList
698             {
699 3     3 1 39 return( values( %$OTEvents ) );
700             }
701              
702             sub OTEventByCommand
703             {
704 7     7 1 121 return( $OTCommandEvents->{ $_[0] } );
705             }
706            
707             # API method name to command number map
708             sub OTAPItoCommand
709             {
710 6     6 1 15 my $repl;
711              
712             return( wantarray
713 6 100       37 ? ( $OTAPItoCommands->{ $_[0] },
714             OTDeprecated( $OTAPItoCommands->{ $_[0] } ) )
715             : $OTAPItoCommands->{ $_[0] } );
716             }
717              
718             # command number to API map
719             sub OTCommandtoAPI
720             {
721 0 0   0 1 0 return unless defined( $_[0] );
722 0         0 my %map = reverse %{ $OTAPItoCommands };
  0         0  
723              
724 0         0 return( $map{ $_[0] } );
725             }
726              
727             # Equity TRADE indicator code to description map
728             sub OTTradeIndicator
729             {
730 5     5 1 27 return( $OTTradeIndicators->{ $_[0] } );
731             }
732              
733             # Equity QUOTE indicator code to description map
734             sub OTQuoteIndicator
735             {
736 5     5 1 30 return( $OTQuoteIndicators->{ $_[0] } );
737             }
738              
739             # Return the number of responses (a constant) for a command type
740             sub OTResponses
741             {
742 7     7 1 38 return( $OTResponses->{ $_[0] } );
743             }
744              
745             # Return the suggested command id, if the supplied command id is deprecated
746             sub OTDeprecated
747             {
748 1     1 1 6 return( $OTDeprecated->{ $_[0] } );
749             }
750              
751             # Is a valid command status
752             sub OTCmdStatus
753             {
754 7     7 1 19 my( $cmd_status ) = @_;
755              
756 7 100 66     94 return( ( $cmd_status =~ /^\d+$/ and
757             ( $cmd_status == $OTConstants->{OT_STATUS_ERROR} or
758             $cmd_status == $OTConstants->{OT_STATUS_OK} ) )
759             ? $TRUE
760             : $FALSE );
761             }
762              
763             # Is a valid opentick message type
764             sub OTMsgType
765             {
766 7     7 1 29 my( $msg_type ) = @_;
767              
768 7 100 66     86 return( ( $msg_type =~ /^\d+$/ &&
769             ( $msg_type == $OTConstants->{OT_MES_REQUEST} or
770             $msg_type == $OTConstants->{OT_MES_RESPONSE} ) )
771             ? $TRUE
772             : $FALSE );
773             }
774              
775             # Is DataType End-of-Data ?
776             sub OTeod
777             {
778 5     5 1 16 my( $data_type ) = @_;
779              
780 5 100 100     67 return( ( defined( $data_type ) &&
781             $data_type =~ /^\d+$/ &&
782             $data_type == $OTConstants->{OT_DATATYPE_EOD} )
783             ? $TRUE
784             : $FALSE );
785             }
786              
787             # Are some fields actually supposed to be 64-bit integral values?
788             sub OT64bit
789             {
790 8     8 1 30 my( $input ) = @_;
791              
792 8 50       25 return () if( $PERL_64BIT_INT );
793              
794 8 100       37 return( defined( $OT64bit->{$input} ) ? @{$OT64bit->{$input}} : () );
  6         32  
795             }
796              
797             # Return the pack template for the specified item.
798             # Allows for some XPath-style magic.
799             sub OTTemplate
800             {
801 30     30 1 60 my( $template ) = @_;
802              
803 30         96 my( $tree, $tmpl_name ) = split( /\//, $template );
804              
805 30         42 my $result;
806 30 100       69 if( defined( $tmpl_name ) )
807             {
808             # be nice and convert the command for them.
809 11 50       62 $tmpl_name = $OTConstants->{ $tmpl_name }
810             unless( $tmpl_name =~ /^\d+$/ );
811 11 100       34 return unless( defined( $tmpl_name ) );
812 10         111 $result = $OTTemplates->{ $tree }->{ $tmpl_name };
813             }
814             else
815             {
816 19         67 $result = $OTTemplates->{ $template };
817             }
818              
819 29         184 return( $result );
820             }
821              
822             ###
823             ### Main
824             ###
825              
826             1;
827              
828             __END__