Skip to content

Example orderbook subscribe sol. #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8629f99
squashed:
papadpickle Feb 22, 2022
8d04f8a
* using MAINNET.endpoint instead of magic numbers
papadpickle Mar 1, 2022
587e1aa
* added on_close callbacks to handle error in wss connections and sto…
papadpickle Mar 2, 2022
46f206a
style fixup
Mar 2, 2022
2ade336
replaced mtx with shared_ptr trick
papadpickle Mar 4, 2022
3671454
style fixup
Mar 4, 2022
06c7e5d
* added accountSubscriber template class
papadpickle Mar 5, 2022
400efea
minor interface change
papadpickle Apr 1, 2022
2efe235
Merge branch 'main' into example_orderbook_subscribe_sol
papadpickle Apr 1, 2022
3a514b0
style fixup
Apr 1, 2022
c644ad2
Merge branch 'main' into example_orderbook_subscribe_sol
papadpickle May 19, 2022
d014f4c
merged upstream changes and minor improvement
papadpickle May 19, 2022
17946c9
style fixup
May 19, 2022
701d150
merge upstream
papadpickle May 21, 2022
a8b9e1a
decoding the message at account subscriber before passing the data to…
papadpickle May 21, 2022
322b78c
style fixup
May 21, 2022
f8a589f
corrected expired order culling
papadpickle May 22, 2022
b84d2c4
storing whole fill event in trades instead of only price. client can …
papadpickle May 22, 2022
155320f
using leafNode as order struct itself
papadpickle May 22, 2022
e625ded
Merge branch 'mschneider:main' into origin/example_orderbook_subscrib…
papadpickle May 22, 2022
b77315d
added NativeToUi conversion functionality
papadpickle May 24, 2022
d886062
minor log adjustment
papadpickle May 30, 2022
7ac7765
added utest for NativeToUi conversions
papadpickle Jun 4, 2022
1ade8c2
strict concurrency mtxing
papadpickle Jun 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ add_executable(example-get-account-info getAccountInfo.cpp)
add_executable(example-account-subscribe accountSubscribe.cpp)
add_executable(example-send-transaction sendTransaction.cpp)
add_executable(example-place-order placeOrder.cpp)
add_executable(example-orderbook-subscribe orderbookSubscribe.cpp)
add_executable(example-positions positions.cpp)

# link
target_link_libraries(example-get-account-info ${CONAN_LIBS} sol)
target_link_libraries(example-account-subscribe ${CONAN_LIBS} sol)
target_link_libraries(example-send-transaction ${CONAN_LIBS} sol)
target_link_libraries(example-place-order ${CONAN_LIBS} sol)
target_link_libraries(example-orderbook-subscribe ${CONAN_LIBS} sol)
target_link_libraries(example-positions ${CONAN_LIBS} sol)

target_compile_definitions(example-place-order PUBLIC FIXTURES_DIR="${CMAKE_SOURCE_DIR}/tests/fixtures")
105 changes: 105 additions & 0 deletions examples/orderbookSubscribe.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <cpr/cpr.h>
#include <spdlog/spdlog.h>

#include <chrono>
#include <mutex>
#include <websocketpp/client.hpp>
#include <websocketpp/config/asio_client.hpp>

#include "mango_v3.hpp"
#include "solana.hpp"
#include "subscriptions/accountSubscriber.hpp"
#include "subscriptions/orderbook.hpp"

class updateLogger {
public:
updateLogger(
mango_v3::subscription::orderbook& orderbook,
mango_v3::subscription::accountSubscriber<mango_v3::Trades>& trades,
const mango_v3::NativeToUi& nativeToUi)
: orderbook(orderbook), trades(trades), nativeToUi(nativeToUi) {
orderbook.registerUpdateCallback(std::bind(&updateLogger::logUpdate, this));
trades.registerUpdateCallback(std::bind(&updateLogger::logUpdate, this));
orderbook.registerCloseCallback(std::bind(&updateLogger::abort, this));
trades.registerCloseCallback(std::bind(&updateLogger::abort, this));
}

void start() {
orderbook.subscribe();
trades.subscribe();
}

void logUpdate() {
std::scoped_lock lock(logMtx);
auto level1Snapshot = orderbook.getLevel1();
if (level1Snapshot) {
if (level1Snapshot->valid()) {
spdlog::info("============Update============");
auto lastTrade = trades.getAccount()->getLastTrade();
if (lastTrade) {
spdlog::info("Last trade: price {:.2f}, quantity {:.2f}",
nativeToUi.getPrice(lastTrade->price),
nativeToUi.getQuantity(lastTrade->quantity));
} else {
spdlog::info("No trade since the subscription started");
}
spdlog::info("Bid-Ask ({:.2f}) {:.2f}-{:.2f} ({:.2f})",
nativeToUi.getQuantity(level1Snapshot->highestBidSize),
nativeToUi.getPrice(level1Snapshot->highestBid),
nativeToUi.getPrice(level1Snapshot->lowestAsk),
nativeToUi.getQuantity(level1Snapshot->lowestAskSize));
spdlog::info("MidPrice: {:.2f}",
nativeToUi.getPrice(level1Snapshot->midPoint));
spdlog::info("Spread: {:.2f} bps", level1Snapshot->spreadBps);

constexpr auto depth = 2;
spdlog::info("Market depth -{}%: {}", depth,
orderbook.getDepth(-depth));
spdlog::info("Market depth +{}%: {}", depth, orderbook.getDepth(depth));
}
}
}

void abort() {
spdlog::error("websocket subscription error");
throw std::runtime_error("websocket subscription error");
}

private:
mango_v3::subscription::orderbook& orderbook;
mango_v3::subscription::accountSubscriber<mango_v3::Trades>& trades;
const mango_v3::NativeToUi& nativeToUi;
std::mutex logMtx;
};

int main() {
using namespace mango_v3;
const auto& config = MAINNET;
const solana::rpc::Connection solCon;
const auto group = solCon.getAccountInfo<MangoGroup>(config.group);

const auto symbolIt =
std::find(config.symbols.begin(), config.symbols.end(), "SOL");
const auto marketIndex = symbolIt - config.symbols.begin();
assert(config.symbols[marketIndex] == "SOL");

const auto perpMarketPk = group.perpMarkets[marketIndex].perpMarket;
auto market = solCon.getAccountInfo<PerpMarket>(perpMarketPk.toBase58());
assert(market.mangoGroup.toBase58() == config.group);

subscription::accountSubscriber<Trades> trades(market.eventQueue.toBase58());
subscription::orderbook book(market);

mango_v3::NativeToUi nativeToUi(market.quoteLotSize, market.baseLotSize,
group.tokens[QUOTE_INDEX].decimals,
group.tokens[marketIndex].decimals);
updateLogger logger(book, trades, nativeToUi);
logger.start();

using namespace std::literals::chrono_literals;
while (true) {
std::this_thread::sleep_for(100s);
}

return 0;
}
Loading