Skip to content

Commit

Permalink
Merge pull request #445 from crypto-chassis/ws_balance_position
Browse files Browse the repository at this point in the history
dev: add experimental websocket update for balance and position for b…
  • Loading branch information
cryptochassis authored Oct 24, 2023
2 parents b4b4b79 + 6f0f6a4 commit c96709e
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 24 deletions.
10 changes: 10 additions & 0 deletions include/ccapi_cpp/ccapi_macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,18 @@
#ifndef CCAPI_UNKNOWN
#define CCAPI_UNKNOWN "unknown"
#endif
#ifndef CCAPI_EM_ORDER_UPDATE
#define CCAPI_EM_ORDER_UPDATE "ORDER_UPDATE"
#endif
#ifndef CCAPI_EM_PRIVATE_TRADE
#define CCAPI_EM_PRIVATE_TRADE "PRIVATE_TRADE"
#endif
#ifndef CCAPI_EM_BALANCE_UPDATE
#define CCAPI_EM_BALANCE_UPDATE "BALANCE_UPDATE"
#endif
#ifndef CCAPI_EM_POSITION_UPDATE
#define CCAPI_EM_POSITION_UPDATE "POSITION_UPDATE"
#endif
#ifndef CCAPI_EM_ORDER_SIDE
#define CCAPI_EM_ORDER_SIDE "SIDE"
#endif
Expand Down
8 changes: 8 additions & 0 deletions include/ccapi_cpp/ccapi_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class Message CCAPI_FINAL {
MARKET_DATA_EVENTS_CANDLESTICK,
EXECUTION_MANAGEMENT_EVENTS_ORDER_UPDATE,
EXECUTION_MANAGEMENT_EVENTS_PRIVATE_TRADE,
EXECUTION_MANAGEMENT_EVENTS_BALANCE_UPDATE,
EXECUTION_MANAGEMENT_EVENTS_POSITION_UPDATE,
SUBSCRIPTION_STARTED,
SUBSCRIPTION_FAILURE,
SESSION_CONNECTION_UP,
Expand Down Expand Up @@ -110,6 +112,12 @@ class Message CCAPI_FINAL {
case Type::EXECUTION_MANAGEMENT_EVENTS_PRIVATE_TRADE:
output = "EXECUTION_MANAGEMENT_EVENTS_PRIVATE_TRADE";
break;
case Type::EXECUTION_MANAGEMENT_EVENTS_BALANCE_UPDATE:
output = "EXECUTION_MANAGEMENT_EVENTS_BALANCE_UPDATE";
break;
case Type::EXECUTION_MANAGEMENT_EVENTS_POSITION_UPDATE:
output = "EXECUTION_MANAGEMENT_EVENTS_POSITION_UPDATE";
break;
case Type::SUBSCRIPTION_STARTED:
output = "SUBSCRIPTION_STARTED";
break;
Expand Down
3 changes: 2 additions & 1 deletion include/ccapi_cpp/ccapi_subscription.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class Subscription CCAPI_FINAL {
this->optionMap[optionKeyValue.at(0)] = optionKeyValue.at(1);
}
}
std::set<std::string> executionManagementSubscriptionFieldSet = {std::string(CCAPI_EM_ORDER_UPDATE), std::string(CCAPI_EM_PRIVATE_TRADE)};
std::set<std::string> executionManagementSubscriptionFieldSet = {std::string(CCAPI_EM_ORDER_UPDATE), std::string(CCAPI_EM_PRIVATE_TRADE),
std::string(CCAPI_EM_BALANCE_UPDATE), std::string(CCAPI_EM_POSITION_UPDATE)};
if (field == CCAPI_GENERIC_PUBLIC_SUBSCRIPTION) {
this->serviceName = CCAPI_MARKET_DATA;
} else if (field == CCAPI_FIX || field == CCAPI_FIX_MARKET_DATA || field == CCAPI_FIX_EXECUTION_MANAGEMENT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,44 @@ class ExecutionManagementServiceBinanceBase : public ExecutionManagementService
messageList.emplace_back(std::move(message));
}
}
} else if (this->isDerivatives && type == "ACCOUNT_UPDATE") {
event.setType(Event::Type::SUBSCRIPTION_DATA);
const rj::Value& data = document["a"];
if (fieldSet.find(CCAPI_EM_BALANCE_UPDATE) != fieldSet.end() && !data["B"].Empty()) {
Message message;
message.setTimeReceived(timeReceived);
message.setCorrelationIdList({subscription.getCorrelationId()});
message.setTime(TimePoint(std::chrono::milliseconds(std::stoll(document["E"].GetString()))));
message.setType(Message::Type::EXECUTION_MANAGEMENT_EVENTS_BALANCE_UPDATE);
std::vector<Element> elementList;
for (const auto& x : data["B"].GetArray()) {
Element element;
element.insert(CCAPI_EM_ASSET, x["a"].GetString());
element.insert(CCAPI_EM_QUANTITY_TOTAL, x["wb"].GetString());
elementList.emplace_back(std::move(element));
}
message.setElementList(elementList);
messageList.emplace_back(std::move(message));
}
if (fieldSet.find(CCAPI_EM_POSITION_UPDATE) != fieldSet.end() && !data["P"].Empty()) {
Message message;
message.setTimeReceived(timeReceived);
message.setCorrelationIdList({subscription.getCorrelationId()});
message.setTime(TimePoint(std::chrono::milliseconds(std::stoll((this->isDerivatives ? document : data)["E"].GetString()))));
message.setType(Message::Type::EXECUTION_MANAGEMENT_EVENTS_POSITION_UPDATE);
std::vector<Element> elementList;
for (const auto& x : data["P"].GetArray()) {
Element element;
element.insert(CCAPI_INSTRUMENT, x["s"].GetString());
element.insert(CCAPI_EM_POSITION_SIDE, x["ps"].GetString());
element.insert(CCAPI_EM_POSITION_QUANTITY, x["pa"].GetString());
element.insert(CCAPI_EM_POSITION_ENTRY_PRICE, x["ep"].GetString());
element.insert(CCAPI_EM_UNREALIZED_PNL, x["up"].GetString());
elementList.emplace_back(std::move(element));
}
message.setElementList(elementList);
messageList.emplace_back(std::move(message));
}
}
event.setMessageList(messageList);
return event;
Expand Down
144 changes: 121 additions & 23 deletions test/test_unit/src/execution_management/binance_usds_futures/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, convertTextMessageToMes
EXPECT_EQ(elementList.size(), 1);
Element element = elementList.at(0);
EXPECT_EQ(element.getValue(CCAPI_EM_ORDER_CUMULATIVE_FILLED_PRICE_TIMES_QUANTITY), "0.01");
EXPECT_EQ(element.getValue(CCAPI_LAST_UPDATED_TIME_SECONDS), "1579276756.075");
}

TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, createEventExecutionTypeTrade) {
Expand Down Expand Up @@ -141,6 +140,110 @@ TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, createEventExecutionTyp
EXPECT_EQ(element.getValue(CCAPI_EM_ORDER_FEE_ASSET), "USDT");
}

TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, createEventBalanceUpdate) {
Subscription subscription(CCAPI_EXCHANGE_NAME_BINANCE_USDS_FUTURES, "BTCUSDT", CCAPI_EM_BALANCE_UPDATE);
std::string textMessage = R"(
{
"e": "ACCOUNT_UPDATE",
"E": 1564745798939,
"T": 1564745798938,
"a": {
"m": "ORDER",
"B": [
{
"a": "USDT",
"wb": "122624.12345678",
"cw": "100.12345678",
"bc": "50.12345678"
},
{
"a": "BUSD",
"wb": "1.00000000",
"cw": "0.00000000",
"bc": "-49.12345678"
}
]
}
}
)";
rj::Document document;
document.Parse<rj::kParseNumbersAsStringsFlag>(textMessage.c_str());
auto messageList = this->service->createEvent(std::shared_ptr<WsConnection>(), subscription, textMessage, document, this->now).getMessageList();
EXPECT_EQ(messageList.size(), 1);
verifyCorrelationId(messageList, subscription.getCorrelationId());
auto message = messageList.at(0);
EXPECT_EQ(message.getType(), Message::Type::EXECUTION_MANAGEMENT_EVENTS_BALANCE_UPDATE);
auto elementList = message.getElementList();
EXPECT_EQ(elementList.size(), 2);
Element element = elementList.at(0);
EXPECT_EQ(element.getValue(CCAPI_EM_ASSET), "USDT");
EXPECT_EQ(element.getValue(CCAPI_EM_QUANTITY_TOTAL), "122624.12345678");
}

TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, createEventPositionUpdate) {
Subscription subscription(CCAPI_EXCHANGE_NAME_BINANCE_USDS_FUTURES, "BTCUSDT", CCAPI_EM_POSITION_UPDATE);
std::string textMessage = R"(
{
"e": "ACCOUNT_UPDATE",
"E": 1564745798939,
"T": 1564745798938,
"a": {
"m": "ORDER",
"P": [
{
"s": "BTCUSDT",
"pa": "0",
"ep": "0.00000",
"bep": "0",
"cr": "200",
"up": "0",
"mt": "isolated",
"iw": "0.00000000",
"ps": "BOTH"
},
{
"s": "BTCUSDT",
"pa": "20",
"ep": "6563.66500",
"bep": "6563.6",
"cr": "0",
"up": "2850.21200",
"mt": "isolated",
"iw": "13200.70726908",
"ps": "LONG"
},
{
"s": "BTCUSDT",
"pa": "-10",
"ep": "6563.86000",
"bep": "6563.6",
"cr": "-45.04000000",
"up": "-1423.15600",
"mt": "isolated",
"iw": "6570.42511771",
"ps": "SHORT"
}
]
}
}
)";
rj::Document document;
document.Parse<rj::kParseNumbersAsStringsFlag>(textMessage.c_str());
auto messageList = this->service->createEvent(std::shared_ptr<WsConnection>(), subscription, textMessage, document, this->now).getMessageList();
EXPECT_EQ(messageList.size(), 1);
verifyCorrelationId(messageList, subscription.getCorrelationId());
auto message = messageList.at(0);
EXPECT_EQ(message.getType(), Message::Type::EXECUTION_MANAGEMENT_EVENTS_POSITION_UPDATE);
auto elementList = message.getElementList();
EXPECT_EQ(elementList.size(), 3);
Element element = elementList.at(0);
EXPECT_EQ(element.getValue(CCAPI_INSTRUMENT), "BTCUSDT");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_SIDE), "BOTH");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_QUANTITY), "0");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_ENTRY_PRICE), "0.00000");
EXPECT_EQ(element.getValue(CCAPI_EM_UNREALIZED_PNL), "0");
}

TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, createEventExecutionTypeNew) {
Subscription subscription(CCAPI_EXCHANGE_NAME_BINANCE_USDS_FUTURES, "BTCUSDT", CCAPI_EM_ORDER_UPDATE);
std::string textMessage = R"(
Expand Down Expand Up @@ -301,7 +404,6 @@ TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, convertTextMessageToMes
Element element = elementList.at(0);
EXPECT_EQ(element.getValue(CCAPI_EM_ASSET), "USDT");
EXPECT_EQ(element.getValue(CCAPI_EM_QUANTITY_AVAILABLE_FOR_TRADING), "23.72469206");
EXPECT_EQ(element.getValue(CCAPI_LAST_UPDATED_TIME_SECONDS), "1625474304.765");
}

TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, convertRequestGetAccountPositions) {
Expand All @@ -321,24 +423,21 @@ TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, convertTextMessageToMes
std::string textMessage =
R"(
[
{
"entryPrice": "0.00000",
"breakEvenPrice": "0.0",
"marginType": "isolated",
"isAutoAddMargin": "false",
"isolatedMargin": "0.00000000",
"leverage": "10",
"liquidationPrice": "0",
"markPrice": "6679.50671178",
"maxNotionalValue": "20000000",
"positionAmt": "0.000",
"notional": "0",
"isolatedWallet": "0",
"symbol": "BTCUSDT",
"unrealizedProfit": "0.00000000",
"positionSide": "BOTH",
"updateTime": 0
}
{
"symbol": "BTCUSDT",
"initialMargin": "0",
"maintMargin": "0",
"unrealizedProfit": "0.00000000",
"positionInitialMargin": "0",
"openOrderInitialMargin": "0",
"leverage": "100",
"isolated": true,
"entryPrice": "0.00000",
"maxNotional": "250000",
"positionSide": "BOTH",
"positionAmt": "0",
"updateTime": 0
}
]
)";
auto messageList = this->service->convertTextMessageToMessageRest(request, textMessage, this->now);
Expand All @@ -351,10 +450,9 @@ TEST_F(ExecutionManagementServiceBinanceUsdsFuturesTest, convertTextMessageToMes
Element element = elementList.at(0);
EXPECT_EQ(element.getValue(CCAPI_INSTRUMENT), "BTCUSDT");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_SIDE), "BOTH");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_QUANTITY), "0.000");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_QUANTITY), "0");
EXPECT_DOUBLE_EQ(std::stod(element.getValue(CCAPI_EM_POSITION_ENTRY_PRICE)), 0);
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_LEVERAGE), "10");
EXPECT_EQ(element.getValue(CCAPI_LAST_UPDATED_TIME_SECONDS), "0");
EXPECT_EQ(element.getValue(CCAPI_EM_POSITION_LEVERAGE), "100");
}
} /* namespace ccapi */
#endif
Expand Down

0 comments on commit c96709e

Please sign in to comment.