Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

finish responses

  • Loading branch information...
commit d72c8405075a540b27ce04ed68956fd4065a45eb 1 parent 5007ea6
@uwe authored
View
3  TODO
@@ -0,0 +1,3 @@
+- consume $data
+- validation
+
View
1  ids.pl
@@ -9,6 +9,7 @@
list_ids('Request');
+print "\n";
list_ids('Response');
View
7 lib/Protocol/TWS/Response.pm
@@ -47,12 +47,7 @@ sub _lines {
sub _minimum_version { 1 }
sub _parse {
- my ($class, $version, $data) = @_;
-
- # check lines
- if (@$data < $class->_lines) {
- die \($class->_lines);
- }
+ my ($class, $version, $data, $lines) = @_;
my @meta = $class->_meta;
View
11 lib/Protocol/TWS/Response/bondContractDetails.pm
@@ -5,6 +5,8 @@ use warnings;
use base 'Protocol::TWS::Response';
+use Protocol::TWS::Util::Lines;
+
sub _id { 18 }
@@ -22,6 +24,11 @@ sub _lines { 30 }
sub _parse {
my ($class, $version, $data) = @_;
+ my $lines = Protocol::TWS::Util::Lines->new(
+ data => $data,
+ lines => $class->_lines,
+ );
+
my %data = (
id => $data->[0],
);
@@ -63,9 +70,7 @@ sub _parse {
my $sec_id_count = $data->[29];
if ($sec_id_count > 0) {
- if (@$data < 30 + 2 * $sec_id_count) {
- die \(2 * $sec_id_count);
- }
+ $lines->add(2 * $sec_id_count);
my %sec_id = ();
my $i = 30;
View
11 lib/Protocol/TWS/Response/contractDetails.pm
@@ -5,6 +5,8 @@ use warnings;
use base 'Protocol::TWS::Response';
+use Protocol::TWS::Util::Lines;
+
sub _id { 10 }
@@ -22,6 +24,11 @@ sub _lines { 30 }
sub _parse {
my ($class, $version, $data) = @_;
+ my $lines = Protocol::TWS::Util::Lines->new(
+ data => $data,
+ lines => $class->_lines,
+ );
+
my %data = (
id => $data->[0],
);
@@ -62,9 +69,7 @@ sub _parse {
my $sec_id_count = $data->[29];
if ($sec_id_count > 0) {
- if (@$data < 30 + 2 * $sec_id_count) {
- die \(2 * $sec_id_count);
- }
+ $lines->add(2 * $sec_id_count);
my %sec_id = ();
my $i = 30;
View
2  lib/Protocol/TWS/Response/contractDetailsEnd.pm
@@ -10,7 +10,7 @@ sub _id { 52 }
sub _meta {
return (
- reqId => 'int',
+ id => {alias => 'reqId'},
);
}
View
29 lib/Protocol/TWS/Response/execDetails.pm
@@ -18,7 +18,7 @@ sub _meta {
sub _minimum_version { 9 }
-sub _lines { 22 }
+sub _lines { 27 }
sub _parse {
my ($class, $version, $data) = @_;
@@ -41,17 +41,22 @@ sub _parse {
);
my %execution = (
- orderId => $data->[1],
- execId => $data->[12],
- time => $data->[13],
- acctNumber => $data->[14],
- exchange => $data->[15],
- side => $data->[16],
- shares => $data->[17],
- price => $data->[18],
- permId => $data->[19],
- clientId => $data->[20],
- liquidation => $data->[21],
+ orderId => $data->[1],
+ execId => $data->[12],
+ time => $data->[13],
+ acctNumber => $data->[14],
+ exchange => $data->[15],
+ side => $data->[16],
+ shares => $data->[17],
+ price => $data->[18],
+ permId => $data->[19],
+ clientId => $data->[20],
+ liquidation => $data->[21],
+ cumQty => $data->[22],
+ avgPrice => $data->[23],
+ orderRef => $data->[24],
+ evRule => $data->[25],
+ evMultiplier => $data->[26],
);
$data{contract} = Protocol::TWS::Struct::Contract->new(%contract);
View
51 lib/Protocol/TWS/Response/historicalData.pm
@@ -10,23 +10,52 @@ sub _id { 17 }
sub _meta {
return (
- reqId => 'tickerId',
- date => {},
- open => 'double',
- high => 'double',
- low => 'double',
- close => 'double',
- volume => 'int',
- barCount => 'int',
- WAP => 'double',
- hasGaps => 'int',
+ id => {alias => 'reqId'},
+ startDate => {},
+ endDate => {},
+ bars => {type => 'array', subtype => 'BarData'},
);
}
sub _lines { 4 }
sub _parse {
- die
+ my ($class, $version, $data) = @_;
+
+ my $lines = Protocol::TWS::Util::Lines->new(
+ data => $data,
+ lines => $class->_lines,
+ );
+
+ my %data = (
+ id => $data->[0],
+ startDate => $data->[1],
+ endDate => $data->[2],
+ );
+
+ if (my $bar_count = $data->[3]) {
+ $lines->add(9 * $bar_count);
+
+ my $i = 4;
+ my @bars = ();
+ foreach (1 .. $bar_count) {
+ my %bar_data = (
+ date => $data->[$i++],
+ open => $data->[$i++],
+ high => $data->[$i++],
+ low => $data->[$i++],
+ close => $data->[$i++],
+ volume => $data->[$i++],
+ average => $data->[$i++],
+ hasGaps => $data->[$i++],
+ barCount => $data->[$i++],
+ );
+ push @bars, Protocol::TWS::Struct::BarData->new(%bar_data);
+ }
+ $data{bars} = \@bars;
+ }
+
+ return $class->new(%data);
}
View
222 lib/Protocol/TWS/Response/openOrder.pm
@@ -5,24 +5,240 @@ use warnings;
use base 'Protocol::TWS::Response';
+use Protocol::TWS::Util::Lines;
+
sub _id { 5 }
sub _meta {
return (
- orderId => 'orderId',
+ id => {alias => 'orderId'},
contract => 'Contract',
order => 'Order',
orderState => 'OrderState',
);
}
-sub _lines { die }
+sub _minimum_version { 30 }
+
+sub _lines { 90 }
sub _parse {
my ($class, $version, $data) = @_;
- die 'TODO';
+ my $lines = Protocol::TWS::Util::Lines->new(
+ data => $data,
+ lines => $class->_lines,
+ );
+
+ my %data = (
+ id => $data->[0],
+ );
+
+ my %contract = (
+ conId => $data->[1],
+ symbol => $data->[2],
+ secType => $data->[3],
+ expiry => $data->[4],
+ strike => $data->[5],
+ right => $data->[6],
+ exchange => $data->[7],
+ currency => $data->[8],
+ localSymbol => $data->[9],
+ );
+
+ my %order = (
+ action => $data->[10],
+ totalQuantity => $data->[11],
+ orderType => $data->[12],
+ lmtPrice => $data->[13],
+ auxPrice => $data->[14],
+ tif => $data->[15],
+ ocaGroup => $data->[16],
+ accout => $data->[17],
+ openClose => $data->[18],
+ origin => $data->[19],
+ orderRef => $data->[20],
+ clientId => $data->[21],
+ permId => $data->[22],
+ outsideRth => $data->[23],
+ hidden => $data->[24],
+ discretionaryAmt => $data->[25],
+ goodAfterTime => $data->[26],
+ faGroup => $data->[28],
+ faMethod => $data->[29],
+ faPercentage => $data->[30],
+ faProfile => $data->[31],
+ goodTillDate => $data->[32],
+ rule80A => $data->[33],
+ percentOffset => $data->[34],
+ settlingFirm => $data->[35],
+ shortSaleSlot => $data->[36],
+ designatedLocation => $data->[37],
+ exemptCode => $data->[38],
+ auctionStrategy => $data->[39],
+ startingPrice => $data->[40],
+ stockRefPrice => $data->[41],
+ delta => $data->[42],
+ stockRangeLower => $data->[43],
+ stockRangeUpper => $data->[44],
+ displaySize => $data->[45],
+ blockOrder => $data->[46],
+ sweepToFill => $data->[47],
+ allOrNone => $data->[48],
+ minQty => $data->[49],
+ ocaType => $data->[50],
+ eTradeOnly => $data->[51],
+ firmQuoteOnly => $data->[52],
+ nbboPriceCap => $data->[53],
+ parentId => $data->[54],
+ triggerMethod => $data->[55],
+ volatility => $data->[56],
+ volatilityType => $data->[57],
+ deltaNeutralOrderType => $data->[58],
+ deltaNeutralAuxPrice => $data->[59],
+ );
+
+ my $i = 60;
+ if ($order{deltaNeutralOrderType}) {
+ $lines->add(4);
+
+ $order{deltaNeutralConId} = $data->[$i++];
+ $order{deltaNeutralSettlingFirm} = $data->[$i++];
+ $order{detlaNeutralClearingAccount} = $data->[$i++];
+ $order{deltaNeutralClearingIntent} = $data->[$i++];
+ }
+
+ $order{continuousUpdate} = $data->[$i++];
+ $order{referencePriceType} = $data->[$i++];
+ $order{trailStopPrice} = $data->[$i++];
+ $order{trailingPercent} = $data->[$i++];
+ $order{basisPoints} = $data->[$i++];
+ $order{basisPointsType} = $data->[$i++];
+
+ $contract{comboLegsDescrip} = $data->[$i++];
+
+ if (my $combo_legs_count = $data->[$i++]) {
+ $lines->add(8 * $combo_legs_count);
+
+ my @combo_legs = ();
+ foreach (1 .. $combo_legs_count) {
+ my %combo_leg = (
+ conId => $data->[$i++],
+ ratio => $data->[$i++],
+ action => $data->[$i++],
+ exchange => $data->[$i++],
+ openClose => $data->[$i++],
+ shortSaleSlot => $data->[$i++],
+ designatedLocation => $data->[$i++],
+ exemptCode => $data->[$i++],
+ );
+ my $combo_leg = Protocol::TWS::Struct::ComboLeg->new(%combo_leg);
+ push @combo_legs, $combo_leg;
+ }
+ $contract{comboLegs} = \@combo_legs;
+ }
+
+ if (my $order_combo_legs_count = $data->[$i]) {
+ $lines->add($order_combo_legs_count);
+
+ my @order_combo_legs = ();
+ foreach (1 .. $order_combo_legs_count) {
+ my %order_combo_leg = (
+ price => $data->[$i++],
+ );
+ my $order_combo_leg = Protocol::TWS::Struct::OrderComboLeg->new(%order_combo_leg);
+ push @order_combo_legs, $order_combo_leg;
+ }
+ $order{orderComboLegs} = \@order_combo_legs;
+ }
+
+ if (my $smart_combo_routing_params_count = $data->[$i++]) {
+ $lines->add(2 * $smart_combo_routing_params_count);
+
+ my %smart_combo_routing_params = ();
+ foreach (1 .. $smart_combo_routing_params_count) {
+ $smart_combo_routing_params{$data->[$i++]} = $data->[$i++];
+ }
+ $order{smartComboRoutingParams} = \%smart_combo_routing_params;
+ }
+
+ $order{scaleInitLevelSize} = $data->[$i++];
+ $order{scaleSubsLevelSize} = $data->[$i++];
+ $order{scalePriceIncrement} = $data->[$i++];
+
+ if ($order{scalePriceIncrement}) {
+ $lines->add(7);
+
+ $order{scalePriceAdjustValue} = $data->[$i++];
+ $order{scalePriceAdjustInterval} = $data->[$i++];
+ $order{scaleProfitOffset} = $data->[$i++];
+ $order{scaleAutoReset} = $data->[$i++];
+ $order{scaleInitPosition} = $data->[$i++];
+ $order{scaleInitFillQty} = $data->[$i++];
+ $order{scaleRandomPercent} = $data->[$i++];
+ }
+
+ $order{hedgeType} = $data->[$i++];
+
+ if ($order{hedgeType}) {
+ $lines->add(1);
+
+ $order{hedgeParam} = $data->[$i++];
+ }
+
+ $order{optOutSmartRouting} = $data->[$i++];
+ $order{clearingAccount} = $data->[$i++];
+ $order{clearingIntent} = $data->[$i++];
+ $order{notHeld} = $data->[$i++];
+
+ if ($data->[$i++]) {
+ $lines->add(3);
+
+ my %under_comp = (
+ conId => $data->[$i++],
+ delta => $data->[$i++],
+ price => $data->[$i++],
+ );
+ my $under_comp = Protocol::TWS::Struct::UnderComp->new(%under_comp);
+ $contract{underComp} = $under_comp;
+ }
+
+ $order{algoStrategy} = $data->[$i++];
+
+ if ($order{algoStrategy}) {
+ $lines->add(1);
+
+ if (my $algo_params_count = $data->[$i++]) {
+ $lines->add(2 * $algo_params_count);
+
+ my %algo_params = ();
+ foreach (1 .. $algo_params_count) {
+ $algo_params{$data->[$i++]} = $data->[$i++];
+ }
+ $order{algoParams} = \%algo_params;
+ }
+ }
+
+ $order{whatIf} = $data->[$i++];
+
+ my %order_state = (
+ status => $data->[$i++],
+ initMargin => $data->[$i++],
+ maintMargin => $data->[$i++],
+ equityWithLoan => $data->[$i++],
+ commission => $data->[$i++],
+ minCommission => $data->[$i++],
+ maxCommission => $data->[$i++],
+ commissionCurrency => $data->[$i++],
+ warningText => $data->[$i++],
+ );
+
+ $data{contract} = Protocol::TWS::Struct::Contract->new(%contract);
+ $data{order} = Protocol::TWS::Struct::Order->new(%order);
+ $data{order_state} = Protocol::TWS::Struct::OrderState->new(%order_state);
+
+ return $class->new(%data);
}
View
68 lib/Protocol/TWS/Response/scannerData.pm
@@ -5,26 +5,76 @@ use warnings;
use base 'Protocol::TWS::Response';
+use Protocol::TWS::Util::Lines;
+
sub _id { 20 }
sub _meta {
return (
- id => {alias => 'reqId'},
- rank => 'int',
- contractDetails => 'ContractDetails',
- distance => {},
- benchmark => {},
- projection => {},
- legsStr => {},
+ id => {alias => 'reqId'},
+ scan_data => {type => 'array', subtype => 'ScanData'},
);
}
-sub _lines { die }
+sub _lines { 2 }
sub _parse {
- die
+ my ($class, $version, $data) = @_;
+
+ my $lines = Protocol::TWS::Util::Lines->new(
+ data => $data,
+ lines => $class->_lines,
+ );
+
+ my %data = (
+ id => $data->[0],
+ );
+
+ if (my $scan_data_count = $data->[1]) {
+ $lines->add(16 * $scan_data_count);
+
+ my $i = 2;
+ my @scan_data = ();
+ foreach (1 .. $scan_data_count) {
+ my %scan_data = (
+ rank => $data->[$i++],
+ );
+
+ my %contract = (
+ conId => $data->[$i++],
+ symbol => $data->[$i++],
+ secType => $data->[$i++],
+ expiry => $data->[$i++],
+ strike => $data->[$i++],
+ right => $data->[$i++],
+ exchange => $data->[$i++],
+ currency => $data->[$i++],
+ localSymbol => $data->[$i++],
+ );
+
+ my %contract_details = (
+ marketName => $data->[$i++],
+ tradingClass => $data->[$i++],
+ );
+
+ $contract_details{summary} = Protocol::TWS::Struct::Contract->new(%contract);
+
+ $scan_data{distance} = $data->[$i++];
+ $scan_data{benchmark} = $data->[$i++];
+ $scan_data{projection} = $data->[$i++];
+ $scan_data{legsStr} = $data->[$i++];
+
+ $scan_data{contract} = Protocol::TWS::Struct::ContractDetails->new(%contract_details);
+
+ push @scan_data, Protocol::TWS::Struct::ScanData->new(%scan_data);
+ }
+ $data{scan_data} = \@scan_data;
+ }
+
+ return $class->new(%data);
}
+
1;
View
2  lib/Protocol/TWS/Response/tickOptionComputation.pm
@@ -23,5 +23,7 @@ sub _meta {
);
}
+sub _minimum_version { 6 }
+
1;
View
2  lib/Protocol/TWS/Response/tickSnapshotEnd.pm
@@ -10,7 +10,7 @@ sub _id { 57 }
sub _meta {
return (
- reqId => 'int',
+ id => {alias => 'reqId'},
);
}
View
24 lib/Protocol/TWS/Struct/BarData.pm
@@ -0,0 +1,24 @@
+package Protocol::TWS::Struct::BarData;
+
+use strict;
+use warnings;
+
+use base 'Protocol::TWS::Struct';
+
+
+sub _meta {
+ return (
+ date => {},
+ open => 'double',
+ high => 'double',
+ low => 'double',
+ close => 'double',
+ volume => 'int',
+ average => 'double',
+ hasGaps => {},
+ barCount => 'int',
+ );
+}
+
+
+1;
View
21 lib/Protocol/TWS/Struct/ScanData.pm
@@ -0,0 +1,21 @@
+package Protocol::TWS::Struct::ScanData;
+
+use strict;
+use warnings;
+
+use base 'Protocol::TWS::Struct';
+
+
+sub _meta {
+ return (
+ contract => 'ContractDetails',
+ rank => 'int',
+ distance => {},
+ benchmark => {},
+ projection => {},
+ legsStr => {},
+ );
+}
+
+
+1;
View
36 lib/Protocol/TWS/Util/Lines.pm
@@ -0,0 +1,36 @@
+package Protocol::TWS::Util::Lines;
+
+use strict;
+use warnings;
+
+
+sub new {
+ my ($class, $data, $lines) = @_;
+
+ my $self = bless {
+ data => scalar @$data,
+ lines => $lines,
+ }, $class;
+
+ $self->check;
+
+ return $self;
+}
+
+sub add {
+ my ($self, $add) = @_;
+
+ $self->{lines} += $add;
+
+ $self->check;
+}
+
+sub check {
+ my ($self) = @_;
+
+ my $diff = $self->{lines} - $self->{data};
+ die \$diff if $diff > 0;
+}
+
+1;
+
Please sign in to comment.
Something went wrong with that request. Please try again.