970 lines
50 KiB
C++
970 lines
50 KiB
C++
#include "lib/api/services/AdminService.server.pb.h"
|
|
#include "lib/api/service_helpers/AdminServiceUtils.h"
|
|
|
|
namespace bts{
|
|
namespace admin{
|
|
////////////////////////////////////////////
|
|
// connection accessors ////////////////////
|
|
////////////////////////////////////////////
|
|
uint32_t AdminServiceUtils::find_max_connection_id (const bts::api::admin::AdminData& data){
|
|
uint32_t rv = 0;
|
|
for(const auto &conn : data.connections())
|
|
if (conn.id() > rv)
|
|
rv = conn.id();
|
|
return rv;
|
|
}
|
|
const bts::api::admin::ExchangeConnection* AdminServiceUtils::find_connection(const bts::api::admin::AdminData& data,
|
|
const std::string& connection_name){
|
|
for(const auto& connection : data.connections())
|
|
if(connection.name()==connection_name)
|
|
return &connection;
|
|
return nullptr;
|
|
}
|
|
bool AdminServiceUtils::has_exchange(const bts::api::admin::ExchangeConnection& conn,
|
|
bts::api::Venue exchange){
|
|
bool rv = false;
|
|
switch(exchange)
|
|
{
|
|
case api::Venue::VENUE_GLBX:
|
|
rv = conn.has_cme_connection() &&
|
|
(conn.cme_connection().has_cgw_connection() || conn.cme_connection().has_msgw_connection());
|
|
break;
|
|
case api::Venue::VENUE_UNSET:
|
|
case api::Venue::VENUE_BTS:
|
|
case api::Venue::VENUE_CBOE:
|
|
case api::Venue::VENUE_CBOECFE:
|
|
case api::Venue::VENUE_ICE:
|
|
case api::Venue::Venue_INT_MIN_SENTINEL_DO_NOT_USE_:
|
|
case api::Venue::Venue_INT_MAX_SENTINEL_DO_NOT_USE_:
|
|
rv = false;
|
|
break;
|
|
}
|
|
return rv;
|
|
}
|
|
const bts::api::admin::ExchangeConnection* AdminServiceUtils::find_default_account_connection(const bts::api::admin::AdminData& data,
|
|
const bts::api::admin::BTSAccount& account,
|
|
bts::api::Venue exchange){
|
|
//todo:get from parent accounts if not overridden
|
|
if(account.has_connections())
|
|
for (const std::string& conn_name : account.connections().exchange_connection_names()){
|
|
const bts::api::admin::ExchangeConnection* conn = find_connection(data, conn_name);
|
|
if (conn!=nullptr && has_exchange(*conn, exchange))
|
|
return conn;
|
|
}
|
|
return nullptr;
|
|
}
|
|
////////////////////////////////////////////
|
|
// connection mutators /////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::ExchangeConnection* AdminServiceUtils::add_connection (bts::api::admin::AdminData& data,
|
|
const bts::api::admin::ExchangeConnection& new_connection){
|
|
auto new_connection_ptr = data.add_connections();
|
|
new_connection_ptr->CopyFrom(new_connection);
|
|
return new_connection_ptr;
|
|
}
|
|
void AdminServiceUtils::fill_connections_from_config(bts::api::admin::AdminData& admin_data){
|
|
admin_data.clear_connections();
|
|
auto &all_connections = config::get<config::JetFIX>().connection();
|
|
for (auto const &c : all_connections){
|
|
// TODO:(assumes all exchanges are CME)
|
|
bts::api::admin::ExchangeConnection connection;
|
|
uint32_t new_id = find_max_connection_id(admin_data)+1;
|
|
connection.set_id(new_id);
|
|
connection.set_name(c.name());
|
|
connection.mutable_cme_connection()->mutable_msgw_connection();
|
|
add_connection(admin_data,connection);
|
|
}
|
|
for(int i=0;i<admin_data.accounts_size();i++)
|
|
sync_account_connections(admin_data, *admin_data.mutable_accounts(i));
|
|
}
|
|
////////////////////////////////////////////
|
|
// account accessors ///////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::BTSAccount* AdminServiceUtils::find_account (bts::api::admin::AdminData& data,
|
|
const std::string& name,
|
|
bool include_deleted){
|
|
auto account_ptrs = accounts_mutable(data, include_deleted);
|
|
for (auto account_ptr : account_ptrs)
|
|
if(name==account_ptr->name())
|
|
return account_ptr;
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::BTSAccount* AdminServiceUtils::find_account (const bts::api::admin::AdminData& data,
|
|
const std::string& name,
|
|
bool include_deleted){
|
|
auto account_ptrs = accounts(data, include_deleted);
|
|
for (auto account_ptr : account_ptrs)
|
|
if(name==account_ptr->name())
|
|
return account_ptr;
|
|
return nullptr;
|
|
}
|
|
bts::api::admin::BTSAccount* AdminServiceUtils::find_account (bts::api::admin::AdminData& data,
|
|
uint32_t id,
|
|
bool include_deleted){
|
|
auto account_ptrs = accounts_mutable(data, include_deleted);
|
|
for (auto account_ptr : account_ptrs)
|
|
if(id==account_ptr->id())
|
|
return account_ptr;
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::BTSAccount* AdminServiceUtils::find_account (const bts::api::admin::AdminData& data,
|
|
uint32_t id,
|
|
bool include_deleted){
|
|
auto account_ptrs = accounts(data, include_deleted);
|
|
for (auto account_ptr : account_ptrs)
|
|
if(id==account_ptr->id())
|
|
return account_ptr;
|
|
return nullptr;
|
|
}
|
|
std::vector<const bts::api::admin::BTSAccount*> AdminServiceUtils::accounts (const bts::api::admin::AdminData& data,
|
|
bool include_deleted){
|
|
std::vector<const bts::api::admin::BTSAccount*> rv;
|
|
for (const auto& account : data.accounts())
|
|
if (account.is_present() || include_deleted)
|
|
rv.push_back(&account);
|
|
return rv;
|
|
}
|
|
std::vector<bts::api::admin::BTSAccount*> AdminServiceUtils::accounts_mutable (bts::api::admin::AdminData& data,
|
|
bool include_deleted){
|
|
std::vector<bts::api::admin::BTSAccount*> rv;
|
|
for(int i=0; i<data.accounts_size(); i++){
|
|
bts::api::admin::BTSAccount* account_ptr = data.mutable_accounts(i);
|
|
if (account_ptr->is_present() || include_deleted)
|
|
rv.push_back(account_ptr);
|
|
}
|
|
return rv;
|
|
}
|
|
uint32_t AdminServiceUtils::find_max_acct_id (const bts::api::admin::AdminData& data){
|
|
uint32_t rv = 0;
|
|
for(const auto &acct : data.accounts())
|
|
if (acct.id() > rv)
|
|
rv = acct.id();
|
|
return rv;
|
|
}
|
|
const bts::api::admin::CMEAccountData* AdminServiceUtils::get_account_cme_data(const bts::api::admin::BTSAccount& account,
|
|
const bts::api::admin::AdminData& data){
|
|
if (account.has_exchange_account_data() && account.exchange_account_data().has_cme_account_data())
|
|
return &(account.exchange_account_data().cme_account_data());
|
|
else if (has_id(account.parent_account_id())){
|
|
const bts::api::admin::BTSAccount* parent_account = find_account(data, account.parent_account_id());
|
|
if (parent_account != nullptr)
|
|
return get_account_cme_data (*parent_account, data);
|
|
}
|
|
return nullptr;
|
|
}
|
|
bool AdminServiceUtils::account_has_connection(const bts::api::admin::BTSAccount& account,
|
|
const std::string& connection_name){
|
|
if(account.has_connections()){
|
|
for(int i=0; i<account.connections().exchange_connection_names_size();i++)
|
|
if(connection_name == account.connections().exchange_connection_names(i))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
std::string AdminServiceUtils::find_account_exchange_account (const bts::api::admin::AdminData& data,
|
|
const bts::api::admin::BTSAccount& account,
|
|
api::Venue exchange,
|
|
bts::api::admin::AdminServiceOperationResult& out_result){
|
|
out_result.set_is_success(true);
|
|
const api::admin::CMEAccountData* cme_account_data;
|
|
std::string rv = "";
|
|
switch(exchange)
|
|
{
|
|
case api::Venue::VENUE_GLBX:
|
|
cme_account_data = get_account_cme_data(account, data);
|
|
if (cme_account_data != nullptr)
|
|
rv = cme_account_data->clearing_account();
|
|
break;
|
|
case api::Venue::VENUE_UNSET:
|
|
case api::Venue::VENUE_BTS:
|
|
case api::Venue::VENUE_CBOE:
|
|
case api::Venue::VENUE_CBOECFE:
|
|
case api::Venue::VENUE_ICE:
|
|
case api::Venue::Venue_INT_MIN_SENTINEL_DO_NOT_USE_:
|
|
case api::Venue::Venue_INT_MAX_SENTINEL_DO_NOT_USE_:
|
|
out_result.set_is_success(false); out_result.set_error_text("Exchange not supported");
|
|
break;
|
|
}
|
|
return rv;
|
|
}
|
|
std::map<uint32_t,bool> AdminServiceUtils::accounts_map(const bts::api::admin::AdminData& admin_data){
|
|
std::map<uint32_t,bool> rv;
|
|
auto account_ptrs = accounts(admin_data, false);
|
|
for(const bts::api::admin::BTSAccount* account_ptr : account_ptrs)
|
|
rv.insert(std::pair<uint32_t,bool>(account_ptr->id(),account_ptr->is_active()));
|
|
return rv;
|
|
}
|
|
void AdminServiceUtils::validate_account_update (const bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::BTSAccount& updated_account,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
// validate id
|
|
if(find_account(admin_data, updated_account.id()) == nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Could not find account id");
|
|
return;
|
|
}
|
|
// validate that name change doesnt collide
|
|
auto account_ptrs = accounts(admin_data, false);
|
|
for (const bts::api::admin::BTSAccount* account_ptr : account_ptrs)
|
|
if (account_ptr->id() != updated_account.id() && account_ptr->name() == updated_account.name()){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Account by this name already exists");
|
|
return;
|
|
}
|
|
// validate account exchange changes
|
|
validate_account_exchange_data (updated_account, result);
|
|
}
|
|
void AdminServiceUtils::validate_account_exchange_data (const bts::api::admin::BTSAccount& account,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
if (account.has_exchange_account_data()){
|
|
if (account.exchange_account_data().has_cme_account_data()){
|
|
const bts::api::admin::CMEAccountData& cme_account_data = account.exchange_account_data().cme_account_data();
|
|
if (cme_account_data.clearing_account().size() > 12){
|
|
result.set_is_success(false);
|
|
result.set_error_text("CME account can not be more 12 characters long");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bts::api::orderman::RoutingRecord AdminServiceUtils::get_routing_record(const bts::api::admin::AdminData& data,
|
|
const std::string& account_name,
|
|
const std::string& user_name,
|
|
const bts::api::Security& sec,
|
|
bts::api::admin::AdminServiceOperationResult& out_result){
|
|
bts::api::orderman::RoutingRecord rv;
|
|
const bts::api::admin::BTSAccount* account_ptr = find_account(data, account_name);
|
|
if (account_ptr == nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find account");
|
|
return rv;
|
|
}
|
|
const bts::api::admin::BTSUser* user_ptr = find_user(data, user_name);
|
|
if (user_ptr == nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find user");
|
|
return rv;
|
|
}
|
|
return get_routing_record(data, account_ptr->id(), user_ptr->id(), sec, out_result);
|
|
}
|
|
bts::api::orderman::RoutingRecord AdminServiceUtils::get_routing_record(const bts::api::admin::AdminData& data,
|
|
uint32_t account_id,
|
|
uint32_t user_id,
|
|
const bts::api::Security& sec,
|
|
bts::api::admin::AdminServiceOperationResult& out_result){
|
|
bts::api::orderman::RoutingRecord rv;
|
|
out_result.set_is_success(true);
|
|
const bts::api::admin::BTSAccount* account_ptr = find_account(data,account_id);
|
|
if (account_ptr == nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find account");
|
|
return rv;
|
|
}
|
|
const bts::api::admin::BTSUser* user_ptr = find_user(data, user_id);
|
|
if (user_ptr == nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find user");
|
|
return rv;
|
|
}
|
|
const bts::api::admin::ExchangeConnection* conn_ptr = find_default_account_connection(data, *account_ptr, sec.exchange());
|
|
if(conn_ptr == nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find connection");
|
|
return rv;
|
|
}
|
|
if(sec.exchange()==bts::api::Venue::VENUE_GLBX){
|
|
const bts::api::admin::CMEUserData* cme_user_data = get_user_cme_data(*user_ptr, data);
|
|
if(cme_user_data==nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find CME data for user");//CME or globex ?
|
|
return rv;
|
|
}
|
|
const bts::api::admin::CMEAccountData* cme_account_data = get_account_cme_data(*account_ptr, data);
|
|
if(cme_account_data==nullptr){
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Could not find CME data for account");
|
|
return rv;
|
|
}
|
|
rv.set_session(conn_ptr->name());
|
|
rv.set_operator_id(cme_user_data->operator_id());
|
|
rv.set_account(cme_account_data->clearing_account());
|
|
rv.set_cti_code(cme_account_data->cti());
|
|
rv.set_customer_or_firm(cme_account_data->origin());
|
|
return rv;
|
|
}
|
|
else{
|
|
out_result.set_is_success(false);
|
|
out_result.set_error_text("Only contracts at the CME are supported right now");
|
|
return rv;
|
|
}
|
|
}
|
|
////////////////////////////////////////////
|
|
// account mutators ////////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::BTSAccount* AdminServiceUtils::create_account(bts::api::admin::AdminData& data,
|
|
uint32_t parent_account_id,
|
|
const std::string& account_name,
|
|
const std::string& description,
|
|
bool is_active,
|
|
bts::api::admin::AdminServiceCreateAccountResult& result){
|
|
result.set_is_success(true);
|
|
// the error conditions are checked first and returned immediatly
|
|
// i. account with the name already exists
|
|
// ii. parent account is set and does not exist
|
|
if (find_account(data, account_name, true) != nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Account by this name already exists");
|
|
return nullptr;
|
|
}
|
|
if (has_id(parent_account_id)){
|
|
if (find_account(data, parent_account_id) == nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Parent group does not exist");
|
|
return nullptr;
|
|
}
|
|
}
|
|
uint32_t new_id = find_max_acct_id(data)+1;
|
|
result.set_new_id(new_id);
|
|
bts::api::admin::BTSAccount* new_account_ptr = data.add_accounts();
|
|
new_account_ptr->set_is_present(true);
|
|
new_account_ptr->set_id(new_id);
|
|
new_account_ptr->set_parent_account_id(parent_account_id);
|
|
new_account_ptr->set_name(account_name);
|
|
new_account_ptr->set_description(description);
|
|
new_account_ptr->set_is_active(is_active);
|
|
return new_account_ptr;
|
|
}
|
|
void AdminServiceUtils::update_account(bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::BTSAccount& updated_account,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
validate_account_update (admin_data, updated_account, result);
|
|
if (result.is_success()){
|
|
bts::api::admin::BTSAccount* account_ptr = find_account(admin_data, updated_account.id());
|
|
account_ptr->CopyFrom(updated_account);
|
|
}
|
|
}
|
|
void AdminServiceUtils::delete_account (bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::IDAPIArgument& id,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
api::admin::BTSAccount* account_ptr = AdminServiceUtils::find_account(admin_data, id.id());
|
|
if (account_ptr != nullptr)
|
|
{
|
|
std::string deleted_name;
|
|
int deleted_idx = 0;
|
|
do{
|
|
deleted_idx++;
|
|
deleted_name = deleted_idx == 1 ? fmt::format("DELETED_{}", account_ptr->name()) :
|
|
fmt::format("DELETED_{}_{}", deleted_idx, account_ptr->name());
|
|
}
|
|
while(AdminServiceUtils::find_account(admin_data, deleted_name, true) != nullptr);
|
|
account_ptr->set_is_present(false);
|
|
account_ptr->set_name(deleted_name);
|
|
}
|
|
else{
|
|
result.set_is_success(false);
|
|
result.set_error_text("Could not find account");
|
|
}
|
|
}
|
|
void AdminServiceUtils::set_account_exchange_data(bts::api::admin::BTSAccount* account,
|
|
const bts::api::admin::ExchangeAccountData& exchange_data){
|
|
account->mutable_exchange_account_data()->CopyFrom(exchange_data);
|
|
}
|
|
void AdminServiceUtils::sync_account_connections(const bts::api::admin::AdminData& data,
|
|
bts::api::admin::BTSAccount& account){
|
|
if(account.has_connections()){
|
|
std::map<std::string, bool> all_conn_names;
|
|
for(int i=0; i< data.connections_size(); i++)
|
|
all_conn_names[data.connections(i).name()]=true;
|
|
std::vector<std::string> cleaned_connections;
|
|
for(int i=0; i<account.connections().exchange_connection_names_size();i++){
|
|
const std::string& conn_name=account.connections().exchange_connection_names(i);
|
|
if(all_conn_names.find(conn_name)!=all_conn_names.end())
|
|
cleaned_connections.push_back(conn_name);
|
|
}
|
|
account.mutable_connections()->mutable_exchange_connection_names()->Clear();
|
|
for(auto it=cleaned_connections.begin(); it!= cleaned_connections.end(); it++)
|
|
account.mutable_connections()->add_exchange_connection_names(*it);
|
|
}
|
|
}
|
|
////////////////////////////////////////////
|
|
// group accessors /////////////////////////
|
|
////////////////////////////////////////////
|
|
|
|
bts::api::admin::BTSUserGroup* AdminServiceUtils::find_group (bts::api::admin::AdminData& data,
|
|
uint32_t id){
|
|
for(int i=0; i<data.user_groups_size();i++){
|
|
bts::api::admin::BTSUserGroup* group = data.mutable_user_groups(i);
|
|
if(id == group->id())
|
|
return group;
|
|
}
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::BTSUserGroup* const AdminServiceUtils::find_group (const bts::api::admin::AdminData& data,
|
|
uint32_t id){
|
|
for(const bts::api::admin::BTSUserGroup& group : data.user_groups())
|
|
if(id == group.id())
|
|
return &group;
|
|
return nullptr;
|
|
}
|
|
bts::api::admin::BTSUserGroup* AdminServiceUtils::find_group (bts::api::admin::AdminData& data,
|
|
const std::string& group_name){
|
|
for(int i=0; i<data.user_groups_size();i++){
|
|
bts::api::admin::BTSUserGroup* group = data.mutable_user_groups(i);
|
|
if(group_name == group->name())
|
|
return group;
|
|
}
|
|
return nullptr;
|
|
}
|
|
uint32_t AdminServiceUtils::find_max_group_id (const bts::api::admin::AdminData& data){
|
|
uint32_t rv = 0;
|
|
for(const bts::api::admin::BTSUserGroup& group : data.user_groups())
|
|
if (group.id() > rv)
|
|
rv = group.id();
|
|
return rv;
|
|
}
|
|
const bts::api::admin::CMEUserData* AdminServiceUtils::get_group_cme_data(const bts::api::admin::BTSUserGroup& group,
|
|
const bts::api::admin::AdminData& data){
|
|
if (group.has_user_data() && group.user_data().has_exchange_user_data() && group.user_data().exchange_user_data().has_cme_data())
|
|
return &(group.user_data().exchange_user_data().cme_data());
|
|
else if (has_id(group.parent_group_id())){
|
|
const bts::api::admin::BTSUserGroup* parent_group = find_group(data, group.parent_group_id());
|
|
if (parent_group != nullptr)
|
|
return get_group_cme_data(*parent_group, data);
|
|
}
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::UserAccountPermissions* const AdminServiceUtils::get_group_user_permissions (const bts::api::admin::AdminData& admin_data,
|
|
uint32_t group_id){
|
|
const bts::api::admin::BTSUserGroup* const group = find_group(admin_data, group_id);
|
|
if(group != nullptr){
|
|
if (group->has_user_data() && group->user_data().has_account_permissions())
|
|
return &group->user_data().account_permissions();
|
|
if (has_id(group->parent_group_id()))
|
|
return get_group_user_permissions(admin_data, group->parent_group_id());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
////////////////////////////////////////////
|
|
// group mutators //////////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::BTSUserGroup* AdminServiceUtils::create_group(bts::api::admin::AdminData& data,
|
|
uint32_t parent_group_id,
|
|
const std::string& group_name,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
// the error conditions are checked first and returned immediatly
|
|
// i. account with the name already exists
|
|
// ii. parent account is set and does not exist
|
|
result.set_is_success(true);
|
|
if (find_group (data, group_name) != nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Group by this name already exists");
|
|
return nullptr;
|
|
}
|
|
if (has_id(parent_group_id)){
|
|
if(find_group(data, parent_group_id) == nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Parent group does not exist");
|
|
return nullptr;
|
|
}
|
|
}
|
|
uint32_t new_id = find_max_group_id(data)+1;
|
|
bts::api::admin::BTSUserGroup* new_group_ptr = data.add_user_groups();
|
|
new_group_ptr->set_id(new_id);
|
|
new_group_ptr->set_parent_group_id(parent_group_id);
|
|
new_group_ptr->set_name(group_name);
|
|
return new_group_ptr;
|
|
}
|
|
////////////////////////////////////////////
|
|
// user accessors //////////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::BTSUser* AdminServiceUtils::find_user (bts::api::admin::AdminData& data, const std::string& user_name,
|
|
bool include_deleted){
|
|
auto user_ptrs = users_mutable(data,include_deleted);
|
|
for(auto user_ptr : user_ptrs){
|
|
if(user_name==user_ptr->name())
|
|
return user_ptr;
|
|
}
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::BTSUser* AdminServiceUtils::find_user (const bts::api::admin::AdminData& data, const std::string& user_name,
|
|
bool include_deleted){
|
|
auto user_ptrs = users(data,include_deleted);
|
|
for (auto user_ptr : user_ptrs)
|
|
if(user_name==user_ptr->name())
|
|
return user_ptr;
|
|
return nullptr;
|
|
}
|
|
bts::api::admin::BTSUser* AdminServiceUtils::find_user (bts::api::admin::AdminData& data, uint32_t id,
|
|
bool include_deleted){
|
|
auto user_ptrs = users_mutable(data,include_deleted);
|
|
for(auto user_ptr : user_ptrs){
|
|
if(id==user_ptr->id())
|
|
return user_ptr;
|
|
}
|
|
return nullptr;
|
|
}
|
|
const bts::api::admin::BTSUser* const AdminServiceUtils::find_user (const bts::api::admin::AdminData& data,uint32_t id,
|
|
bool include_deleted){
|
|
auto user_ptrs = users(data,include_deleted);
|
|
for (auto user_ptr : user_ptrs)
|
|
if(id==user_ptr->id())
|
|
return user_ptr;
|
|
return nullptr;
|
|
}
|
|
std::vector<const bts::api::admin::BTSUser*> AdminServiceUtils::users (const bts::api::admin::AdminData& data,
|
|
bool include_deleted){
|
|
std::vector<const bts::api::admin::BTSUser*> rv;
|
|
for (const bts::api::admin::BTSUser& user : data.users())
|
|
if (user.is_present() || include_deleted)
|
|
rv.push_back(&user);
|
|
return rv;
|
|
}
|
|
std::vector<bts::api::admin::BTSUser*> AdminServiceUtils::users_mutable (bts::api::admin::AdminData& data,
|
|
bool include_deleted){
|
|
std::vector<bts::api::admin::BTSUser*> rv;
|
|
for(int i=0; i<data.users_size(); i++){
|
|
auto user_ptr = data.mutable_users(i);
|
|
if (user_ptr->is_present() || include_deleted)
|
|
rv.push_back(user_ptr);
|
|
}
|
|
return rv;
|
|
}
|
|
uint32_t AdminServiceUtils::find_max_user_id (const bts::api::admin::AdminData& data){
|
|
uint32_t rv = 0;
|
|
auto user_ptrs = users(data,true);
|
|
for(auto user_ptr : user_ptrs)
|
|
if (user_ptr->id() > rv)
|
|
rv = user_ptr->id();
|
|
return rv;
|
|
}
|
|
const bts::api::admin::CMEUserData* AdminServiceUtils::get_user_cme_data(const bts::api::admin::BTSUser& user,
|
|
const bts::api::admin::AdminData& data){
|
|
if (user.has_user_data() && user.user_data().has_exchange_user_data() && user.user_data().exchange_user_data().has_cme_data())
|
|
return &(user.user_data().exchange_user_data().cme_data());
|
|
else{
|
|
const bts::api::admin::BTSUserGroup* parent_group = find_group(data, user.parent_group_id());
|
|
if (parent_group != nullptr)
|
|
return get_group_cme_data(*parent_group, data);
|
|
}
|
|
return nullptr;
|
|
}
|
|
// finds the "exchange user" (ex: "operator_id" at CME or "authorized_trader"
|
|
// at ICE) for a user
|
|
std::string AdminServiceUtils::find_user_exchange_id (const bts::api::admin::AdminData& data,
|
|
const bts::api::admin::BTSUser& user,
|
|
api::Venue exchange,
|
|
bts::api::admin::AdminServiceOperationResult& out_result){
|
|
const api::admin::CMEUserData* cme_user_data;
|
|
out_result.set_is_success(true);
|
|
std::string rv = "";
|
|
switch(exchange)
|
|
{
|
|
case api::Venue::VENUE_GLBX:
|
|
cme_user_data = get_user_cme_data(user, data);
|
|
if (cme_user_data != nullptr)
|
|
rv = cme_user_data->operator_id();
|
|
break;
|
|
case api::Venue::VENUE_UNSET:
|
|
case api::Venue::VENUE_BTS:
|
|
case api::Venue::VENUE_CBOE:
|
|
case api::Venue::VENUE_CBOECFE:
|
|
case api::Venue::VENUE_ICE:
|
|
case api::Venue::Venue_INT_MIN_SENTINEL_DO_NOT_USE_:
|
|
case api::Venue::Venue_INT_MAX_SENTINEL_DO_NOT_USE_:
|
|
out_result.set_is_success(false); out_result.set_error_text("Exchange not supported");
|
|
break;
|
|
}
|
|
return rv;
|
|
}
|
|
std::pair<const bts::api::admin::BTSAccount*, const bts::api::admin::BTSUser*>
|
|
AdminServiceUtils::find_user_account_matches (const bts::api::admin::AdminData& admin_data,
|
|
const std::string& connection, const std::string& exchange_account,
|
|
const std::string& exchange_user,
|
|
api::Venue exchange){
|
|
bts::api::admin::AdminServiceOperationResult find_account_result, find_user_result;
|
|
auto account_ptrs = accounts(admin_data, false);
|
|
auto user_ptrs = users(admin_data, false);
|
|
for(const bts::api::admin::BTSAccount* account_ptr : account_ptrs){
|
|
if (account_has_connection(*account_ptr, connection)){
|
|
if (exchange_account == find_account_exchange_account(admin_data,*account_ptr,exchange,find_account_result) && find_account_result.is_success()){
|
|
for(const bts::api::admin::BTSUser* user_ptr : user_ptrs){
|
|
if (exchange_user == find_user_exchange_id(admin_data,*user_ptr,exchange,find_user_result) && find_user_result.is_success())
|
|
return std::pair<const bts::api::admin::BTSAccount*, const bts::api::admin::BTSUser*>(account_ptr,user_ptr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return std::pair<const bts::api::admin::BTSAccount*, const bts::api::admin::BTSUser*>(nullptr, nullptr);
|
|
}
|
|
// for a given user finds the account permissions (if permissions are
|
|
// derived from the group, it traverses the group hierarcy to find the
|
|
// correct permissions.
|
|
const bts::api::admin::UserAccountPermissions* AdminServiceUtils::get_user_permissions (const bts::api::admin::AdminData& admin_data,
|
|
uint32_t user_id){
|
|
const bts::api::admin::BTSUser* const user = find_user(admin_data, user_id);
|
|
if(user != nullptr){
|
|
if (user->has_user_data() && user->user_data().has_account_permissions())
|
|
return &user->user_data().account_permissions();
|
|
else
|
|
return get_group_user_permissions(admin_data, user->parent_group_id());
|
|
}
|
|
return nullptr;
|
|
}
|
|
// for a given user, fills in the associated_accounts ref arg
|
|
// with the accounts the user has permission to trade in
|
|
void AdminServiceUtils::find_user_trading_accounts (const bts::api::admin::AdminData& admin_data,
|
|
uint32_t user_id,
|
|
std::vector<const api::admin::BTSAccount*>& associated_accounts){
|
|
const bts::api::admin::UserAccountPermissions* user_perm_ptr = get_user_permissions (admin_data, user_id);
|
|
if (user_perm_ptr != nullptr)
|
|
for(auto it=user_perm_ptr->account_permissions().begin(); it!=user_perm_ptr->account_permissions().end(); it++)
|
|
if (it->second.has_trading_permission()){
|
|
const api::admin::BTSAccount* account_ptr = find_account(admin_data, it->first);
|
|
if (account_ptr != nullptr)
|
|
associated_accounts.push_back(account_ptr);
|
|
}
|
|
}
|
|
void AdminServiceUtils::validate_user_update (const bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::BTSUser& updated_user,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
// validate id
|
|
if(find_user(admin_data, updated_user.id()) == nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Could not find user id");
|
|
return;
|
|
}
|
|
// validate that name change doesnt collide
|
|
auto user_ptrs = users(admin_data,true);
|
|
for (auto user_ptr : user_ptrs)
|
|
if (user_ptr->id() != updated_user.id() && user_ptr->name() == updated_user.name()){
|
|
result.set_is_success(false);
|
|
result.set_error_text("User by this name already exists");
|
|
return;
|
|
}
|
|
validate_user_exchange_data (updated_user, result);
|
|
}
|
|
void AdminServiceUtils::validate_user_exchange_data (const bts::api::admin::BTSUser& user,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
// this is not right (should navigate to the group)
|
|
if (user.has_user_data() && user.user_data().has_exchange_user_data() && user.user_data().exchange_user_data().has_cme_data()){
|
|
const api::admin::CMEUserData& cme_user_data = user.user_data().exchange_user_data().cme_data();
|
|
if (cme_user_data.operator_id().size() > 18){
|
|
result.set_is_success(false);
|
|
result.set_error_text("CME operator id can not be more 12 characters long");
|
|
}
|
|
}
|
|
}
|
|
////////////////////////////////////////////
|
|
// user mutators ///////////////////////////
|
|
////////////////////////////////////////////
|
|
bts::api::admin::BTSUser* AdminServiceUtils::create_user (bts::api::admin::AdminData& data,
|
|
uint32_t parent_group_id,
|
|
const std::string& name,
|
|
const std::string& password,
|
|
bool is_active,
|
|
const bts::api::admin::LicenseData& license_data,
|
|
const bts::api::admin::LicenseEntitlements& license_entitlements,
|
|
bts::api::admin::AdminServiceCreateEntityResult& result){
|
|
result.set_is_success(true);
|
|
// the error conditions are checked first and returned immediatly
|
|
// i. user with the name already exists
|
|
// ii. parent group does not exist
|
|
if (find_user (data, name, true) != nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("User by this name already exists");
|
|
return nullptr;
|
|
}
|
|
if (find_group(data, parent_group_id) == nullptr){
|
|
result.set_is_success(false);
|
|
result.set_error_text("Parent group does not exist");
|
|
return nullptr;
|
|
}
|
|
uint32_t new_id = AdminServiceUtils::find_max_user_id(data)+1;
|
|
bts::api::admin::BTSUser* new_user_ptr = data.add_users();
|
|
new_user_ptr->set_is_present(true);
|
|
new_user_ptr->set_id(new_id);
|
|
new_user_ptr->set_parent_group_id(parent_group_id);
|
|
new_user_ptr->set_name(name);
|
|
new_user_ptr->set_password (password);
|
|
new_user_ptr->set_is_active(is_active);
|
|
new_user_ptr->mutable_license_data()->CopyFrom(license_data);
|
|
new_user_ptr->mutable_license_entitlements()->CopyFrom(license_entitlements);
|
|
result.set_new_id(new_id);
|
|
return new_user_ptr;
|
|
}
|
|
void AdminServiceUtils::set_user_exchange_data(bts::api::admin::BTSUser* user,
|
|
const bts::api::admin::ExchangeUserData& exchange_user_data){
|
|
if (!user->has_user_data())
|
|
user->mutable_user_data();
|
|
if (!user->user_data().has_exchange_user_data())
|
|
user->mutable_user_data()->mutable_exchange_user_data()->CopyFrom(exchange_user_data);
|
|
}
|
|
void AdminServiceUtils::set_user_md_entitlement_data(bts::api::admin::BTSUser* user,
|
|
const bts::api::admin::ExchangeUserMarketDataEntitlementData& exchange_user_md_entitelemnt_data){
|
|
if (!user->has_user_data())
|
|
user->mutable_user_data();
|
|
if (!user->user_data().has_exchange_md_entitlement_data())
|
|
user->mutable_user_data()->mutable_exchange_md_entitlement_data()->CopyFrom(exchange_user_md_entitelemnt_data);
|
|
}
|
|
void AdminServiceUtils::clear_user_accounts (bts::api::admin::BTSUser* user){
|
|
if(user->has_user_data() && user->user_data().has_account_permissions())
|
|
user->mutable_user_data()->clear_account_permissions();
|
|
}
|
|
void AdminServiceUtils::set_user_accounts (bts::api::admin::BTSUser* user, const bts::api::admin::UserAccountPermissions& user_account_permissions){
|
|
if(!user->has_user_data())
|
|
user->mutable_user_data();
|
|
user->mutable_user_data()->mutable_account_permissions()->CopyFrom(user_account_permissions);
|
|
}
|
|
bts::api::admin::BTSUser* AdminServiceUtils::update_user(bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::BTSUser& updated_user,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
validate_user_update(admin_data, updated_user, result);
|
|
if (result.is_success()){
|
|
bts::api::admin::BTSUser* user_ptr = find_user(admin_data, updated_user.id());
|
|
user_ptr->CopyFrom(updated_user);
|
|
return user_ptr;
|
|
}
|
|
else
|
|
return nullptr;
|
|
}
|
|
void AdminServiceUtils::delete_user (bts::api::admin::AdminData& admin_data,
|
|
const bts::api::admin::IDAPIArgument& id,
|
|
bts::api::admin::AdminServiceOperationResult& result){
|
|
result.set_is_success(true);
|
|
api::admin::BTSUser* user_ptr = AdminServiceUtils::find_user(admin_data, id.id());
|
|
if (user_ptr != nullptr)
|
|
{
|
|
std::string deleted_name;
|
|
int deleted_idx = 0;
|
|
do{
|
|
// keep going until the modified name is not found,
|
|
// otherwise keep "incrementing" the modified name
|
|
deleted_idx++;
|
|
deleted_name = deleted_idx == 1 ? fmt::format("DELETED_{}", user_ptr->name()) :
|
|
fmt::format("DELETED_{}_{}", deleted_idx, user_ptr->name());
|
|
}
|
|
while(AdminServiceUtils::find_user(admin_data, deleted_name, true) != nullptr);
|
|
user_ptr->set_is_present(false);
|
|
user_ptr->set_name(deleted_name);
|
|
}
|
|
else{
|
|
result.set_is_success(false);
|
|
result.set_error_text("Could not find user");
|
|
}
|
|
}
|
|
////////////////////////////////////////////
|
|
//risk limits //////////////////////////////
|
|
////////////////////////////////////////////
|
|
bool AdminServiceUtils::_sort_security_scopes (const bts::api::admin::SecurityScope& a,
|
|
const bts::api::admin::SecurityScope& b){
|
|
if (has_id(a.security_id()))
|
|
return true;
|
|
if (has_id(b.security_id()))
|
|
return false;
|
|
if (a.security_symbol() != "*")
|
|
return true;
|
|
return false;
|
|
}
|
|
bool AdminServiceUtils::_sort_product_scopes (const bts::api::admin::ProductScope& a,
|
|
const bts::api::admin::ProductScope&){
|
|
if (a.security_symbol() != "*")
|
|
return true;
|
|
return false;
|
|
}
|
|
void AdminServiceUtils::sort_limits (bts::api::admin::BTSAccount& account){
|
|
std::sort (account.mutable_security_position_limits()->begin(),
|
|
account.mutable_security_position_limits()->end(),
|
|
[](const bts::api::admin::AccountSecurityPositionLimitUnit& a, const bts::api::admin::AccountSecurityPositionLimitUnit& b){
|
|
return _sort_security_scopes(a.security(), b.security());
|
|
});
|
|
std::sort (account.mutable_product_position_limits()->begin(),
|
|
account.mutable_product_position_limits()->end(),
|
|
[](const bts::api::admin::AccountProductPositionLimitUnit& a, const bts::api::admin::AccountProductPositionLimitUnit& b){
|
|
return _sort_product_scopes(a.product(), b.product());
|
|
});
|
|
if (account.has_security_clip_limits())
|
|
std::sort (account.mutable_security_clip_limits()->mutable_limit()->begin(),
|
|
account.mutable_security_clip_limits()->mutable_limit()->end(),
|
|
[](const bts::api::admin::AccountSecurityClipLimitUnit& a, const bts::api::admin::AccountSecurityClipLimitUnit& b){
|
|
return _sort_security_scopes(a.security(), b.security());
|
|
});
|
|
}
|
|
bts::api::admin::AdminData AdminServiceUtils::sort_limits (const bts::api::admin::AdminData& admin_data){
|
|
bts::api::admin::AdminData rv;
|
|
rv.CopyFrom(admin_data);
|
|
for(int i=0; i<rv.accounts_size();i++)
|
|
sort_limits(*rv.mutable_accounts(i));
|
|
return rv;
|
|
}
|
|
// find the clip size for a security, account
|
|
const uint32_t AdminServiceUtils::find_account_security_clip_size(const bts::api::admin::BTSAccount& account,
|
|
const api::Security& security){
|
|
uint32_t rv = 0;
|
|
if (account.has_security_clip_limits())
|
|
for(const auto& limit : account.security_clip_limits().limit()){
|
|
if(match_security_scope(limit.security(), security))
|
|
return limit.clip_size();
|
|
}
|
|
return rv;
|
|
}
|
|
// find the position limit for an account, security
|
|
const bts::api::admin::AccountSecurityPositionLimitUnit* AdminServiceUtils::find_account_security_position_limit(const bts::api::admin::BTSAccount& account,
|
|
const api::Security& security){
|
|
for(const auto& limit : account.security_position_limits())
|
|
if(match_security_scope(limit.security(), security))
|
|
return &limit;
|
|
return nullptr;
|
|
}
|
|
// find the position limit for an account, product
|
|
const bts::api::admin::AccountProductPositionLimitUnit* AdminServiceUtils::find_account_product_position_limit(const bts::api::admin::BTSAccount& account,
|
|
const api::Product& product){
|
|
for(const auto& limit : account.product_position_limits())
|
|
if(match_product_scope(limit.product(), product))
|
|
return &limit;
|
|
return nullptr;
|
|
}
|
|
bool AdminServiceUtils::match_security_scope (const bts::api::admin::SecurityScope& scope,
|
|
const bts::api::Security& security){
|
|
if(has_id(scope.security_id())){
|
|
if (scope.security_id() == security.id())
|
|
return true;
|
|
}
|
|
else if (security.exchange() == scope.exchange() &&
|
|
security_type(security) == scope.security_type() &&
|
|
_match_limit_rule_symbol(security.symbol(), scope.security_symbol()))
|
|
return true;
|
|
return false;
|
|
}
|
|
bool AdminServiceUtils::match_product_scope (const bts::api::admin::ProductScope& scope,
|
|
const bts::api::Product& product){
|
|
return product.exchange() == scope.exchange() &&
|
|
product.type() && scope.security_type() &&
|
|
_match_limit_rule_symbol(product.symbol(), scope.security_symbol());
|
|
}
|
|
bool AdminServiceUtils::match_product(const api::Security& security,
|
|
const api::Product& product){
|
|
return product.exchange() == security.exchange() &&
|
|
product.type() == security_type(security) &&
|
|
product.symbol() == security.symbol();
|
|
}
|
|
bool AdminServiceUtils::_match_limit_rule_symbol (const std::string& symbol,
|
|
const std::string& limit_symbol){
|
|
return limit_symbol=="*" || symbol==limit_symbol;
|
|
}
|
|
api::SecurityType AdminServiceUtils::security_type(const api::Security& security){
|
|
switch(security.Contract_case())
|
|
{
|
|
case api::Security::ContractCase::kFuture:
|
|
return api::SecurityType::SECURITYTYPE_FUTURE;
|
|
case api::Security::ContractCase::kOption:
|
|
return api::SecurityType::SECURITYTYPE_OPTION;
|
|
case api::Security::ContractCase::kSpread:
|
|
return api::SecurityType::SECURITYTYPE_SPREAD;
|
|
case api::Security::ContractCase::kSynthetic:
|
|
return api::SecurityType::SECURITYTYPE_SYNTHETIC;
|
|
case api::Security::ContractCase::CONTRACT_NOT_SET:
|
|
return api::SecurityType::SECURITYTYPE_UNSET;
|
|
}
|
|
return api::SecurityType::SECURITYTYPE_UNSET;
|
|
}
|
|
////////////////////////////////////////////
|
|
// boostrapping ////////////////////////////
|
|
////////////////////////////////////////////
|
|
void AdminServiceUtils::bootstrap_data (bts::api::admin::AdminData& data){
|
|
data.set_id(1);
|
|
bts::api::admin::AdminServiceOperationResult result;
|
|
bts::api::admin::AdminServiceCreateAccountResult account_result;
|
|
bts::api::admin::AdminServiceCreateEntityResult user_result;
|
|
// adding accounts
|
|
auto parent_account = create_account(data, 0, std::string("ACC A"), std::string("description"), true, account_result);
|
|
auto account_1 = create_account(data, parent_account->id(), std::string("ACC A1"), std::string("description"), true, account_result); account_1->set_is_active(true);
|
|
auto account_2 = create_account(data, parent_account->id(), std::string("ACC A2"), std::string("description"), true, account_result); account_2->set_is_active(true);
|
|
auto account_3 = create_account(data, parent_account->id(), std::string("ACC A3"), std::string("description"), true, account_result); account_3->set_is_active(true);
|
|
create_account(data, parent_account->id(), std::string("ACC A4"), std::string("description"), true, account_result);
|
|
// add group
|
|
auto def_group = create_group(data, 0, std::string("DEFAULT"), result);
|
|
// adding users to the group
|
|
bts::api::admin::LicenseData license_data;
|
|
bts::api::admin::LicenseEntitlements license_entitlements;
|
|
auto user_1 = create_user(data, def_group->id(), std::string("bts"), std::string(""), false, license_data, license_entitlements, user_result); user_1->set_is_active(true);
|
|
auto user_2 = create_user(data, def_group->id(), std::string("bts_2"), std::string("bts_2"), false, license_data, license_entitlements, user_result); user_2->set_is_active(true);
|
|
auto user_3 = create_user(data, def_group->id(), std::string("bts_3"), std::string("bts_3"), false, license_data, license_entitlements, user_result); user_3->set_is_active(true);
|
|
//associate users
|
|
bts::api::admin::UserAccountPermissionUnit permission_unit;
|
|
permission_unit.mutable_trading_permission()->set_submit_market_orders(true);
|
|
permission_unit.mutable_admin_permission()->set_has_permissions(true);
|
|
bts::api::admin::UserAccountPermissions account_permissions;
|
|
account_permissions.mutable_account_permissions()->insert(google::protobuf::MapPair<uint32_t, bts::api::admin::UserAccountPermissionUnit>(parent_account->id(), permission_unit));
|
|
account_permissions.mutable_account_permissions()->insert(google::protobuf::MapPair<uint32_t, bts::api::admin::UserAccountPermissionUnit>(account_1->id(), permission_unit));
|
|
account_permissions.mutable_account_permissions()->insert(google::protobuf::MapPair<uint32_t, bts::api::admin::UserAccountPermissionUnit>(account_2->id(), permission_unit));
|
|
account_permissions.mutable_account_permissions()->insert(google::protobuf::MapPair<uint32_t, bts::api::admin::UserAccountPermissionUnit>(account_3->id(), permission_unit));
|
|
set_user_accounts(user_1, account_permissions);
|
|
set_user_accounts(user_2, account_permissions);
|
|
set_user_accounts(user_3, account_permissions);
|
|
// add cme account data
|
|
bts::api::admin::ExchangeAccountData exchange_account_data;
|
|
exchange_account_data.mutable_cme_account_data()->set_cti(bts::api::orderman::CTICode::CTI_CODE_CTI_CODE1);
|
|
exchange_account_data.mutable_cme_account_data()->set_origin(bts::api::orderman::CustomerOrFirm::CUSTOMER_OR_FIRM_FIRM);
|
|
exchange_account_data.mutable_cme_account_data()->set_clearing_account("ca_" + parent_account->name());
|
|
set_account_exchange_data(parent_account, exchange_account_data);
|
|
exchange_account_data.mutable_cme_account_data()->set_clearing_account("ca_" + account_1->name());
|
|
set_account_exchange_data(account_1, exchange_account_data);
|
|
exchange_account_data.mutable_cme_account_data()->set_clearing_account("ca_" + account_2->name());
|
|
set_account_exchange_data(account_2, exchange_account_data);
|
|
exchange_account_data.mutable_cme_account_data()->set_clearing_account("ca_" + account_3->name());
|
|
set_account_exchange_data(account_3, exchange_account_data);
|
|
// add cme user data
|
|
bts::api::admin::ExchangeUserData exchange_user_data;
|
|
exchange_user_data.mutable_cme_data()->set_operator_id("op_id_" + user_1->name());
|
|
set_user_exchange_data(user_1, exchange_user_data);
|
|
exchange_user_data.mutable_cme_data()->set_operator_id("op_id_" + user_2->name());
|
|
set_user_exchange_data(user_2, exchange_user_data);
|
|
exchange_user_data.mutable_cme_data()->set_operator_id("op_id_" + user_3->name());
|
|
set_user_exchange_data(user_3, exchange_user_data);
|
|
// associate all connections to all accounts
|
|
for(int i=0; i<data.connections_size();i++){
|
|
std::string conn_name = data.connections(i).name();
|
|
for(int j=0; j<data.accounts_size();j++)
|
|
data.mutable_accounts(j)->mutable_connections()->add_exchange_connection_names(conn_name);
|
|
}
|
|
// add prod limit for ACC A
|
|
auto acct_a_prod_limit = parent_account->add_product_position_limits();
|
|
acct_a_prod_limit->mutable_product()->set_exchange(api::Venue::VENUE_GLBX);
|
|
acct_a_prod_limit->mutable_product()->set_security_type(api::SecurityType::SECURITYTYPE_FUTURE);
|
|
acct_a_prod_limit->mutable_product()->set_security_symbol("*");
|
|
acct_a_prod_limit->set_long_position_limit(500000);
|
|
acct_a_prod_limit->set_short_position_limit(500000);
|
|
// security clip sizes for ACC A
|
|
auto acct_a_clip_size = parent_account->mutable_security_clip_limits()->add_limit();
|
|
acct_a_clip_size->mutable_security()->set_exchange(api::Venue::VENUE_GLBX);
|
|
acct_a_clip_size->mutable_security()->set_security_type(api::SecurityType::SECURITYTYPE_FUTURE);
|
|
acct_a_clip_size->mutable_security()->set_security_symbol("*");
|
|
acct_a_clip_size->set_clip_size(50);
|
|
// add sec limit for ACC A1
|
|
auto acct_a1_sec_limit = account_1->add_security_position_limits();
|
|
acct_a1_sec_limit->mutable_security()->set_exchange(api::Venue::VENUE_GLBX);
|
|
acct_a1_sec_limit->mutable_security()->set_security_type(api::SecurityType::SECURITYTYPE_FUTURE);
|
|
acct_a1_sec_limit->mutable_security()->set_security_symbol("*");
|
|
acct_a1_sec_limit->set_long_position_limit (10000);
|
|
acct_a1_sec_limit->set_short_position_limit (10000);
|
|
// add prod limit for ACC A1
|
|
auto acct_a1_prod_limit = account_1->add_product_position_limits();
|
|
acct_a1_prod_limit->mutable_product()->set_exchange(api::Venue::VENUE_GLBX);
|
|
acct_a1_prod_limit->mutable_product()->set_security_type(api::SecurityType::SECURITYTYPE_FUTURE);
|
|
acct_a1_prod_limit->mutable_product()->set_security_symbol("*");
|
|
acct_a1_prod_limit->set_long_position_limit(1000000);
|
|
acct_a1_prod_limit->set_short_position_limit(1000000);
|
|
// security clip sizes for ACC A1
|
|
auto acct_a1_clip_size = account_1->mutable_security_clip_limits()->add_limit();
|
|
acct_a1_clip_size->mutable_security()->set_exchange(api::Venue::VENUE_GLBX);
|
|
acct_a1_clip_size->mutable_security()->set_security_type(api::SecurityType::SECURITYTYPE_FUTURE);
|
|
acct_a1_clip_size->mutable_security()->set_security_symbol("*");
|
|
acct_a1_clip_size->set_clip_size(100);
|
|
}
|
|
bool AdminServiceUtils::has_id (uint32_t id){return id>0;}
|
|
}} |