Alpaca sell order in Perl

57 views Asked by At

I have read the LWP documentation, the Alpaca API documentation for its primitives, and numerous examples in other languages. I can't get POSTs to work in Perl. GETS work fine. POSTs work fine in curl or Python, but I can't find the right syntax for Perl.

I always get {"code":40010000,"message":"request body format is invalid"} Always.

Working in the sandbox, of course. Here are some subroutines I have tried.

use LWP::UserAgent;

my vars...

while ($line = <POSITIONS>) {
 ($ticker, $date8601, $epoch, $side, $qty0, $entryprice, $unrealized) = split(",", $line);
 sellorder5($url, $API, $secret, $ticker, $qty0);
}

sub sellorder5 {
    $req=HTTP::Request->new(POST=>$url);
    $req->header( 'APCA-API-KEY-ID' => $API, 'APCA-API-SECRET-KEY' => $secret, 'content-type' => 'application/json');
    $req->content('{"symbol":"$ticker","qty":"$qty0","side":"sell","type":"market","time_in_force":"gtc"}');
    $resp = $browser->request($req);
    $raw_text = $resp->decoded_content;
}

sub sellorder4 {
    $req = HTTP::Request->new(POST => $url);      # Create a request
    $req->header( 'APCA-API-KEY-ID' => $API, 'APCA-API-SECRET-KEY' => $secret, 'content-type' => 'application/json');
    $req->content('{"symbol":"$ticker", "qty":"$qty0", "side":"sell", "type":"market", "time_in_force":"gtc"}');
    $resp = $browser->request($req);
    $raw_text = $resp->content;
}

sub sellorder3 {
    $req = HTTP::Request->new(POST => $url);
    $req->header( 'APCA-API-KEY-ID' => $API, 'APCA-API-SECRET-KEY' => $secret, 'content-type' => 'application/json');
    $post_data = '{ "symbol":"$ticker", "qty":"$qty0", "side":"sell", "type":"market", "time_in_force":"gtc" }';
    $req->content($post_data);
    $resp = $browser->request($req);
    $raw_text = $resp->decoded_content;
}

sub sellorder2 {
    my $req = HTTP::Request->new(POST => $url);
    $req->header( 'APCA-API-KEY-ID' => $API, 'APCA-API-SECRET-KEY' => $secret);
    $post_data = '{ "symbol":"$ticker",  "qty" : $qty0,  "side" : "sell",  "type" : "market",  "time_in_force" : "gtc" }';
    $req->content($post_data);
    $response = $browser->request($req);
    $raw_text = $response->decoded_content;
}

sub sellorder {
   $response = $browser->post($url, 'APCA-API-KEY-ID' , $API, 'APCA-API-SECRET-KEY' , $secret, [ 'symbol'  => '$ticker', 'qty' => '$qty0', 'side' => 'sell', 'type' => 'market', 'time_in_force' => 'gtc' ] );
    $raw_text = $response->content;
    $raw_text =~ s/[\x00-\x1f]//g;      #remove stray characters, and make into one line
}

I would appreciate a working example if someone has one. Thanks.

1

There are 1 answers

1
tobyink On

Your problem is this line:

$req->content('{"symbol":"$ticker","qty":"$qty0","side":"sell","type":"market","time_in_force":"gtc"}');

Single quotes are for strings without interpolation. So $ticker won't be the contents of the $ticker variable, but a string consisting of the dollar sign followed by the word "ticker".

Double quotes will interpolate variables, so:

$req->content("{\"symbol\":\"$ticker\",\"qty\":\"$qty0\",\"side\":\"sell\",\"type\":\"market\",\"time_in_force\":\"gtc\"}");

Of course, that's ugly. So you could use qq// instead, the interpolating quote-like operator.

$req->content(qq/{"symbol":"$ticker","qty":"$qty0","side":"sell","type":"market","time_in_force":"gtc"}/);

But better yet, don't hand-write your JSON. Instead use JSON::PP or similar.

use JSON::PP qw( encode_json decode_json );

# ...

$req->content( encode_json( {
  symbol         => $ticker,
  qty            => $qty0,
  side           => 'sell',
  type           => 'market',
  time_in_force  => 'gtc',
} ) );