SkillAgentSearch skills...

Openat

OpenAT: Open Source Algorithmic Trading Library

Install / Use

npx skills add galeone/openat

Installs into whichever agent you are using.

About this skill

Quality Score

0/100

Supported Platforms

Universal

README

OpenAT: Open Source Algorithmic Trading Library

OpenAT provides an easy to use C++ interface for working with (crypto-)currencies markets and exchanges.

The aim is to give to the user the possibility to build it's own generic (crypto-)currency trading bot or daemon (check out an example of crypto trading daemon and currency price monitor (WIP!): Openatd: OpenAT Daemon.

OpenAT is divided in 3 different parts:

  1. Market: place/cancel orders, monitor order book, access history of placed/cancelled orders, global balance, balance per coin, ...
  2. Global market data monitoring: crypto currency price, volume, markets, fiat value, ...
  3. Exchange: change a currency for another currency without defining the price (shapeshift like)

Everything using a strong typing system: every request returns a well defined type, the request to the markets are created using C++ structure: you will never fill a JSON field manually.

Have a look at types.hpp.

This project is in early stage and needs your help!

Examples

The best way to understand how OpenAT works is looking at the examples.

Market

Every implemented market satisfies the contract with the Market interface: you can write code that works with a general Market and just use any available implementation.

Market: available coins

// A call to `coins()` returns `std::map<std::string, coin_t>` where the key is the name of the coin
// and the value is a `coin_t` type, which contains basic informations about the coin
// like t's name, the symbol and it's status

auto coins = market->coins();
for(const auto& pair : coins) {
    auto coin = pair.second;
    std::cout << "name: " << coin.name << " symbol: " << coin.symbol << " status: "
              << coin.status << "\n";
}

Market: available pairs and pair info

// Given the market variable `market`
// market->info() returns a std::vector<market_info_t> where each entry of the
// vector contains the information about any available pair in the market

auto pair_info = market->info();
for(const auto& info : pair_info) {
    std::cout << "pair: " << info.pair << " " << "limits: " << info.limit << " fees: "
              << "maker: " << info.maker_fee << " taker: " << info.taker_fee << "\n";
}

You can specify the pair you're interested in, hence:

// information about the ETH/EUR pair
auto info = market->info(currency_pair_t("eth", "eur");
std::cout << "pair: " << info.pair << " " << "limits: " << info.limit << " fees: "
          << "maker: " << info.maker_fee << " taker: " << info.taker_fee << "\n";

Market: ticker per pair

// given a certain pair, obtain the ticker information
auto ticker = market->ticker(currency_pair_t("eth", "eur"));

// ticker is a struct with 2 `quotation_t` fileds: bid and ask

std::cout << "bid:\n\price: " << ticker.bid.price << " amount: " << ticker.bid.amount << " time: " << ticker.bid.time << "\n";

std::cout << "ask:\n\price: " << ticker.ask.price << " amount: " << ticker.ask.amount << " time: " << ticker.ask.time << "\n";

Market: order book per pair
// a call to the `orderBook(pair)` returns a std::vector<ticker_t>
auto order_book = market->orderBook(currency_pair_t("eth", "eur"));
for(const auto& order : order_book) {
    // handle the `ticker_t` fields, see previous example
}
Market: balance per currency and global balance
// The method balance has 2 versions:
// 1. `std::map<std::string, double> balance()` which returns the pair `symbol`,`balance`
auto balances = market->balance();
for(const auto& pair : balances) {
    std::cout << pair.first << ": " << pair.second << "\n";
}
// 2. `double balance(std::string symbol)` which returns the balance for the specified symbol

auto btc = market->balance("BTC");
std::cout << "BTC: " << btc << "\n";
Market: list of open and closed orders
// We can get the list of closed orders (a std::vector<order_t>) calling
auto closed_orders = market->closedOrders();
for(const auto order : closed_orders) {
    std::cout << "txid: " << order.txid
              << " status: " << order.status
              << " type: " << order.type
              << " action: " << order.action
              << " pair: " << order.pair
              << " open time: " << order.open
              << " close time: " << order.close
              << " volume: " << order.volume
              << " cost: " << order.cost
              << " fee: " << order.fee
              << " price: " << order.price;
}

// We can get the list of open orders calling
auto open_orders = market->openOrders();
for(const auto order : open_orders) {
    std::cout << "txid: " << order.txid
              << " status: " << order.status
              << " type: " << order.type
              << " action: " << order.action
              << " pair: " << order.pair
              << " open time: " << order.open
              << " close time: " << order.close
              << " volume: " << order.volume
              << " cost: " << order.cost
              << " fee: " << order.fee
              << " price: " << order.price;
}

Market: place and cancel order
// Given an open order, close it (use the txid to identify the order on the market)
auto close_me = open_orders[0];
market->close(close_me);

// Place a limit order for a certain pair
// let's buy a litecoin with EUR
order_t limit;
limit.pair = currency_pair_t("LTC", "EUR");
limit.volume = 1;
limit.action = order_action_t::buy; // BUY
limit.type = order_type_t::limit; // limit order
// place
try {
    market->place(limit);
}
catch(...) {
    // handle the exception in case of error
}

// Place a market order (no specify the price)
// half ltc per eur
order_t market;
market.pair = currency_pair_t("LTC", "EUR");
market.volume = 0.5;
market.action = order_action_t::buy;
market.type = order_type_t::market;
// place
try {
    market->place(market);
} catch(...) {
    // handle errors
}

// Sell LTC for eur, market order
order_t market;
market.pair = currency_pair_t("LTC", "EUR");
market.volume = 0.5;
market.action = order_action_t::sell; // SELL order
market.type = order_type_t::market;
// place
try {
    market->place(market);
} catch(...) {
    // handle errors
}

At the moment of writing the only implementation of the Market interface is for https://kraken.com/. But pull requests for any other market are more than welcome!

Global market data monitor

OpenAT contains a client for the coinmarketcap.com API and also it's able to parse the webpage of the currencies in order to extract information about certain currencies that are available only in the website and not in the API.

The interface is easy and intuitive:

// ticker returns a vector of `cm_ticker_t`, where `cm` stands for cumulative
// The struct it's easy, so no further explaination are required:
/*
typedef struct {
    std::string id, name, symbol;
    int rank;
    double price_usd, price_btc;
    long long int day_volume_usd, market_cap_usd, available_supply,
        total_supply;
    float percent_change_1h, percent_change_24h, percent_change_7d;
    std::time_t last_updated;
} cm_ticker_t;
*/
std::vector<cm_ticker_t> ticker();

// The call to ticer(uint32_t limit) it's the same of limit() but returns only
// the first `limit` currencies
std::vector<cm_ticker_t> ticker(uint32_t limit);

// ticker(std::string currency_symbol) returns a single `cm_ticker_t`
// for the specified currency
cm_ticker_t ticker(std::string currency_symbol);

// markets(std::string currency_symbol) returns the information parsed from the website
// about the markets where the specified symbol is traded on.
// The cm_market_t struct is:
/*
typedef struct {
    std::string name;
    currency_pair_t pair;
    long long int day_volume_usd;
    double price_usd;
    float percent_volume;
    std::time_t last_updated;
} cm_market_t;
*/
std::vector<cm_market_t> markets(std::string currency_symbol);

// A call to global() returns the overall information about the cryptomarket
// gm_data_t is:
/*
typedef struct {
    long long int total_market_cap_usd, total_24h_volume_usd;
    float bitcoin_percentage_of_market_cap;
    int active_currencies, active_assets, active_markets;
} gm_data_t;
*/
gm_data_t global();

Exchange

OpenAT contains also a client for https://shapeshift.com/. The shapeshift.hpp file is documented (and it's nothing more than the shapeshift API documentation), you can use it as documentation.

Build

Clone the repository and make sure to clone the submodules too:

git clone --recursive https://github.com/galeone/openat

Building on (Arch)linux

# Install the required dependencies

sudo pacman -S spdlog nlohmann-json gumbo-parser sqlite
# install gumbo query to your system
cd libs/gumbo/query/build
cmake ..
make
sudo make install
# if there are problem with the static library, remove the last line
# `libfind_process(Gumbo)`
# from libs/gumbo/query/cmake/FindGumbo.cmake
cd -
# Install curlpp, or with yay -S curlpp
# or using the submodule
cd libs/curlpp
mkdir build
cd build
cmake ..
make
sudo make install
cd -
# build openat
mkdir build
cd build
cmake ..
CC=clang CXX=clang++ make

Building on macOS

Install the needed dependencies and remember to link them:

brew install gcc
brew install openssl sqlite
brew link sqlite --force

For security reasons, HomeBrew doesn't allow to symlink OpenSSL to /usr/local. You will need to manually tell cmake where to find these libraries. Make sure to provide cmake with the correct version of the OpenSSL (1.1).

You can now proceed and build at:

mkdi

Related Skills

View on GitHub
GitHub Stars76
CategoryDevelopment
Updated16d ago
Forks13

Languages

C++

Security Score

95/100

Audited on Jul 22, 2026

No findings