This document has the following sections:
alpaca-trade-api-cpp
is a C++ client library for the Alpaca Commission Free Trading API.
Alpaca is a modern platform for algorithmic trading. You can use the Alpaca API to communicate with Alpaca’s brokerage service. The API allows your trading algorithm to access real-time price data, place orders, maintain watchlists, manage your portfolio, and more. In order to start trading with Alpaca API, please sign up at https://alpaca.markets/.
Once you have signed up and have familiarized yourself with the API, please check out the C++ client documentation and begin implementing your own algorithm! If you'd rather use a language other than C++, clients are available in several other languages that may better satisfy your needs. You can browse the available API client libraries here.
Always a useful resource, the official HTTP API documentation can be found at https://docs.alpaca.markets/.
For information on building, testing, and contributing to this repository, please see the Contributor Guide.
The Alpaca SDK will check the environment for a number of variables which can be used rather to authenticate with and connect to the Alpaca API.
Environment Variable | Default Value | Description |
---|---|---|
APCA_API_KEY_ID |
Your API Key. | |
APCA_API_SECRET_KEY |
Your API Secret Key. | |
APCA_API_BASE_URL |
paper-api.alpaca.markets |
The endpoint for API calls. Note that the default is paper so you must specify this to switch to the live endpoint. |
APCA_API_DATA_URL |
data.alpaca.markets |
The endpoint for the Data API. |
To instantiate an instance of the API client, the main classes you'll need are:
alpaca::Client
: The main API client class.alpaca::Environment
: A helper class for parsing the required environment variables from the local environment.
Consider the following minimal example usage of these classes:
#include <iostream>
#include "alpaca/client.h"
#include "alpaca/config.h"
int main(int argc, char* argv[]) {
// Parse the required environment variables using the supplied helper utility
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cout << "Error parsing config from environment: "
<< status.getMessage()
<< std::endl;
return status.getCode();
}
// Instantiate an instance of the API client
auto client = alpaca::Client(env)
}
With few exceptions, most API client methods return a std::pair
where the first item in the pair is an instance of alpaca::Status
. The alpaca::Status
class is used to represent the success or failure of the operation. The second item in the pair is the value that is requested, the response of API operation, etc.
// Call the API
auto resp = client.getOrders();
// Check the status returned by the API client before using the response
if (auto status = resp.first; !status.ok()) {
std::cerr << "The API operation failed: " << status.getMessage() << std::endl;
return status.getCode();
}
// Now you can safely use the response object returned by the API
auto orders = resp.second;
for (const auto& order : orders) {
std::cout << "Order ID: " << order.id << std::endl;
}
The Orders API allows a user to monitor, place, and cancel their orders with Alpaca. Each order has a unique identifier provided by the client. This client-side unique order ID will be automatically generated by the system if not provided by the client, and will be returned as part of the order object along with the rest of the fields described below. Once an order is placed, it can be queried using the client-side order ID to check the status. Updates on open orders at Alpaca will also be sent over the streaming interface, which is the recommended method of maintaining order state.
For further details on order functionality, please see the Trading On Alpaca - Orders page.
Consider the following example which exhibits buying 10 shares of NFLX, using the API to retieve the order by ID, and then using the API to cancel all open orders.
// Submit an order to buy 10 shares of NFLX
auto submit_order_response = client.submitOrder(
"NFLX",
10,
alpaca::OrderSide::Buy,
alpaca::OrderType::Market,
alpaca::OrderTimeInForce::Day
);
if (auto status = submit_order_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto order1 = submit_order_response.second;
// Use the API to retrieve the order we just placed.
auto get_order_response = client.getOrder(order.id);
if (auto status = get_order_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto order2 = get_order_response.second;
// Assert the client order IDs are the same for both order objects
assert(order1.client_order_id == order2.client_order_id);
// Cancel existing orders
auto cancel_orders_response = client.cancelOrders();
if (auto status = cancel_orders_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
For more information on the Orders API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/orders/.
The positions API provides information about an account’s current open positions. The response will include information such as cost basis, shares traded, and market value, which will be updated live as price information is updated. Once a position is closed, it will no longer be queryable through this API.
Consider the following example which exhibits how to perform various API operations with the positions API.
// Liquidate all existing positions
auto close_positions_response = client.closePositions()
if (auto status = close_positions_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Submit an order to buy 10 shares of NFLX
auto symbol = "NFLX";
auto submit_order_response = client.submitOrder(
symbol,
10,
alpaca::OrderSide::Buy,
alpaca::OrderType::Market,
alpaca::OrderTimeInForce::Day
);
if (auto status = submit_order_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Get all open positions
auto get_positions_response = client.getPositions();
if (auto status = get_positions_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Ensure there is an open position for the stock we just purchased
auto found_symbol = false;
alpaca::Position found_position;
for (const auto& position : positions) {
if (position.symbol == symbol) {
found_symbol = true;
found_position = position;
break;
}
}
assert(found_symbol);
// Directly retrieve the position for the stock we just purchased
auto get_position_response = client.getPosition(symbol);
if (auto status = get_position_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Ensure the asset ID is the same for the position we found while enumerating
// all positions as well as the position we retrieved by symbol
assert(found_position.asset_id, get_position_response.second.asset_id);
For more information on the Positions API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/positions/.
The assets API serves as the master list of assets available for trade and data consumption from Alpaca. Assets are sorted by asset class, exchange and symbol. Some assets are only available for data consumption via Polygon, and are not tradable with Alpaca. These alpaca::Asset
objects will be marked with the tradable
property set to false
.
Consider the following example which exhibits how to perform various API operations with the assets API.
// Submit an order to buy 10 shares of NFLX
auto symbol = "NFLX";
auto submit_order_response = client.submitOrder(
symbol,
10,
alpaca::OrderSide::Buy,
alpaca::OrderType::Market,
alpaca::OrderTimeInForce::Day
);
if (auto status = submit_order_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Get all assets
auto get_assets_response = client.getAssets();
if (auto status = get_assets_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Ensure there is an asset for the stock we just purchased
auto found_symbol = false;
alpaca::Asset found_asset;
for (const auto& asset : assets) {
if (asset.symbol == symbol) {
found_symbol = true;
found_asset = asset;
break;
}
}
assert(found_asset);
// Directly retrieve the asset for the stock we just purchased
auto get_asset_response = client.getAsset(symbol);
if (auto status = get_asset_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
// Ensure the ID is the same for the asset we found while enumerating all
// asset as well as the asset we retrieved by symbol
assert(found_asset.id, get_asset_response.second.id);
For more information on the Assets API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/assets/.
The watchlist API provides CRUD operation for the account’s watchlist. An account can have multiple watchlists and each is uniquely identified by id but can also be addressed by user-defined name. Each watchlist is an ordered list of assets.
Consider the following example which exhibits how to use the API to create, read, update, and delete a watchlist.
// Create a watchlist
auto create_watchlist_response = client.createWatchlist("My Watchlist", {"GOOG"});
if (auto status = create_watchlist_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto watchlist = create_watchlist_response.second;
// Read the watchlist
auto get_update_response = client.getWatchlist(watchlist.id);
if (auto status = get_watchlist_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto watchlist = get_watchlist_response.second;
// Update the symbols in the watchlist
auto update_watchlist_response = client.updateWatchlist(
watchlist.id,
watchlist.name,
{"GOOG", "FB"}
);
if (auto status = update_watchlist_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
watchlist = update_watchlist_response.second;
// Add a symbol to the watchlist
auto add_symbol_response = client.addSymbolToWatchlist(watchlist.id, "AAPL");
if (auto status = add_symbol_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
watchlist = add_symbol_response.second;
// Remove a symbol from the watchliist
auto remove_symbol_response = client.removeSymbolFromWatchlist(watchlist.id, "AAPL");
if (auto status = remove_symbol_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
watchlist = remove_symbol_response.second;
// Delete the watchlist
auto delete_watchlist_response = client.deleteWatchlist(watchlist.id);
if (auto status = delete_watchlist_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
For more information on the Watchlist API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/watchlist/.
The calendar API serves the full list of market days from 1970 to 2029. It can also be queried by specifying a start and/or end time to narrow down the results. In addition to the dates, the response also contains the specific open and close times for the market days, taking into account early closures.
Consider the following example which exhibits how to find the open and close times for a date range.
auto get_calendar_response = client.getCalendar("2018-01-02", "2018-01-09");
if (auto status = get_calendar_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto dates = get_calendar_response.second;
for (const auto& date : dates) {
std::cout << "On " << date.date <<
<< ", the market opened at " << date.open
<< " and closed at " << date.close
<< "." << std::endl;
}
For more information on the Calendar API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/calendar/.
The clock API serves the current market timestamp, whether or not the market is currently open, as well as the times of the next market open and close.
Consider the following example which exhibits using the API to determiine the time the market will next open:
auto get_clock_response = client.getClock();
if (auto status = get_clock_response.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto clock = get_clock_response.second;
std::cout << "Next open: " << clock.next_open << std::endl;
For more information on the Clock API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/clock/.
The account API serves important information related to an account, including account status, funds available for trade, funds available for withdrawal, and various flags relevant to an account’s ability to trade. An account maybe be blocked for just for trades (the trades_blocked
property of alpaca::Account
) or for both trades and transfers (the account_blocked
property of alpaca::Account
) if Alpaca identifies the account to engaging in any suspicious activity. Also, in accordance with FINRA’s pattern day trading rule, an account may be flagged for pattern day trading (the pattern_day_trader
property of alpaca::Account
), which would inhibit an account from placing any further day-trades.
Consider the following example which exhibits how one can retrieve account information about the account which is currently authenticated.
auto resp = client.getAccount();
if (auto status = resp.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto account = resp.second;
std::cout << "Account has buying power: " << account.buying_power << std::endl;
For more information the Account API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/account/.
The account configuration API provides custom configurations about your trading account settings. These configurations control various allow you to modify settings to suit your trading needs. For DTMC protection, see the documentation on Day Trade Margin Call Protection.
Consider the following example which exhibits how one can check whether or not shorting is enabled and then conditionally enable shorting if it's not.
auto resp = client.getAccountConfigurations();
if (auto status = resp.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
auto account_configurations = resp.second;
if (account_configurations.no_shorting) {
std::cout << "Shorting is disabled for this account." << std::endl;
auto update_resp = client.updateAccountConfigurations(
false,
account_configurations.dtbp_check,
account_configurations.trade_confirm_email,
account_configurations.suspend_trade
);
if (auto status = update_resp.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode();
}
std::cout << "Enabled shorting." << std::endl;
}
std::cout << "Shorting is enabled for this account." << std::endl;
For more information on the Account Configuration API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/account-configuration/.
The account activities API provides access to a historical record of transaction activities that have impacted your account. Trade execution activities and non-trade activities, such as dividend payments, are both reported through this endpoint. At the time of this writing, the following are the types of activities that may be reported:
Activity Type | Description |
---|---|
FILL |
Order fills (both partial and full fills) |
TRANS |
Cash transactions (both CSD and CSR) |
MISC |
Miscellaneous or rarely used activity types (All types except those in TRANS , DIV , or FILL ) |
ACATC |
ACATS IN/OUT (Cash) |
ACATS |
ACATS IN/OUT (Securities) |
CSD |
Cash disbursement(+) |
CSR |
Cash receipt(-) |
DIV |
Dividends |
DIVCGL |
Dividend (capital gain long term) |
DIVCGS |
Dividend (capital gain short term) |
DIVFEE |
Dividend fee |
DIVFT |
Dividend adjusted (Foreign Tax Withheld) |
DIVNRA |
Dividend adjusted (NRA Withheld) |
DIVROC |
Dividend return of capital |
DIVTW |
Dividend adjusted (Tefra Withheld) |
DIVTXEX |
Dividend (tax exempt) |
INT |
Interest (credit/margin) |
INTNRA |
Interest adjusted (NRA Withheld) |
INTTW |
Interest adjusted (Tefra Withheld) |
JNL |
Journal entry |
JNLC |
Journal entry (cash) |
JNLS |
Journal entry (stock) |
MA |
Merger/Acquisition |
NC |
Name change |
OPASN |
Option assignment |
OPEXP |
Option expiration |
OPXRC |
Option exercise |
PTC |
Pass Thru Charge |
PTR |
Pass Thru Rebate |
REORG |
Reorg CA |
SC |
Symbol change |
SSO |
Stock spinoff |
SSP |
Stock split |
Consider the following example which exhibits how one can enumerate both trade and non-trade activity:
auto resp = client.getAccountActivity();
if (auto status = resp.first; !status.ok()) {
std::cerr << "Error calling API: " << status.getMessage() << std::endl;
return status.getCode()
}
auto activities = resp.second;
for (const auto& activity : activities) {
try {
auto trade_activity = std::get<alpaca::TradeActivity>(activity);
std::cout << "Trade Activity: " << std::endl;
std::cout << " - Symbol = " << trade_activity.symbol << std::endl;
std::cout << " - Side = " << trade_activity.side << std::endl;
std::cout << " - Price = " << trade_activity.price << std::endl;
std::cout << " - Quantity = " << trade_activity.qty << std::endl;
} catch (const std::bad_variant_access&) {}
try {
auto non_trade_activity = std::get<alpaca::NonTradeActivity>(activity);
std::cout << "Non-Trade Activity: " << std::endl;
std::cout << " - Activity Type = " << non_trade_activity.activity_type << std::endl;
std::cout << " - Symbol = " << non_trade_activity.symbol << std::endl;
std::cout << " - Quantity = " << non_trade_activity.qty << std::endl;
} catch (const std::bad_variant_access&) {}
}
For more information on the Account Activities API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/account-activities/.
To instantiate an instance of the stream handler, the main classes you'll need are:
alpaca::StreamHandler
: The main stream handler class.alpaca::Environment
: A helper class for parsing the required environment variables from the local environment.
Consider the following minimal example usage of these classes:
#include <iostream>
#include "alpaca/config.h"
#include "alpaca/streaming.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
int main(int argc, char* argv[]) {
// Parse the configuration from the environment
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing environment: " << status.getMessage() << std::endl;
return status.getCode();
}
// Log trade updates
std::function<void(alpaca::stream::DataType data)> on_trade_update = [=](alpaca::stream::DataType data) {
rapidjson::Document d;
d.Parse(data.c_str());
rapidjson::StringBuffer s;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
d.Accept(writer);
std::cout << "Got trade update: " << s.GetString() << std::endl;
};
// Log account updates
std::function<void(alpaca::stream::DataType data)> on_account_update = [=](alpaca::stream::DataType data) {
rapidjson::Document d;
d.Parse(data.c_str());
rapidjson::StringBuffer s;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(s);
d.Accept(writer);
std::cout << "Got account update: " << s.GetString() << std::endl;
};
// Create and run the stream handler
auto handler = alpaca::stream::Handler(on_trade_update, on_account_update);
if (auto status = handler.run(env); !status.ok()) {
std::cerr << "Error running stream handler: " << status.getMessage() << std::endl;
return status.getCode();
}
return 0;
}
For more information on the Streaming API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/streaming/.
Alpaca Data API provides the market data available to the client user. Specifically, the bars API provides time-aggregated price and volume data.
Consider the following example usage of the Bars API.
auto client = alpaca::Client(env);
auto bars_response = client.getBars(
{"AAPL"},
"2020-04-01T09:30:00-04:00",
"2020-04-03T09:30:00-04:00"
);
if (auto status = bars_response.first; !status.ok()) {
std::cerr << "Error getting bars information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto bars = bars_response.second.bars["AAPL"];
auto start_price = bars.front().open_price;
auto end_price = bars.back().close_price;
auto percent_change = (end_price - start_price) / start_price * 100;
std::cout << "AAPL moved " << percent_change << "% over the time range." << std::endl;
For more information on the Market Data API, see the official API documentation: https://alpaca.markets/docs/api-documentation/api-v2/market-data/.
By sending a GET request to the /v2/account
endpoint, you can see various information about your account, such as the amount of buying power available or whether or not it has a PDT flag.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Get our account information.
auto account_response = client.getAccount();
if (auto status = account_response.first; !status.ok()) {
std::cerr << "Error getting account information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto account = account_response.second;
// Check if our account is restricted from trading.
if (account.trading_blocked) {
std::cout << "Account is currently restricted from trading." << std::endl;
}
// Check how much money we can use to open new positions.
std::cout << account.buying_power << " is available as buying power." << std::endl;
return 0;
}
You can use the information from the account endpoint to do things like calculating the daily profit or loss of your account.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Get account info
auto account_response = client.getAccount();
if (auto status = account_response.first; !status.ok()) {
std::cerr << "Error getting account information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto account = account_response.second;
// Check our current balance vs. our balance at the last market close
std::cout << "Equity (cash + long_market_value + short_market_value): " << account.equity;
std::cout << "Equity as of previous trading day: " << account.last_equity;
return 0;
}
If you send a GET request to the /v2/assets
endpoint, you’ll receive a list of US equities.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Get a list of all active assets.
auto assets_response = client.getAssets();
if (auto status = assets_response.first; !status.ok()) {
std::cerr << "Error getting assets information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto assets = assets_response.second;
// Filter the assets down to just those on NASDAQ.
std::vector<alpaca::Asset> nasdaq_assets;
for (const auto& asset : assets) {
if (asset.exchange == "NASDAQ") {
nasdaq_assets.push_back(asset);
}
}
std::cout << "Found " << nasdaq_assets.size() << " assets being traded on the NASDAQ exchange" << std::endl;
return 0;
}
By sending a symbol along with our request, we can get the information about just one asset. This is useful if we just want to make sure that a particular asset is tradable before we attempt to buy it.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Check if AAPL is tradable on the Alpaca platform.
auto asset_response = client.getAsset("AAPL");
if (auto status = asset_response.first; !status.ok()) {
std::cerr << "Error getting asset information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto asset = asset_response.second;
if (asset.tradable) {
std::cout << "We can trade AAPL." << std::endl;
} else {
std::cout << "We can not trade AAPL." << std::endl;
}
return 0;
}
With GET requests to the /v2/calendar
and /v2/clock
endpoints, you can check if the market is open now, or view what times the market will be open or closed on a particular date.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Check if the market is open now.
auto clock_response = client.getClock();
if (auto status = clock_response.first; !status.ok()) {
std::cerr << "Error getting clock information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto clock = clock_response.second;
if (clock.is_open) {
std::cout << "The market is open." << std::endl;
} else {
std::cout << "The market is closed." << std::endl;
}
// Check when the market was open on Dec. 1, 2018
auto date = "2018-12-01";
auto calendar_response = client.getCalendar(date, date);
if (auto status = calendar_response.first; !status.ok()) {
std::cerr << "Error getting calendar information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto days = calendar_response.second;
if (auto size = days.size(); size != 1) {
std::cerr << "Expected to receive 1 day result but got " << size << "instead." << std::endl;
}
auto day = days.front();
std::cout << "The market opened at " << day.open << " and closed at " << day.close << " on " << day.date << "."
<< std::endl;
return 0;
}
These are examples of some of the things you can do with order objects through the Alpaca API. For additional help understanding different types of orders and how they behave once they’re placed, please see this page.
Orders can be placed with a POST request to the /v2/orders
endpoint.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Submit a market order to buy 1 share of Apple at market price
auto buy_response =
client.submitOrder("AAPL", 1, alpaca::OrderSide::Buy, alpaca::OrderType::Market, alpaca::OrderTimeInForce::Day);
if (auto status = buy_response.first; !status.ok()) {
std::cerr << "Error submitting purchase order: " << status.getMessage() << std::endl;
return status.getCode();
}
// Submit a limit order to attempt to sell 1 share of AMD at a particular
// price ($20.50) when the market opens
auto sell_response = client.submitOrder(
"AMD", 1, alpaca::OrderSide::Sell, alpaca::OrderType::Limit, alpaca::OrderTimeInForce::OPG, "20.50");
if (auto status = sell_response.first; !status.ok()) {
std::cerr << "Error submitting sell order: " << status.getMessage() << std::endl;
return status.getCode();
}
return 0;
}
Client Order IDs can be used to organize and track specific orders in your client program.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Submit a market order to buy 1 share of Apple at market price
auto buy_response = client.submitOrder("AAPL",
1,
alpaca::OrderSide::Buy,
alpaca::OrderType::Market,
alpaca::OrderTimeInForce::Day,
"",
"",
false,
"my_first_order");
if (auto status = buy_response.first; !status.ok()) {
std::cerr << "Error submitting purchase order: " << status.getMessage() << std::endl;
return status.getCode();
}
// Get order by it's client order ID
auto get_order_response = client.getOrderByClientOrderID("my_first_order");
if (auto status = get_order_response.first; !status.ok()) {
std::cerr << "Error getting order: " << status.getMessage() << std::endl;
return status.getCode();
}
auto order = get_order_response.second;
std::cout << "Got order by client order ID: " << order.id;
return 0;
}
If you’d like to see a list of your existing orders, you can send a get request to the /v2/orders
endpoint.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Get the last 100 of our closed orders
auto list_orders_response = client.getOrders(alpaca::ActionStatus::Closed, 100);
if (auto status = list_orders_response.first; !status.ok()) {
std::cerr << "Error listing orders: " << status.getMessage() << std::endl;
return status.getCode();
}
auto orders = list_orders_response.second;
// Get only the closed orders for a particular stock
std::vector<alpaca::Order> aapl_orders;
for (const auto& order : orders) {
if (order.symbol == "AAPL") {
aapl_orders.push_back(order);
}
}
std::cout << "Found " << aapl_orders.size() << " closed orders for AAPL." << std::endl;
return 0;
}
You can view the positions in your portfolio by making a GET request to the /v2/positions
endpoint. If you specify a symbol, you’ll see only your position for the associated stock.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
auto client = alpaca::Client(env);
// Get our position in AAPL.
auto get_position_response = client.getPosition("AAPL");
if (auto status = get_position_response.first; status.ok()) {
auto position = get_position_response.second;
std::cout << "Apple position: " << position.qty << " shares." << std::endl;
} else {
std::cout << "No AAPL position.";
}
// Get a list of all of our positions.
auto get_positions_response = client.getPositions();
if (auto status = get_positions_response.first; !status.ok()) {
std::cerr << "Error getting positions information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto positions = get_positions_response.second;
for (const auto& position : positions) {
std::cout << position.qty << " shares in " << position.symbol << std::endl;
}
return 0;
}
By using the data API, you can see what a stock price was at a particular time, information about the last trade and last quote, etc.
#include <iostream>
#include "alpaca/alpaca.h"
int main(int argc, char* argv[]) {
// Parse configuration from the environment
auto env = alpaca::Environment();
if (auto status = env.parse(); !status.ok()) {
std::cerr << "Error parsing config from environment: " << status.getMessage() << std::endl;
return status.getCode();
}
// Create an API client object
auto client = alpaca::Client(env);
auto bars_response = client.getBars({"AAPL"}, "2020-04-01T09:30:00-04:00", "2020-04-03T09:30:00-04:00");
if (auto status = bars_response.first; !status.ok()) {
std::cerr << "Error getting bars information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto bars = bars_response.second.bars["AAPL"];
auto start_price = bars.front().open_price;
auto end_price = bars.back().close_price;
auto percent_change = (end_price - start_price) / start_price * 100;
std::cout << "AAPL moved " << percent_change << "% over the time range." << std::endl;
auto last_trade_response = client.getLastTrade("AAPL");
if (auto status = last_trade_response.first; !status.ok()) {
std::cerr << "Error getting last trade information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto last_trade = last_trade_response.second;
std::cout << "The last traded price of AAPL was: $" << last_trade.trade.price << std::endl;
auto last_quote_response = client.getLastQuote("AAPL");
if (auto status = last_quote_response.first; !status.ok()) {
std::cerr << "Error getting last quote information: " << status.getMessage() << std::endl;
return status.getCode();
}
auto last_quote = last_quote_response.second;
std::cout << "The last quoted ask price of AAPL was: $" << last_quote.quote.ask_price << std::endl;
return 0;
}
Since alpaca-trade-api-cpp
is built using the Bazel build system, the easiest way to use this library is if your C++ is also built using Bazel.
To make it as easy as possible to get started, we also publish the Alpaca C++ Starter Template which is a GitHub repository template for setting up a new Bazel build environment with the Alpaca C++ API Client pre-configured. You can use this template by clicking here.
For stability and security reasons, it is worth using a pinned version of this library. For example, if you'd like to use version 0.0.2
, you may add the following http_archive
stanza to your WORKSPACE
file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_github_marpaia_alpaca_trade_api_cpp",
strip_prefix = "alpaca-trade-api-cpp-0.0.2",
urls = ["https://github.com/marpaia/alpaca-trade-api-cpp/archive/v0.0.2.tar.gz"],
sha256 = "65aa17318d356ff7cfc55e6510cebcf1ab94c3d7a3eb0f6175a197b503cb7dfe",
)
To depend on the master
branch of this repository, you could alternativly add the following to your WORKSPACE
file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_github_marpaia_alpaca_trade_api_cpp",
strip_prefix = "alpaca-trade-api-cpp-master",
urls = ["https://github.com/marpaia/alpaca-trade-api-cpp/archive/master.tar.gz"],
)
Once you've added the appropriate http_archive
stanza to your WORKSPACE
file, add the following to initialize all transient dependencies:
load("@com_github_marpaia_alpaca_trade_api_cpp//bazel:deps.bzl", "alpaca_deps")
alpaca_deps()
All in all, your WORKSPACE
file should contain:
################################################################################
# General Initialization
################################################################################
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
################################################################################
# C++ Dependencies
################################################################################
# alpaca-trade-api-cpp is a C++ client library for the Alpaca Trading API.
http_archive(
name = "com_github_marpaia_alpaca_trade_api_cpp",
strip_prefix = "alpaca-trade-api-cpp-0.0.2",
urls = ["https://github.com/marpaia/alpaca-trade-api-cpp/archive/v0.0.2.tar.gz"],
sha256 = "65aa17318d356ff7cfc55e6510cebcf1ab94c3d7a3eb0f6175a197b503cb7dfe",
)
load("@com_github_marpaia_alpaca_trade_api_cpp//bazel:deps.bzl", "alpaca_deps")
alpaca_deps()
To compile a program, you must add the dependency to the desired target to deps
in a BUILD
file. For example, consider the following cpp_binary
stanza:
cc_binary(
name = "trading_algo",
srcs = ["main.cpp"],
deps = [
"@com_github_marpaia_alpaca_trade_api_cpp//alpaca:alpaca",
],
)