-
Notifications
You must be signed in to change notification settings - Fork 16
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
papadpickle
wants to merge
24
commits into
mschneider:main
Choose a base branch
from
papadpickle:example_orderbook_subscribe_sol
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
8629f99
squashed:
papadpickle 8d04f8a
* using MAINNET.endpoint instead of magic numbers
papadpickle 587e1aa
* added on_close callbacks to handle error in wss connections and sto…
papadpickle 46f206a
style fixup
2ade336
replaced mtx with shared_ptr trick
papadpickle 3671454
style fixup
06c7e5d
* added accountSubscriber template class
papadpickle 400efea
minor interface change
papadpickle 2efe235
Merge branch 'main' into example_orderbook_subscribe_sol
papadpickle 3a514b0
style fixup
c644ad2
Merge branch 'main' into example_orderbook_subscribe_sol
papadpickle d014f4c
merged upstream changes and minor improvement
papadpickle 17946c9
style fixup
701d150
merge upstream
papadpickle a8b9e1a
decoding the message at account subscriber before passing the data to…
papadpickle 322b78c
style fixup
f8a589f
corrected expired order culling
papadpickle b84d2c4
storing whole fill event in trades instead of only price. client can …
papadpickle 155320f
using leafNode as order struct itself
papadpickle e625ded
Merge branch 'mschneider:main' into origin/example_orderbook_subscrib…
papadpickle b77315d
added NativeToUi conversion functionality
papadpickle d886062
minor log adjustment
papadpickle 7ac7765
added utest for NativeToUi conversions
papadpickle 1ade8c2
strict concurrency mtxing
papadpickle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#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 "orderbook/levelOne.hpp" | ||
#include "orderbook/orderbook.hpp" | ||
#include "solana.hpp" | ||
#include "subscriptions/bookSide.hpp" | ||
#include "subscriptions/trades.hpp" | ||
|
||
class updateLogger { | ||
public: | ||
updateLogger(mango_v3::orderbook::book& orderbook, | ||
mango_v3::subscription::trades& trades) | ||
: orderbook(orderbook), trades(trades) { | ||
orderbook.registerUpdateCallback(std::bind(&updateLogger::logUpdate, this)); | ||
trades.registerUpdateCallback(std::bind(&updateLogger::logUpdate, this)); | ||
} | ||
|
||
void start() { | ||
orderbook.subscribe(); | ||
trades.subscribe(); | ||
} | ||
|
||
void logUpdate() { | ||
const std::scoped_lock lock(updateMtx); | ||
auto level1Snapshot = orderbook.getLevel1(); | ||
if (level1Snapshot.valid()) { | ||
spdlog::info("============Update============"); | ||
spdlog::info("Latest trade: {}", trades.getLastTrade() | ||
? to_string(trades.getLastTrade()) | ||
: "not received yet"); | ||
spdlog::info("Bid-Ask {}-{}", level1Snapshot.highestBid, | ||
level1Snapshot.lowestAsk); | ||
spdlog::info("MidPrice: {}", level1Snapshot.midPoint); | ||
spdlog::info("Spread: {0:.2f} bps", level1Snapshot.spreadBps); | ||
|
||
constexpr auto depth = 2; | ||
spdlog::info("Market depth -{}%: {}", depth, orderbook.getDepth(-depth)); | ||
spdlog::info("Market depth +{}%: {}", depth, orderbook.getDepth(depth)); | ||
} | ||
} | ||
|
||
private: | ||
std::mutex updateMtx; | ||
mango_v3::orderbook::book& orderbook; | ||
mango_v3::subscription::trades& trades; | ||
}; | ||
|
||
int main() { | ||
const auto& config = mango_v3::MAINNET; | ||
const solana::rpc::Connection solCon; | ||
const auto group = solCon.getAccountInfo<mango_v3::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<mango_v3::PerpMarket>(perpMarketPk.toBase58()); | ||
assert(market.mangoGroup.toBase58() == config.group); | ||
|
||
mango_v3::subscription::bookSide bids(mango_v3::Buy, market.bids.toBase58()); | ||
mango_v3::subscription::bookSide asks(mango_v3::Sell, market.asks.toBase58()); | ||
mango_v3::subscription::trades trades(market.eventQueue.toBase58()); | ||
|
||
mango_v3::orderbook::book orderbook(bids, asks); | ||
|
||
updateLogger logger(orderbook, trades); | ||
logger.start(); | ||
|
||
while (true) { | ||
} | ||
return 0; | ||
} | ||
|
||
// void updateReceived() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
|
||
namespace mango_v3 { | ||
namespace orderbook { | ||
|
||
struct levelOne { | ||
uint64_t highestBid; | ||
uint64_t highestBidSize; | ||
uint64_t lowestAsk; | ||
uint64_t lowestAskSize; | ||
double midPoint; | ||
double spreadBps; | ||
|
||
bool valid() const { | ||
return ((highestBid && lowestAsk) && (lowestAsk > highestBid)) ? true | ||
: false; | ||
} | ||
}; | ||
|
||
} // namespace orderbook | ||
} // namespace mango_v3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
|
||
namespace mango_v3 { | ||
namespace orderbook { | ||
|
||
struct order { | ||
order(uint64_t price, uint64_t quantity) : price(price), quantity(quantity) {} | ||
|
||
bool operator<(const order& compare) const { | ||
return (price < compare.price) ? true : false; | ||
} | ||
|
||
bool operator>(const order& compare) const { | ||
return (price > compare.price) ? true : false; | ||
} | ||
|
||
uint64_t price; | ||
uint64_t quantity; | ||
}; | ||
|
||
} // namespace orderbook | ||
} // namespace mango_v3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#pragma once | ||
#include <spdlog/spdlog.h> | ||
|
||
#include <functional> | ||
#include <mutex> | ||
|
||
#include "levelOne.hpp" | ||
#include "orderbook/order.hpp" | ||
#include "subscriptions/bookSide.hpp" | ||
|
||
namespace mango_v3 { | ||
namespace orderbook { | ||
class book { | ||
public: | ||
book(subscription::bookSide& bids, subscription::bookSide& asks) | ||
: bids(bids), asks(asks) { | ||
bids.registerUpdateCallback(std::bind(&book::updateCallback, this)); | ||
asks.registerUpdateCallback(std::bind(&book::updateCallback, this)); | ||
} | ||
|
||
void registerUpdateCallback(std::function<void()> callback) { | ||
onUpdateCb = callback; | ||
} | ||
|
||
void subscribe() { | ||
bids.subscribe(); | ||
asks.subscribe(); | ||
} | ||
|
||
void updateCallback() { | ||
const std::scoped_lock lock(callbackMtx); | ||
levelOne newL1; | ||
auto bestBid = bids.getBestOrder(); | ||
auto bestAsk = asks.getBestOrder(); | ||
newL1.highestBid = bestBid.price; | ||
newL1.highestBidSize = bestBid.quantity; | ||
newL1.lowestAsk = bestAsk.price; | ||
newL1.lowestAskSize = bestAsk.quantity; | ||
|
||
if (newL1.valid()) { | ||
newL1.midPoint = ((double)newL1.lowestAsk + newL1.highestBid) / 2; | ||
newL1.spreadBps = | ||
((newL1.lowestAsk - newL1.highestBid) * 10000) / newL1.midPoint; | ||
{ | ||
const std::scoped_lock lock(levelOneMtx); | ||
level1 = newL1; | ||
} | ||
onUpdateCb(); | ||
} | ||
} | ||
|
||
levelOne getLevel1() const { | ||
const std::scoped_lock lock(levelOneMtx); | ||
return level1; | ||
} | ||
|
||
uint64_t getDepth(int8_t percent) { | ||
const std::scoped_lock lock(levelOneMtx); | ||
auto price = (level1.midPoint * (100 + percent)) / 100; | ||
return (percent > 0) ? asks.getVolume<std::less_equal<uint64_t>>(price) | ||
: bids.getVolume<std::greater_equal<uint64_t>>(price); | ||
} | ||
|
||
private: | ||
levelOne level1; | ||
// todo:macos latomic not found issue, otherwise replace mtx with std::atomic | ||
mutable std::mutex levelOneMtx; | ||
std::function<void()> onUpdateCb; | ||
std::mutex callbackMtx; | ||
subscription::bookSide& bids; | ||
subscription::bookSide& asks; | ||
}; | ||
} // namespace orderbook | ||
} // namespace mango_v3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good, want to open a new issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. #22