package POE::Component::Client::opentick::Constants; # # opentick.com POE client # # Protocol constants # # infi/2008 # # Full POD documentation after __END__ # # NOTE: This is deep hackery, and thus ugly. But, I'm trying to do # the Right Thing(tm). # use strict; use Carp qw( carp ); $Carp::CarpLevel = 1; use Data::Dumper; use vars qw( $VERSION $TRUE $FALSE ); BEGIN { require Exporter; our @ISA = qw( Exporter ); our @EXPORT = qw( OTConstant OTCommand OTDefault OTCancel OTTemplate OTResponses OTCmdStatus OTMsgType OTEvent OTEventList OTEventByEvent OTEventByCommand OTAPItoCommand OTeod OTCommandList OTDatatype OTCommandtoAPI OT64bit OTCanceller OTTradeIndicator OTQuoteIndicator has_otlib ); ($VERSION) = q$Revision: 45 $ =~ /(\d+)/; } ### ### Variables ### *TRUE = \1; *FALSE = \0; my $OTLIB_FOUND; # Boolean, TRUE if official library is found my $PERL_64BIT_INT; # Boolean, TRUE if we have 64 bit integers my $OTConstants; # Most of the constants from the library my $OTTemplates; # pack/unpack templates my $OTResponses; # Counts of responses to various requests my $OTDefaults; # Default settings for the main client our $OTCommands; # Command number => name mapping our $OTDatatypes; # Datatype number => name mapping my $OTCancels; # Cancellation command mapping my $OTEvents; # Event alias => name mapping my $OTCommandEvents; # Command => event mapping my $OTAPItoCommands; # API => command mapping my $OTTradeIndicators; # Trade Indicator mapping my $OTQuoteIndicators; # Quote Indicator mapping my $OTDeprecated; # Deprecated method -> replacement mapping my $OT64bit; # COMPLETE HACK; simulate 64bit on 32bit # Check for 64-bit support in our perl. BEGIN { eval{ my $foo = unpack("D",""); }; $PERL_64BIT_INT = $@ ? 0 : 1; } # Try to find the official library to use its constants. BEGIN { # Check if the OPENTICK_LIB envvar is set, and prepend it to @INC. if( defined( $ENV{OPENTICK_LIB} ) && length( $ENV{OPENTICK_LIB} ) && ( -d $ENV{OPENTICK_LIB} ) ) { unshift( @INC, $ENV{OPENTICK_LIB} ); } # Check @INC eval { no warnings; require opentick::OTConstants; }; unless( $@ ) { # Official lib is present in @INC, snarf its constants. for( keys( %opentick::OTConstants:: ) ) { next unless /^OT_/; $OTConstants->{ $_ } = ${ $opentick::OTConstants::{ $_ } }; } $OTLIB_FOUND = 1; } else { # Official lib not found in @INC. Seed with our own values. $OTLIB_FOUND = 0; # carp( "OT:WARN: Official opentick lib not found; using built-in constants.\n" ); $OTConstants = { OT_CANCEL_MESSAGE => 'Request cancelled', # Force protocol version 4 later. # OT_PROTOCOL_VER => 4, OT_MES_REQUEST => 1, OT_MES_RESPONSE => 2, OT_MSG_END_OF_DATA => 10, OT_MSG_END_OF_REQUEST => 20, OT_MSG_END_OF_SNAPSHOT => 30, OT_STATUS_OK => 1, OT_STATUS_ERROR => 2, OT_STATUS_INACTIVE => 1, OT_STATUS_CONNECTING => 2, OT_STATUS_CONNECTED => 3, OT_STATUS_LOGGED_IN => 4, OT_INSTRUMENT_STOCK => 1, OT_INSTRUMENT_INDEX => 2, OT_INSTRUMENT_FUTURE => 4, OT_INSTRUMENT_OPTION => 3, OT_TICK_TYPE_QUOTE => 1, OT_TICK_TYPE_MMQUOTE => 2, OT_TICK_TYPE_TRADE => 3, OT_TICK_TYPE_BBO => 4, OT_MASK_TYPE_QUOTE => 1, OT_MASK_TYPE_MMQUOTE => 2, OT_MASK_TYPE_TRADE => 4, OT_MASK_TYPE_BBO => 8, OT_MASK_TYPE_LEVEL1 => 13, OT_MASK_TYPE_LEVEL2 => 2, OT_MASK_TYPE_BOTH => 15, OT_MASK_TYPE_ALL => 15, OT_BOOK_TYPE_CANCEL => 5, OT_BOOK_TYPE_CHANGE => 6, OT_BOOK_TYPE_DELETE => 7, OT_BOOK_TYPE_EXECUTE => 8, OT_BOOK_TYPE_ORDER => 9, OT_BOOK_TYPE_LEVEL => 10, OT_BOOK_TYPE_PURGE => 11, OT_BOOK_TYPE_REPLACE => 12, OT_DELETE_TYPE_ORDER => '1', OT_DELETE_TYPE_PREVIOUS => '2', OT_DELETE_TYPE_ALL => '3', OT_DELETE_TYPE_AFTER => 'A', OT_FLAG_OPEN => 1, OT_FLAG_HIGH => 2, OT_FLAG_LOW => 4, OT_FLAG_CLOSE => 8, OT_FLAG_UPDATE_LAST => 16, OT_FLAG_UPDATE_VOLUME => 32, OT_FLAG_CANCEL => 64, OT_FLAG_FROM_BOOK => 128, OT_HIST_RAW_TICKS => 1, OT_HIST_OHLC_TICK_BASED => 2, OT_HIST_OHLC_MINUTELY => 3, OT_HIST_OHLC_HOURLY => 4, OT_HIST_OHLC_DAILY => 5, OT_HIST_OHLC_WEEKLY => 6, OT_HIST_OHLC_MONTHLY => 7, OT_HIST_OHLC_YEARLY => 8, OT_HIST_OHL_TODAY => 9, OT_HIST_CODE_EOD => 0, OT_HIST_CODE_TICK_QUOTE => 1, OT_HIST_CODE_TICK_MMQUOTE => 2, OT_HIST_CODE_TICK_TRADE => 3, OT_HIST_CODE_TICK_BBO => 4, OT_HIST_CODE_OHLC => 50, OT_HIST_CODE_OHL_TODAY => 51, OT_INT_UNKNOWN => 0, OT_LOGIN => 1, OT_LOGOUT => 2, OT_REQUEST_TICK_STREAM => 3, # Deprecated, use _EX OT_REQUEST_TICK_STREAM_EX => 15, OT_CANCEL_TICK_STREAM => 4, OT_REQUEST_HIST_DATA => 5, OT_REQUEST_HIST_TICKS => 17, OT_CANCEL_HIST_DATA => 6, OT_REQUEST_LIST_EXCHANGES => 7, OT_REQUEST_LIST_SYMBOLS => 8, OT_HEARTBEAT => 9, OT_REQUEST_EQUITY_INIT => 10, OT_REQUEST_OPTION_CHAIN => 11, # Deprecated, use _EX OT_REQUEST_OPTION_CHAIN_EX => 16, OT_CANCEL_OPTION_CHAIN => 12, OT_REQUEST_BOOK_STREAM => 13, OT_CANCEL_BOOK_STREAM => 14, OT_ERR_OPENTICK => 1000, OT_ERR_SYSTEM => 2000, OT_ERR_SOCK => 3000, OT_ERR_BAD_LOGIN => 1001, OT_ERR_NOT_LOGGED_IN => 1002, OT_ERR_NO_DATA => 1003, OT_ERR_INVALID_CANCEL_ID => 1004, OT_ERR_INVALID_INTERVAL => 1005, OT_ERR_NO_LICENSE => 1006, OT_ERR_LIMIT_EXCEEDED => 1007, OT_ERR_DUPLICATE_REQUEST => 1008, OT_ERR_INACTIVE_ACCOUNT => 1009, OT_ERR_LOGGED_IN => 1010, OT_ERR_BAD_REQUEST => 1011, OT_ERR_NO_HIST_PACKAGE => 1012, OT_ERR_SERVER_ERROR => 2002, OT_ERR_CANNOT_CONNECT => 2003, OT_ERR_BROKEN_CONNECTION => 2004, OT_ERR_NO_THREAD => 2005, OT_ERR_NO_SOCKET => 2006, OT_OS_UNKNOWN => 1, OT_OS_WIN95 => 2, OT_OS_WIN98 => 3, OT_OS_WIN98SE => 4, OT_OS_WINME => 5, OT_OS_WINNT => 6, OT_OS_WIN2000 => 7, OT_OS_WINXP => 8, OT_OS_LINUX => 20, OT_PLATFORM_OT => 1, OT_PLATFORM_WEALTHLAB => 3, OT_PLATFORM_QUANTSTUDIO => 2, OT_PLATFORM_JAVA => 7, }; } # END otlib parsing # Newer constants -- not included in perl otFeed OTConstants.pm distro # So we'll set them regardless of constant source. $OTConstants->{OT_ERR_RECEIVE} = 3001; $OTConstants->{OT_REQUEST_SPLITS} = 18; $OTConstants->{OT_REQUEST_DIVIDENDS} = 19; $OTConstants->{OT_REQUEST_HIST_BOOKS} = 20; $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} = 21; $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} = 22; $OTConstants->{OT_REQUEST_OPTION_INIT} = 23; $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} = 24; $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} = 25; $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} = 26; # Force this to 4, overriding the built-in constant values. $OTConstants->{OT_PROTOCOL_VER} = 4; ####### My own extensions ####### ### Response counts $OTConstants->{OT_RESPONSES_NONE} = 0; $OTConstants->{OT_RESPONSES_ONE} = 1; $OTConstants->{OT_RESPONSES_FINITE} = 2; $OTConstants->{OT_RESPONSES_CONTINUOUS} = 3; ### Data types $OTConstants->{OT_DATATYPE_EOD} = 0; # Misc $OTConstants->{OT_DATATYPE_QUOTE} = 1; $OTConstants->{OT_DATATYPE_MMQUOTE} = 2; $OTConstants->{OT_DATATYPE_TRADE} = 3; $OTConstants->{OT_DATATYPE_BBO} = 4; # RequestBook*, RequestOption*, RequestTick* $OTConstants->{OT_DATATYPE_CANCEL} = 5; $OTConstants->{OT_DATATYPE_CHANGE} = 6; $OTConstants->{OT_DATATYPE_DELETE} = 7; $OTConstants->{OT_DATATYPE_EXECUTE} = 8; $OTConstants->{OT_DATATYPE_ORDER} = 9; $OTConstants->{OT_DATATYPE_PRICELEVEL} = 10; $OTConstants->{OT_DATATYPE_PURGE} = 11; $OTConstants->{OT_DATATYPE_REPLACE} = 12; $OTConstants->{OT_DATATYPE_HALT} = 13; $OTConstants->{OT_DATATYPE_SPLIT} = 14; $OTConstants->{OT_DATATYPE_DIVIDEND} = 15; $OTConstants->{OT_DATATYPE_EQ_INIT} = 17; $OTConstants->{OT_DATATYPE_EQUITY_INIT} = 17; # Alias $OTConstants->{OT_DATATYPE_OPTION_INIT} = 18; $OTConstants->{OT_DATATYPE_OHLC} = 50; $OTConstants->{OT_DATATYPE_OHL_TODAY} = 51; # Fill the reverse command map early for other modules. my @cmds = qw( OT_INT_UNKNOWN OT_LOGIN OT_LOGOUT OT_HEARTBEAT OT_REQUEST_TICK_STREAM OT_REQUEST_TICK_STREAM_EX OT_CANCEL_TICK_STREAM OT_REQUEST_HIST_DATA OT_REQUEST_HIST_TICKS OT_CANCEL_HIST_DATA OT_REQUEST_LIST_EXCHANGES OT_REQUEST_LIST_SYMBOLS OT_REQUEST_EQUITY_INIT OT_REQUEST_OPTION_CHAIN OT_REQUEST_OPTION_CHAIN_EX OT_CANCEL_OPTION_CHAIN OT_REQUEST_BOOK_STREAM OT_CANCEL_BOOK_STREAM OT_REQUEST_SPLITS OT_REQUEST_DIVIDENDS OT_REQUEST_HIST_BOOKS OT_REQUEST_BOOK_STREAM_EX OT_REQUEST_OPTION_CHAIN_U OT_REQUEST_OPTION_INIT OT_REQUEST_LIST_SYMBOLS_EX OT_REQUEST_TICK_SNAPSHOT OT_REQUEST_OPTION_CHAIN_SNAPSHOT ); $OTCommands->{ $OTConstants->{$_} } = $_ for( @cmds ); # Fill in the reverse datatype map my @dts = qw( OT_DATATYPE_EOD OT_DATATYPE_QUOTE OT_DATATYPE_MMQUOTE OT_DATATYPE_TRADE OT_DATATYPE_BBO OT_DATATYPE_SPLIT OT_DATATYPE_DIVIDEND OT_DATATYPE_OPTION_INIT OT_DATATYPE_OHLC OT_DATATYPE_OHL_TODAY OT_DATATYPE_CANCEL OT_DATATYPE_CHANGE OT_DATATYPE_DELETE OT_DATATYPE_EXECUTE OT_DATATYPE_ORDER OT_DATATYPE_PRICELEVEL OT_DATATYPE_PURGE OT_DATATYPE_REPLACE ); $OTDatatypes->{ $OTConstants->{$_} } = $_ for( @dts ); # Commands that cancel other requests. $OTCancels = { $OTConstants->{OT_CANCEL_TICK_STREAM} => { $OTConstants->{OT_REQUEST_TICK_STREAM} => 1, $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => 1, }, $OTConstants->{OT_CANCEL_HIST_DATA} => { $OTConstants->{OT_REQUEST_HIST_DATA} => 1, $OTConstants->{OT_REQUEST_HIST_TICKS} => 1, }, $OTConstants->{OT_CANCEL_OPTION_CHAIN} => { $OTConstants->{OT_REQUEST_OPTION_CHAIN} => 1, $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => 1, }, $OTConstants->{OT_CANCEL_BOOK_STREAM} => { $OTConstants->{OT_REQUEST_BOOK_STREAM} => 1, $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => 1, }, }; } # /BEGIN # Templates for pack() and unpack() $OTTemplates = { # basic templates MSG_LENGTH => 'V', HEADER => 'C C x x V V', ERROR => 'v v a*', # templates for command message bodies cmds => { $OTConstants->{OT_LOGIN} => 'v C C a16 a6 a64 a64', $OTConstants->{OT_LOGOUT} => 'a64', $OTConstants->{OT_REQUEST_TICK_STREAM} => 'a64 a15 a15', $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => 'a64 a15 a15 x x V', $OTConstants->{OT_REQUEST_HIST_DATA} => 'a64 a15 a15 x x V V C x v', $OTConstants->{OT_REQUEST_HIST_TICKS} => 'a64 a15 a15 V V V', $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => 'a64', $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => 'a64 a15', $OTConstants->{OT_REQUEST_EQUITY_INIT} => 'a64 a15 a15', $OTConstants->{OT_REQUEST_OPTION_CHAIN} => 'a64 a15 a15 v V', $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => 'a64 a15 a15 v V V', $OTConstants->{OT_REQUEST_BOOK_STREAM} => 'a64 a15 a15', $OTConstants->{OT_HEARTBEAT} => '', # none $OTConstants->{OT_CANCEL_TICK_STREAM} => 'a64 V', $OTConstants->{OT_CANCEL_HIST_DATA} => 'a64 V', $OTConstants->{OT_CANCEL_OPTION_CHAIN} => 'a64 V', $OTConstants->{OT_CANCEL_BOOK_STREAM} => 'a64 V', # NEW! $OTConstants->{OT_REQUEST_SPLITS} => 'a64 a15 a15 V V', $OTConstants->{OT_REQUEST_DIVIDENDS} => 'a64 a15 a15 V V', $OTConstants->{OT_REQUEST_HIST_BOOKS} => 'a64 a15 a15 V V V', $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => 'a64 a15 a15 x x V', $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => 'a64 a15 a15 v V V d d V', $OTConstants->{OT_REQUEST_OPTION_INIT} => 'a64 a15 a15 v V d d V', $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => 'a64 a15 a15 V', $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => 'a64 a15 a15 x x V', $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => 'a64 a15 a15 v V V d d V', }, # templates for command response bodies resp => { $OTConstants->{OT_LOGIN} => 'a64 C a64 v', $OTConstants->{OT_LOGOUT} => '', # none $OTConstants->{OT_REQUEST_TICK_STREAM} => '', # unneeded $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => '', # unneeded $OTConstants->{OT_REQUEST_HIST_DATA} => 'V', # + datatype $OTConstants->{OT_REQUEST_HIST_TICKS} => 'V', # + datatype $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => 'v/a', $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => 'a4 a15 C v/a', # Requires 64-bit int support built into Perl, but we'll simulate it. $OTConstants->{OT_REQUEST_EQUITY_INIT} => $PERL_64BIT_INT ? 'C a3 C a80 d a8 d a8 d a8 d a8 D D a9 a12 C C C' : 'C a3 C a80 d a8 d a8 d a8 d a8 a8 a8 a9 a12 C C C', $OTConstants->{OT_REQUEST_OPTION_CHAIN} => '', $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => '', $OTConstants->{OT_REQUEST_BOOK_STREAM} => '', $OTConstants->{OT_HEARTBEAT} => '', # none $OTConstants->{OT_CANCEL_TICK_STREAM} => '', $OTConstants->{OT_CANCEL_HIST_DATA} => '', $OTConstants->{OT_CANCEL_OPTION_CHAIN} => '', $OTConstants->{OT_CANCEL_BOOK_STREAM} => '', # NEW! $OTConstants->{OT_REQUEST_SPLITS} => 'C V V V V V V', $OTConstants->{OT_REQUEST_DIVIDENDS} => 'C d V V V V a a', $OTConstants->{OT_REQUEST_HIST_BOOKS} => '', $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => '', $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => '', $OTConstants->{OT_REQUEST_OPTION_INIT} => 'C a12 a12 d V a4 a2 a2 a a9 a3 a', $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => '', $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => '', $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => '', }, datatype => { $OTConstants->{OT_DATATYPE_EOD} => 'C', $OTConstants->{OT_DATATYPE_QUOTE} => 'C V V V d d a2 a a', $OTConstants->{OT_DATATYPE_MMQUOTE} => 'C V V V d d a4 a', # XXX: The 'a8' in the next line should actually be a D. # Requires 64-bit int support built into Perl, but we'll simulate it. $OTConstants->{OT_DATATYPE_TRADE} => $PERL_64BIT_INT ? 'C V d V D V a a C' : 'C V d V a8 V a a C', $OTConstants->{OT_DATATYPE_BBO} => 'C V d V a', $OTConstants->{OT_DATATYPE_OHLC} => 'C V d d d d d', $OTConstants->{OT_DATATYPE_OHL_TODAY} => 'C d d d', # requestBookStream*, requestOptionChain*, requestHistBooks $OTConstants->{OT_DATATYPE_CANCEL} => 'C V a21 V', $OTConstants->{OT_DATATYPE_CHANGE} => 'C V a21 d V', $OTConstants->{OT_DATATYPE_DELETE} => 'C V a21 C C', $OTConstants->{OT_DATATYPE_EXECUTE} => 'C V a21 V V', $OTConstants->{OT_DATATYPE_ORDER} => 'C V a21 d V C C', $OTConstants->{OT_DATATYPE_PRICELEVEL} => 'C V d V C a4', $OTConstants->{OT_DATATYPE_PURGE} => 'C V a3', $OTConstants->{OT_DATATYPE_REPLACE} => 'C V a21 d V C', }, }; # A complete hack. Needed to simulate 64-bit integers in 32-bits. $OT64bit = { $OTConstants->{OT_DATATYPE_TRADE} => [ 4 ], $OTConstants->{OT_DATATYPE_EQUITY_INIT} => [ 12, 13 ], }; # Number of response packets to this request $OTResponses = { $OTConstants->{OT_LOGIN} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_LOGOUT} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_TICK_STREAM} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_CANCEL_TICK_STREAM} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_HIST_DATA} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_CANCEL_HIST_DATA} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_HEARTBEAT} => $OTConstants->{OT_RESPONSES_NONE}, $OTConstants->{OT_REQUEST_EQUITY_INIT} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_OPTION_CHAIN} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_CANCEL_OPTION_CHAIN} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_BOOK_STREAM} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_CANCEL_BOOK_STREAM} => $OTConstants->{OT_RESPONSES_ONE}, $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_HIST_TICKS} => $OTConstants->{OT_RESPONSES_FINITE}, # NEW! $OTConstants->{OT_REQUEST_SPLITS} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_REQUEST_DIVIDENDS} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_REQUEST_HIST_BOOKS} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_OPTION_INIT} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => $OTConstants->{OT_RESPONSES_FINITE}, $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => $OTConstants->{OT_RESPONSES_CONTINUOUS}, }; # opentick client defaults, most can be overridden. $OTDefaults = { # POE defaults alias => 'opentick', # default POE alias # network/socket defaults servers_realtime => [ qw( feed1.opentick.com feed2.opentick.com ) ], servers_delayed => [ qw( delayed1.opentick.com delayed2.opentick.com ) ], port_realtime => 10010, # port for realtime data port_delayed => 10015, # port for delayed data realtime => $FALSE, # request realtime data # Connection defaults autologin => $TRUE, # Automatically log in? conntimeout => 30, # Timeout for connect() autoreconnect => $TRUE, # Automatically reconnect? reconninterval => 60, # Reconn interval in seconds reconnretries => 5, # Retries before giving up # Protocol defaults heartbeat => 15, # delay in seconds for beats protocolver => $OTConstants->{ 'OT_PROTOCOL_VER' }, platform => $OTConstants->{ 'OT_PLATFORM_OT' }, platformpass => '', os => $OTConstants->{ 'OT_OS_LINUX' }, macaddr => '08:00:02:01:02:03', # 3Com, heh apitimeout => 30, # Time out for API commands # LAME request_timeout => 30, # Time before expunging # ListSymbols or ListExch* }; # symbolic event name to actual POE event name map. $OTEvents = { OT_ON_LOGIN => 'ot_on_login', OT_ON_ERROR => 'ot_on_error', OT_ON_DATA => 'ot_on_data', OT_ON_LOGOUT => 'ot_on_logout', OT_REQUEST_COMPLETE => 'ot_request_complete', OT_REQUEST_CANCELLED => 'ot_request_cancelled', OT_CONNECT_FAILED => 'ot_connect_failed', OT_STATUS_CHANGED => 'ot_status_changed', }; # integral command number to POE event name map. $OTCommandEvents = { $OTConstants->{OT_INT_UNKNOWN} => $OTEvents->{OT_ON_ERROR}, $OTConstants->{OT_LOGIN} => $OTEvents->{OT_ON_LOGIN}, $OTConstants->{OT_LOGOUT} => $OTEvents->{OT_ON_LOGOUT}, $OTConstants->{OT_REQUEST_TICK_STREAM} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_CANCEL_TICK_STREAM} => $OTEvents->{OT_REQUEST_CANCELLED}, $OTConstants->{OT_REQUEST_HIST_DATA} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_CANCEL_HIST_DATA} => $OTEvents->{OT_REQUEST_CANCELLED}, $OTConstants->{OT_REQUEST_LIST_SYMBOLS} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_LIST_EXCHANGES} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_HEARTBEAT} => undef, $OTConstants->{OT_REQUEST_EQUITY_INIT} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_OPTION_CHAIN} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_CANCEL_OPTION_CHAIN} => $OTEvents->{OT_REQUEST_CANCELLED}, $OTConstants->{OT_REQUEST_BOOK_STREAM} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_CANCEL_BOOK_STREAM} => $OTEvents->{OT_REQUEST_CANCELLED}, $OTConstants->{OT_REQUEST_TICK_STREAM_EX} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_HIST_TICKS} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_SPLITS} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_DIVIDENDS} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_HIST_BOOKS} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_BOOK_STREAM_EX} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_U} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_OPTION_INIT} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_TICK_SNAPSHOT} => $OTEvents->{OT_ON_DATA}, $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT} => $OTEvents->{OT_ON_DATA}, }; # API method name to command number map $OTAPItoCommands = { 'requestSplits' => $OTConstants->{OT_REQUEST_SPLITS}, 'requestDividends' => $OTConstants->{OT_REQUEST_DIVIDENDS}, 'requestOptionInit' => $OTConstants->{OT_REQUEST_OPTION_INIT}, 'requestHistData' => $OTConstants->{OT_REQUEST_HIST_DATA}, 'requestHistTicks' => $OTConstants->{OT_REQUEST_HIST_TICKS}, 'requestTickStream' => $OTConstants->{OT_REQUEST_TICK_STREAM}, 'requestTickStreamEx' => $OTConstants->{OT_REQUEST_TICK_STREAM_EX}, 'requestTickSnapshot' => $OTConstants->{OT_REQUEST_TICK_SNAPSHOT}, 'requestOptionChain' => $OTConstants->{OT_REQUEST_OPTION_CHAIN}, 'requestOptionChainEx' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX}, 'requestOptionChainU' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_U}, 'requestOptionChainSnapshot' => $OTConstants->{OT_REQUEST_OPTION_CHAIN_SNAPSHOT}, 'requestEqInit' => $OTConstants->{OT_REQUEST_EQUITY_INIT}, 'requestEquityInit' => $OTConstants->{OT_REQUEST_EQUITY_INIT}, 'requestBookStream' => $OTConstants->{OT_REQUEST_BOOK_STREAM}, 'requestBookStreamEx' => $OTConstants->{OT_REQUEST_BOOK_STREAM_EX}, 'requestHistBooks' => $OTConstants->{OT_REQUEST_HIST_BOOKS}, 'requestListSymbols' => $OTConstants->{OT_REQUEST_LIST_SYMBOLS}, 'requestListSymbolsEx' => $OTConstants->{OT_REQUEST_LIST_SYMBOLS_EX}, 'requestListExchanges' => $OTConstants->{OT_REQUEST_LIST_EXCHANGES}, 'cancelTickStream' => $OTConstants->{OT_CANCEL_TICK_STREAM}, 'cancelHistData' => $OTConstants->{OT_CANCEL_HIST_DATA}, 'cancelOptionChain' => $OTConstants->{OT_CANCEL_OPTION_CHAIN}, 'cancelBookStream' => $OTConstants->{OT_CANCEL_BOOK_STREAM}, }; # Deprecated methods and their suggested replacements $OTDeprecated = { $OTConstants->{OT_REQUEST_TICK_STREAM} => $OTConstants->{OT_REQUEST_TICK_STREAM_EX}, $OTConstants->{OT_REQUEST_OPTION_CHAIN} => $OTConstants->{OT_REQUEST_OPTION_CHAIN_EX}, }; $OTTradeIndicators = { '@' => 'Regular Trade', A => 'Acquisition - Cash', B => 'Bunched Trade - Average Price', C => 'Cash Trade', D => 'Distribution - Next Day Market', E => 'Automatic Execution', F => 'Intermarket Sweep Order', G => 'Bunched Sold Trade - Opening/Reopening Trade Detail', H => 'Intraday Trade Detail', I => 'Basket Index on Close Transaction', J => 'Rule 127 Trade (NYSE only)', K => 'Rule 155 Trade (AMEX only)', L => 'Sold Last', N => 'Next Day', O => 'Opened', P => 'Prior Reference Price', R => 'Seller', S => 'Split Trade', T => 'Form-T Trade - Pre/Post Market Trade', W => 'Average Price Trade', Z => 'Sold (Out of Sequence)', }; $OTQuoteIndicators = { A => 'Depth on Ask side', B => 'Depth on Bid side', C => 'Closing', D => 'News Dissemination', E => 'Order Influx', F => 'Fast Trading', G => 'Trading Range Indication', H => 'Depth on Bid and Ask', I => 'Order Imbalance', J => 'Due to Related Security-news Dissemination', K => 'Due to Related Security-news Pending', L => 'Closed Market Maker (NASDAQ)', M => 'No Eligible Market Participant Quotes in Issue at Market Close', N => 'Non-Firm Quote', O => 'Opening Quote', P => 'News Pending', Q => 'Additional Information-Due To Related Security', R => 'Regular (NASDAQ Open)', S => 'Due To Related Security', T => 'Resume', V => 'In View of Common', X => 'Equipment Changeover', Y => 'Regular One Sided', Z => 'No Open/No Resume', ' ' => 'No Special Condition Exists', # space }; ######################################################################## ### Functions ### ######################################################################## sub has_otlib { return( $OTLIB_FOUND ? $TRUE : $FALSE ); } sub OTConstant { return( $OTConstants->{ $_[0] } ); } sub OTCommand { return( $OTCommands->{ $_[0] } || $OTCommands->{ 0 } ); } # NUMBER => DT_SYMBOL sub OTDatatype { return( $OTDatatypes->{ $_[0] } ); } sub OTCommandList { return( values( %{ $OTCommands } ) ); } sub OTDefault { return( $OTDefaults->{ $_[0] } ); } # Return which request command_ids can be cancelled by a cancel command_id sub OTCancel { return( $OTCancels->{ $_[0] } ); } # Return the cancel command_id for a request command_id sub OTCanceller { my( $command_id ) = @_; for my $cancel_id ( keys( %$OTCancels ) ) { return( $cancel_id ) if( $OTCancels->{$cancel_id}->{$command_id} ); } return; } sub OTEvent { return( $OTEvents->{ $_[0] } ); } sub OTEventByEvent { my %OTEventNames = reverse( %$OTEvents ); return( $OTEventNames{ $_[0] } ); } sub OTEventList { return( values( %$OTEvents ) ); } sub OTEventByCommand { return( $OTCommandEvents->{ $_[0] } ); } # API method name to command number map sub OTAPItoCommand { my $repl; return( wantarray ? ( $OTAPItoCommands->{ $_[0] }, OTDeprecated( $OTAPItoCommands->{ $_[0] } ) ) : $OTAPItoCommands->{ $_[0] } ); } # command number to API map sub OTCommandtoAPI { return unless defined( $_[0] ); my %map = reverse %{ $OTAPItoCommands }; return( $map{ $_[0] } ); } # Equity TRADE indicator code to description map sub OTTradeIndicator { return( $OTTradeIndicators->{ $_[0] } ); } # Equity QUOTE indicator code to description map sub OTQuoteIndicator { return( $OTQuoteIndicators->{ $_[0] } ); } # Return the number of responses (a constant) for a command type sub OTResponses { return( $OTResponses->{ $_[0] } ); } # Return the suggested command id, if the supplied command id is deprecated sub OTDeprecated { return( $OTDeprecated->{ $_[0] } ); } # Is a valid command status sub OTCmdStatus { my( $cmd_status ) = @_; return( ( $cmd_status =~ /^\d+$/ and ( $cmd_status == $OTConstants->{OT_STATUS_ERROR} or $cmd_status == $OTConstants->{OT_STATUS_OK} ) ) ? $TRUE : $FALSE ); } # Is a valid opentick message type sub OTMsgType { my( $msg_type ) = @_; return( ( $msg_type =~ /^\d+$/ && ( $msg_type == $OTConstants->{OT_MES_REQUEST} or $msg_type == $OTConstants->{OT_MES_RESPONSE} ) ) ? $TRUE : $FALSE ); } # Is DataType End-of-Data ? sub OTeod { my( $data_type ) = @_; return( ( $data_type =~ /^\d+$/ && $data_type == $OTConstants->{OT_DATATYPE_EOD} ) ? $TRUE : $FALSE ); } # Are some fields actually supposed to be 64-bit integral values? sub OT64bit { my( $input ) = @_; return () if( $PERL_64BIT_INT ); return( defined( $OT64bit->{$input} ) ? @{$OT64bit->{$input}} : () ); } # Return the pack template for the specified item. # Allows for some XPath-style magic. sub OTTemplate { my( $template ) = @_; my( $tree, $tmpl_name ) = split( /\//, $template ); my $result; if( defined( $tmpl_name ) ) { # be nice and convert the command for them. $tmpl_name = $OTConstants->{ $tmpl_name } unless( $tmpl_name =~ /^\d+$/ ); return unless( defined( $tmpl_name ) ); $result = $OTTemplates->{ $tree }->{ $tmpl_name }; } else { $result = $OTTemplates->{ $template }; } return( $result ); } ### ### Main ### 1; __END__ =pod =head1 NAME POE::Component::Client::opentick::Constants - Constants for the opentick POE Component. =head1 SYNOPSIS use POE::Component::Client::opentick::Constants; =head1 DESCRIPTION This module contains all of the constants used by the rest of POE::Component::Client::opentick, and thus is of no use to anything else. It also rudely exports a bunch of junk into your namespace. This is desirable for the POE component, but why would you want that in your own module? Don't fiddle with it. Ist easy schnappen der Springenwerk, blowen-fusen und poppen corken mit spitzensparken. =head1 EXPORTS Exports the following methods into the using package's namespace: =over =item B<$value = OTConstant( $const_name )> Return the value of the named constant. =item B<$cmd_name = OTCommand( $cmd_number )> Return the command name from the constant command number. =item B<$cmd_name = OTCommandList( )> Return a list of all symbolic names. =item B<$value = OTDefault( $value_name )> Return one of the default values by name. =item B<$pack_tmpl = OTTemplate( $tmpl_name )> Return the named pack() template. =item B<$hashref = OTCancel( $cmd_number )> Return a hashref of the command IDs that the supplied $cmd_number can cancel. Mapped like such: { $cmd_number => $TRUE, $cmd_number2 => $TRUE, ... } It's a hashref for O(1) lookups instead of O(n) list grepping. =item B<$cmd_id = OTCanceller( $cmd_id )> Returns the canceller command ID of the appropriate cancel request for the supplied command ID. =item B<$datatype = OTDatatype( $const_num )> Return a $string representing the datatype for the supplied constant. =item B<$value = OTResponses( $cmd_number )> Return the number of expected response packets to the specified command. Possible values and their meanings are: undef Unknown or unlisted number of responses. 0 No response is generated (OT_HEARTBEAT). 1 Only one reply packet is generated. 2 A finite number of response packets are generated. 3 The stream is continuous until told to shut up. =item B<$boolean = OTCmdStatus( $value )> Return TRUE if the value is a valid CommandStatus. =item B<$boolean = OTMsgType( $value )> Return TRUE if the value is a valid MessageType. =item B<$eventname = OTEvent( $name )> Return actual POE $eventname for symbolic event name constant. =item B<$constname = OTEventByEvent( $eventname )> The reverse of the above. =item B<$constname = OTEventByCommand( $cmd_number )> Returns the POE event to issue for a particular $cmd_number response. e.g. OTEventByCommand( OTConstants('OT_LOGIN') ) returns 'ot_on_login' =item B<@eventnames = OTEventList( )> Return a list of all actual OTEvent names ( values( %$OTEvents ) ). =item B<$boolean = OTMsgType( $value )> Return TRUE if the value is a valid MessageType. =item B<$cmd_id = OTDeprecated( $cmd_id )> Return the replacement $cmd_id, if the supplied $cmd_id refers to an Opentick-deprecated command. Only requestTickStream and requestOptionChain are deprecated right now. =item B<$boolean = OTeod( $value )> Return TRUE if the value specifies End-Of-Data for . =item B<$cmd_num = OTAPItoCommand( $api_name )> Return the $command_number for the specified PUBLIC $api_name. =item B<$description = OTQuoteIndicator( $code )> Return the description of the supplied Indicator code from an EQUITY quote, or undef if not found. =item B<$description = OTTradeIndicator( $code )> Return the description of the supplied Indicator code from a TRADE quote, or undef if not found. =item B<$api_name = OTCommandtoAPI( $cmd_id )> Does the reverse of the above. =item B<@fieldnums = OT64bit( $cmd_id )> Return a list of field numbers that are actually supposed to be 64-bit integers for this $cmd_id. This is to simulate 64-bit ints on a 32-bit perl. Returns the empty list if we're compiled with 64-bit ints, or the $cmd_id doesn't require any 64-bit simulation. Basically, it's used internally and useless for anything else. =item B<$boolean = has_otlib( )> Return true if official opentick libraries were found in @INC. =back =head1 WARNINGS This module attempts to include the official 'opentick' perl library paths from @INC, to retrieve constant values, and carps the following warning if it is not present: B It is better to use the official opentick library constant values, if you can. I am sure they will strive to be backward-compatible, but I cannot guarantee the values contained herein will always work in the future. They can be downloaded from: L Install at least B to a path in your @INC, and this module will find them. (Read B if you are unsure how to modify your @INC path.) =head1 SEE ALSO POE, POE::Component::Client::opentick L L perldoc lib perldoc -q "include path" =head1 AUTHOR Jason McManus (infi) =head1 LICENSE Copyright (c) Jason McManus This module may be used, modified, and distributed under the same terms as Perl itself. Please see the license that came with your Perl distribution for details. The data from opentick.com are under an entirely separate license that varies according to exchange rules, etc. It is your responsibility to follow the opentick.com and exchange license agreements with the data. Further details are available on L. =cut