Subject: | placeOrder broken |
I made a modification to the examples/api-demo.pl script to place an
order. MyEventHander.pm is unchanged.
I always get this error:
ValueError invalid null reference in method 'IBAPIClient_placeOrder',
argument 2 of type 'OrderId'
I also get this exact error when making a simple
$ibapi->cancelOrder($orderId) call. Something about OrderId seems to be
messed up in the swig handling or I'm doing something wrong.
nextValidId results implies it is a simple integer value which should be
incremented. Doing that results in the same error as hardcoding '1' does.
Subject: | api-demo.pl |
#!/usr/bin/perl
#
# Finance::InteractiveBrokers::SWIG - API demonstration program
#
# (c) 2010-2011 Jason McManus
#
# This demonstration program shows how to use the F::IB::SWIG
# package to work with the IB API, and receive events.
#
# Steps:
# ------
# 0. Set up either the IB Gateway or the TradeWorkstation interface.
# (see the IB API documentation for details. The API must use one
# of these to connect to their service.
# 1. Subclass Finance::InteractiveBrokers::SWIG::EventHandler, create
# actions for its events, and instantiate an object.
# 2. Call Finance::InteractiveBrokers::SWIG->new, and give it your
# handler.
# 3. Call ->eConnect( $host, $port, $id ) giving it the host and
# port of your IB Gateway or TWS server.
# 4. Set up an event loop calling ->processMessages() each time
# through, so that your event handlers will be called.
# 5. When the event loop is through, call ->eDisconnect() to hang up
# politely.
#
use Data::Dumper;
use strict;
use warnings;
use vars qw( $VERSION );
BEGIN {
$VERSION = '0.05';
}
# Ours
use Finance::InteractiveBrokers::SWIG;
use lib '.';
use MyEventHandler;
$|=1;
###
### Variables
###
use vars qw( $TRUE $FALSE );
*TRUE = \1;
*FALSE = \0;
my $ibhost = 'localhost'; # Set to your IB gateway or TWS host
my $ibport = 7496; # Set to your IB gateway or TWS port
my $clientId = 42; # Some random number as a client ID
my $wantstoexit = 0; # Flag to check for ^C; ignore this
###
### Main
###
#
# 1. Create our event handler object to react to incoming events
# (You can see MyEventHandler.pm in this same directory.)
#
my $handler = MyEventHandler->new();
#
# 2. Create a F::IB::SWIG object so we can make requests
#
my $ibapi = Finance::InteractiveBrokers::SWIG->new(
handler => $handler,
);
#
# 3. Tell the API to connect to the IB Gateway or TWS host
#
print "Connecting to $ibhost:$ibport with clientID = $clientId... ";
if( $ibapi->eConnect( $ibhost, $ibport, $clientId ) ) {
print "Connected!\n";
} else {
die "\nConnection to $ibhost:$ibport failed.";
}
#
# Let's set up a signal handler to catch ^C (SIGINT) events
#
$SIG{INT} = sub { $wantstoexit = 1; };
#
# Let's request the current time on the server
#
print "Sending request for current server time.\n";
$ibapi->reqCurrentTime();
#
# Let's also request a quote for MSFT
#
# Set up a contract object
my $contract = Finance::InteractiveBrokers::SWIG::IBAPI::Contract->new();
$contract->swig_symbol_set( 'MSFT' );
$contract->swig_secType_set( 'STK' );
$contract->swig_exchange_set( 'SMART' );
$contract->swig_currency_set( 'USD' );
# Send the request
my $reqId = get_next_id();
print "Sending snapshot request (reqId $reqId) for MSFT.\n";
$ibapi->reqMktData(
$reqId, # next id from the sequence generator
$contract, # above contract object
'', # don't set this if snapshot (next value) is true
$TRUE, # just get a snapshot and immediately cancel
);
#
# 4. MAIN EVENT LOOP; keep going in here until ^C is pressed
#
print "\nLooping to wait for server responses (^C to exit)...\n";
$ibapi->processMessages();
$ibapi->processMessages();
$ibapi->processMessages();
$ibapi->processMessages();
my $orderId = get_next_order_id();
my $order = Finance::InteractiveBrokers::SWIG::IBAPI::Order->new();
$order->swig_orderId_set($orderId);
# $order->swig_clientId_set( $self->client_id );
$order->swig_action_set( 'BUY' );
$order->swig_totalQuantity_set( 100 );
$order->swig_orderType_set('MKT');
$order->swig_transmit_set(1);
$ibapi->placeOrder($orderId, $contract, $order);
$ibapi->processMessages();
$ibapi->processMessages();
$ibapi->processMessages();
$ibapi->processMessages();
#
# 5. Someone wanted to exit, let's clean up nicely.
#
print "^C detected; disconnecting...\n";
$ibapi->eDisconnect()
if( $ibapi->isConnected() );
#
# Bye!
#
print "Bye!\n";
exit( 0 );
###
### Utility subs
###
# Just a closure to continually generate a new req id
#
# In a full program, these should probably be kept in a hash, with
# the Id set to the key, and the value set to 1 (or perhaps a reqtype,
# timestamp, or other meta information), and then deleted as the
# responses come in, or when a cancel request is sent, depending
# on if that's appropriate for the request or not.
#
# Remember, this is a low-level API. Most of this will be done for you
# in the eventual POE component. :-)
#
# See also: the IB API documentation for the reqIDs() call
#
{
my $id = 0;
sub get_next_id
{
return ++$id;
}
}
{
my $id = 0;
sub get_next_order_id
{
return ++$id;
}
}
__END__
Subject: | MyEventHandler.pm |
package MyEventHandler;
#
# Finance::InteractiveBrokers::SWIG - Demonstration event handler subclass
#
# Copyright (c) 2010-2011 Jason McManus
#
# To use this module:
#
# Insert your code into the event handler subroutine skeletons. These
# will be triggered upon receiving the responses from the IB server,
# at the appropriate times, according to their API documentation.
#
# Fill them to do whatever you need to do to react to the event, e.g.
# store data into a database, set a flag, execute a trade, etc.
#
# NOTE: You /should/ double-check to make sure that all of the events
# subroutines exist for the version of the API you compiled against.
#
# You can get a list of events by typing:
#
# perl -MFinance::InteractiveBrokers::SWIG::EventHandler -e'print Finance::InteractiveBrokers::SWIG::EventHandler::override'
#
# at your shell prompt.
#
# Since IB updates its API regularly, if you compile against a newer
# version, it's possible that some events may not be caught below, at
# which point you will receive an exception that looks like:
#
# Finance::InteractiveBrokers::SWIG::EventHandler::EVENTNAME method
# must be overridden
# at line ....
#
use Carp qw( croak confess );
use Data::Dumper;
use strict;
use warnings;
use vars qw( $VERSION );
BEGIN {
$VERSION = '0.05';
}
# Ours
use base qw( Finance::InteractiveBrokers::SWIG::EventHandler );
###
### Event handlers
###
### These will be called by Finance::InteractiveBrokers::SWIG when it
### receives the specified event from the server. They will be called
### with their arguments in the same order as in the IB API documentation.
###
### Only a few methods are filled in for you, but this class will
### operate as a proper handler, and simply discard the events sent to
### the empty subs. It is up to you to fill them in.
###
### Please see the InteractiveBrokers API documentation regarding EWrapper
### for a full description and list of arguments for each method.
###
#
# Connection and Server
#
sub winError
{
my( $self, $str, $lastError ) = @_;
print "Client Error $lastError: $str\n";
return;
}
sub error
{
my( $self, $id, $errorCode, $errorString ) = @_;
if( $errorCode >= 1100 )
{
print "Server Message: code $errorCode: $errorString\n";
}
else
{
print "Server Error: ReqID $id; code $errorCode: $errorString\n";
}
return;
}
sub connectionClosed
{
print "Connection closed.\n";
return;
}
sub currentTime
{
my( $self, $time ) = @_;
printf "Current time on IB server is: %s\n", scalar gmtime( $time );
return;
}
#
# Market Data
#
# Docs here:
# http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/c/tickprice.htm
sub tickPrice
{
my( $self, $reqId, $tickType, $price, $canAutoExecute ) = @_;
printf "tickPrice for reqId %d: type %d, price %.04f, autoexecute? %s\n",
$reqId,
$tickType,
$price,
( $canAutoExecute ? 'Yes' : 'No' );
return;
}
sub tickSize
{
my $self = shift;
print "tickSize event; contains the following data:\n";
print Dumper \@_;
return;
}
sub tickOptionComputation
{
print "tickOptionComputation\n", Dumper \@_;
}
sub tickGeneric
{
print "tickGeneric\n", Dumper \@_;
}
sub tickString
{
my $self = shift;
print "tickString event; contains the following data:\n";
print Dumper \@_;
return;
}
sub tickEFP
{
print "tickEFP\n", Dumper \@_;
}
sub tickSnapshotEnd
{
my( $self, $reqId ) = @_;
print "tickSnapshotEnd for reqID $reqId\n";
return;
}
#
# Orders
#
sub orderStatus
{}
sub openOrder
{}
sub nextValidId
{}
#
# Account and Portfolio
#
sub updateAccountValue
{}
sub updatePortfolio
{}
sub updateAccountTime
{}
#
# News Bulletins
#
sub updateNewsBulletin
{}
#
# Contract Details
#
sub contractDetails
{}
sub contractDetailsEnd
{}
sub bondContractDetails
{}
#
# Executions
#
sub execDetails
{}
sub execDetailsEnd
{}
#
# Market Depth
#
sub updateMktDepth
{}
sub updateMktDepthL2
{}
#
# Financial Advisors
#
sub managedAccounts
{}
sub receiveFA
{}
#
# Historical Data
#
sub historicalData
{
print "historicalData\n", Dumper \@_;
}
#
# Market Scanners
#
sub scannerParameters
{}
sub scannerData
{}
sub scannerDataEnd
{}
#
# Real Time Bars
#
sub realtimeBar
{}
#
# Fundamental Data
#
sub fundamentalData
{}
#
# This has something to do with RFQs
#
sub deltaNeutralValidation
{}
#
# These are in the C++ headers, but not documented in the IB API docs.
#
sub openOrderEnd
{}
sub accountDownloadEnd
{}
1;
__END__
=pod
=head1 NAME
MyEventHandler - Sample Finance::InteractiveBrokers::SWIG::EventHandler subclass
=head1 DESCRIPTION
You may this module as a starter when building your required subclass of
L<Finance::InteractiveBrokers::SWIG::EventHandler>. It is well-commented,
and guides you through the process.
Please see the documentation for
L<Finance::InteractiveBrokers::SWIG::EventHandler> for details on why this
must be done to use this module distribution.
=head1 SEE ALSO
L<Finance::InteractiveBrokers::SWIG>
L<Finance::InteractiveBrokers::SWIG::EventHandler>
L<Alien::InteractiveBrokers>
L<POE::Component::Client::InteractiveBrokers>
L<Finance::InteractiveBrokers::API>
L<Finance::InteractiveBrokers::Java>
L<http://www.swig.org/> - SWIG, the Simplified Wrapper and Interface Generator
The L<POE> documentation, L<POE::Kernel>, L<POE::Session>
L<http://poe.perl.org/> - All about the Perl Object Environment (POE)
L<http://www.interactivebrokers.com/> - The InteractiveBrokers website
L<http://www.interactivebrokers.com/php/apiUsersGuide/apiguide.htm> - The IB API documentation
The F<examples/> directory of this module's distribution
=head1 AUTHORS
Jason McManus, C<< <infidel at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests to
C<bug-finance-interactivebrokers-swig at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Finance-InteractiveBrokers-SWIG>. The authors will be notified, and then you'll
automatically be notified of progress on your bug as changes are made.
If you are sending a bug report, please include:
=over 4
=item * Your OS type, version, Perl version, and other similar information.
=item * The version of Finance::InteractiveBrokers::SWIG you are using.
=item * The version of the InteractiveBrokers API you are using.
=item * If possible, a minimal test script which demonstrates your problem.
=back
This will be of great assistance in troubleshooting your issue.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Finance::InteractiveBrokers::SWIG
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Finance-InteractiveBrokers-SWIG>
=item * AnnoCPAN: Annotated CPAN documentation
L<http://annocpan.org/dist/Finance-InteractiveBrokers-SWIG>
=item * CPAN Ratings
L<http://cpanratings.perl.org/d/Finance-InteractiveBrokers-SWIG>
=item * Search CPAN
L<http://search.cpan.org/dist/Finance-InteractiveBrokers-SWIG/>
=back
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2010-2011 Jason McManus
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
The authors are not associated with InteractiveBrokers, and as such, take
no responsibility or provide no warranty for your use of this module or the
InteractiveBrokers service. You do so at your own responsibility. No
warranty for any purpose is either expressed or implied by your use of this
module suite.
The data from InteractiveBrokers are under an entirely separate license that
varies according to exchange rules, etc. It is your responsibility to
follow the InteractiveBrokers and exchange license agreements with the data.
=cut
# END