|
@@ -37,11 +37,11 @@ MTAPIRES CPluginInstance::Start(IMTServerAPI * server)
|
|
|
m_api->LoggerOut(MTLogAtt, L"Plugin subscribe failed [%d]", ret);
|
|
m_api->LoggerOut(MTLogAtt, L"Plugin subscribe failed [%d]", ret);
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
- if (ret = m_api->OrderSubscribe(this) != MT_RET_OK)
|
|
|
|
|
- {
|
|
|
|
|
- m_api->LoggerOut(MTLogAtt, L"Order subscribe failed [%d]", ret);
|
|
|
|
|
- return ret;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //if (ret = m_api->OrderSubscribe(this) != MT_RET_OK)
|
|
|
|
|
+ //{
|
|
|
|
|
+ // m_api->LoggerOut(MTLogAtt, L"Order subscribe failed [%d]", ret);
|
|
|
|
|
+ // return ret;
|
|
|
|
|
+ //}
|
|
|
//if (ret = m_api->DealSubscribe(this) != MT_RET_OK)
|
|
//if (ret = m_api->DealSubscribe(this) != MT_RET_OK)
|
|
|
//{
|
|
//{
|
|
|
// m_api->LoggerOut(MTLogAtt, L"Deal subscribe failed [%d]", ret);
|
|
// m_api->LoggerOut(MTLogAtt, L"Deal subscribe failed [%d]", ret);
|
|
@@ -82,9 +82,9 @@ MTAPIRES CPluginInstance::Stop()
|
|
|
if ((ret = m_api->PluginUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
if ((ret = m_api->PluginUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
|
m_api->LoggerOut(MTLogErr, L"Failed to unsubscribe from plugin config updates [%s (%u)]",
|
|
m_api->LoggerOut(MTLogErr, L"Failed to unsubscribe from plugin config updates [%s (%u)]",
|
|
|
SMTFormat::FormatError(ret), ret);
|
|
SMTFormat::FormatError(ret), ret);
|
|
|
- if ((ret = m_api->OrderUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"Failed to unsubscribe order sink [%s (%u)]",
|
|
|
|
|
- SMTFormat::FormatError(ret), ret);
|
|
|
|
|
|
|
+ //if ((ret = m_api->OrderUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
|
|
|
+ // m_api->LoggerOut(MTLogErr, L"Failed to unsubscribe order sink [%s (%u)]",
|
|
|
|
|
+ // SMTFormat::FormatError(ret), ret);
|
|
|
//if ((ret = m_api->DealUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
//if ((ret = m_api->DealUnsubscribe(this)) != MT_RET_OK && ret != MT_RET_ERR_NOTFOUND)
|
|
|
// m_api->LoggerOut(MTLogErr, L"failed to unsubscribe deal [%s (%u)]",
|
|
// m_api->LoggerOut(MTLogErr, L"failed to unsubscribe deal [%s (%u)]",
|
|
|
// SMTFormat::FormatError(ret), ret);
|
|
// SMTFormat::FormatError(ret), ret);
|
|
@@ -136,242 +136,242 @@ void CPluginInstance::OnPluginUpdate(const IMTConPlugin * plugin)
|
|
|
// order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent());
|
|
// order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent());
|
|
|
//}
|
|
//}
|
|
|
|
|
|
|
|
-void CPluginInstance::OnOrderDelete(const IMTOrder * order)
|
|
|
|
|
-{
|
|
|
|
|
- if (order == nullptr) return;
|
|
|
|
|
-
|
|
|
|
|
- std::lock_guard<decltype(m_lock)> lk(m_lock);
|
|
|
|
|
- if (!m_enable) return;
|
|
|
|
|
- if (order->Login() != m_trader) return;
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"OnOrderDelete, login: %lld, ord: %lld, pos: %lld, state: %d, vol_init: %lld, vol_cur: %lld",
|
|
|
|
|
- order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent());
|
|
|
|
|
-
|
|
|
|
|
- if (order->Type() != IMTOrder::OP_BUY
|
|
|
|
|
- && order->Type() != IMTOrder::OP_SELL)
|
|
|
|
|
- {
|
|
|
|
|
- // 不是buy或者sell,不跟,直接退出
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- char order_buf[128];
|
|
|
|
|
- sprintf(order_buf, "%lld", order->PositionID());
|
|
|
|
|
- UINT64 position = order->PositionID();
|
|
|
|
|
- UINT64 order_id = order->Order();
|
|
|
|
|
- IMTAccount* account = m_api->UserCreateAccount();
|
|
|
|
|
- IMTOrder* new_order = m_api->OrderCreate();
|
|
|
|
|
-
|
|
|
|
|
- ScopeGuard guard([account, new_order, this]
|
|
|
|
|
- {
|
|
|
|
|
- if (account)
|
|
|
|
|
- account->Release();
|
|
|
|
|
- if (new_order)
|
|
|
|
|
- new_order->Release();
|
|
|
|
|
-
|
|
|
|
|
- m_redis_client->commit();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 订单在进入filled状态时,也会产生一个order delete回调
|
|
|
|
|
- if (order->Order() == order->PositionID())
|
|
|
|
|
- {
|
|
|
|
|
- // 如果是新建订单,那么写入新纪录
|
|
|
|
|
- char login_buf[128] = { 0 };
|
|
|
|
|
- char req_buf[128] = { 0 };
|
|
|
|
|
- for (auto login : m_followers)
|
|
|
|
|
- {
|
|
|
|
|
- if (m_api->UserAccountGet(login, account) != MT_RET_OK)
|
|
|
|
|
- {
|
|
|
|
|
- // TODO: 这里失败直接跳过没有做其他处理,下一次进来可能依然会遇到一样的问题
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- sprintf(login_buf, "%lld", login);
|
|
|
|
|
-
|
|
|
|
|
- UINT level = (UINT)(account->Balance() / m_step);
|
|
|
|
|
- UINT volume = round((double)level * order->VolumeCurrent() / 10000) * 100;
|
|
|
|
|
- UINT volume_ext = round((double)level * order->VolumeCurrentExt() / 10000) * 100;
|
|
|
|
|
- UINT init_volume = round((double)level * order->VolumeInitial() / 10000) * 100;
|
|
|
|
|
- UINT init_volume_ext = round((double)level * order->VolumeInitialExt() / 10000) * 100;
|
|
|
|
|
- UINT64 new_order_id = 0;
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"add order, vol_init: %lld, vol_cur: %lld", init_volume, volume);
|
|
|
|
|
-
|
|
|
|
|
- char msg[1024] = { 0 };
|
|
|
|
|
- sprintf(msg, "orig_position=&lld&login=%lld&source_login=1005&symbol=%s&action=200&type=%d&volume=%lld&price_order=%lf",
|
|
|
|
|
- order->PositionID(), login, ws2s(order->Symbol()).c_str(), order->Type(), init_volume, order->PriceOrder());
|
|
|
|
|
- m_redis_client->publish("dealer_send", msg, [this, position, login, order_id](cpp_redis::reply& r)
|
|
|
|
|
- {
|
|
|
|
|
- // 记录下login order等信息
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"original position #%lld, original order #%lld, login %lld, failed to excute dealer_send",
|
|
|
|
|
- );
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // dealer send之后需要另外一边记录request id
|
|
|
|
|
-
|
|
|
|
|
- // 尚未完成建仓,目前position id不填,仅完成订单后记录
|
|
|
|
|
- new_order->Clear();
|
|
|
|
|
- new_order->VolumeInitial(init_volume);
|
|
|
|
|
- new_order->VolumeCurrent(volume);
|
|
|
|
|
- new_order->Login(login);
|
|
|
|
|
- new_order->Symbol(order->Symbol());
|
|
|
|
|
- new_order->Type(order->Type());
|
|
|
|
|
- new_order->Digits(order->Digits());
|
|
|
|
|
- new_order->DigitsCurrency(order->DigitsCurrency());
|
|
|
|
|
- new_order->ContractSize(order->ContractSize());
|
|
|
|
|
- new_order->PriceOrder(order->PriceOrder());
|
|
|
|
|
- new_order->PriceCurrent(order->PriceCurrent());
|
|
|
|
|
- new_order->StateSet(order->State());
|
|
|
|
|
- new_order->TimeSetup(order->TimeSetup());
|
|
|
|
|
- new_order->TimeSetupMsc(order->TimeSetupMsc());
|
|
|
|
|
- new_order->TimeDone(order->TimeDone());
|
|
|
|
|
- new_order->TimeDoneMsc(order->TimeDoneMsc());
|
|
|
|
|
- // --
|
|
|
|
|
- new_order->PriceSL(order->PriceSL());
|
|
|
|
|
- new_order->PriceTP(order->PriceTP());
|
|
|
|
|
- new_order->Comment(order->Comment());
|
|
|
|
|
- new_order->ActivationFlags(order->ActivationFlags());
|
|
|
|
|
- new_order->ActivationMode(order->ActivationMode());
|
|
|
|
|
- new_order->ActivationPrice(order->ActivationPrice());
|
|
|
|
|
- new_order->ActivationTime(order->ActivationTime());
|
|
|
|
|
- new_order->PriceTrigger(order->PriceTrigger());
|
|
|
|
|
- new_order->RateMargin(order->RateMargin()); //
|
|
|
|
|
- new_order->ReasonSet(order->Reason()); //
|
|
|
|
|
- new_order->TypeFill(order->TypeFill()); //
|
|
|
|
|
- new_order->TypeTime(order->TypeTime()); //
|
|
|
|
|
-
|
|
|
|
|
- MTAPIRES ret = m_api->HistoryAdd(new_order);
|
|
|
|
|
- if (ret != MT_RET_OK)
|
|
|
|
|
- {
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"%lld failed to add order, original order #%lld [%d]", login, order->Login(), ret);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- new_order_id = new_order->Order();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"%lld add order #%lld, original order #%lld [%d]", login, new_order_id, order->Order());
|
|
|
|
|
-
|
|
|
|
|
- // TODO: 现在做法是,如果level为0,后面都不管
|
|
|
|
|
- // 如果跟单失败,那么position id也为0,所以后面也不应该处理
|
|
|
|
|
- position_context context;
|
|
|
|
|
- context.level = level;
|
|
|
|
|
- context.cur_ord = new_order_id;
|
|
|
|
|
- context.position_id = new_order_id; // 建仓,order id = position id
|
|
|
|
|
- int direction = 1;
|
|
|
|
|
- if (order->Type() == IMTOrder::OP_SELL)
|
|
|
|
|
- direction = -1;
|
|
|
|
|
- context.volume = direction * order->VolumeInitial();
|
|
|
|
|
-
|
|
|
|
|
- m_redis_client->hset(order_buf, login_buf, std::string((char*)&context, sizeof(position_context)), [this](cpp_redis::reply& r)
|
|
|
|
|
- {
|
|
|
|
|
- if (r.ko())
|
|
|
|
|
- {
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"redis: %s", r.error().c_str());
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 可以在退出前提交
|
|
|
|
|
- // m_redis_client->commit();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- // 如果不是新建订单,先使用position id先检查记录是否存在
|
|
|
|
|
- char login_buf[128];
|
|
|
|
|
- for (auto login : m_followers)
|
|
|
|
|
- {
|
|
|
|
|
- sprintf(login_buf, "%lld", login);
|
|
|
|
|
- auto fut = m_redis_client->hget(order_buf, login_buf);
|
|
|
|
|
- m_redis_client->sync_commit();
|
|
|
|
|
- auto reply = fut.get();
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"request cache, key %s, field %s", s2ws(order_buf).c_str(), s2ws(login_buf).c_str());
|
|
|
|
|
-
|
|
|
|
|
- // 如果不存在,忽略
|
|
|
|
|
- if (reply.ko()) continue;
|
|
|
|
|
- if (reply.is_null()) continue;
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"get context, login: %lld", login);
|
|
|
|
|
-
|
|
|
|
|
- // 获取context
|
|
|
|
|
- position_context context;
|
|
|
|
|
- memcpy(&context, reply.as_string().c_str(), sizeof(position_context));
|
|
|
|
|
-
|
|
|
|
|
- // 按建仓时的叙述,如果level或者position为0,亦忽略该记录
|
|
|
|
|
- if (context.level == 0) continue;
|
|
|
|
|
- if (context.position_id == 0) continue;
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"get context, order: #%lld, position: #%lld", context.cur_ord, context.position_id);
|
|
|
|
|
-
|
|
|
|
|
- // 如果存在,则继续操作
|
|
|
|
|
- UINT volume = round((double)context.level * order->VolumeCurrent() / 10000) * 100;
|
|
|
|
|
- UINT volume_ext = round((double)context.level * order->VolumeCurrentExt() / 10000) * 100;
|
|
|
|
|
- UINT init_volume = round((double)context.level * order->VolumeInitial() / 10000) * 100;
|
|
|
|
|
- UINT init_volume_ext = round((double)context.level * order->VolumeInitialExt() / 10000) * 100;
|
|
|
|
|
- UINT64 new_order_id = 0;
|
|
|
|
|
-
|
|
|
|
|
- new_order->Clear();
|
|
|
|
|
- new_order->VolumeInitial(init_volume);
|
|
|
|
|
- new_order->VolumeCurrent(volume); // 这里是状态START,如果是状态4的FILLED时,volume current为0
|
|
|
|
|
- //new_order->VolumeCurrent(init_volume);
|
|
|
|
|
- new_order->Login(login);
|
|
|
|
|
- new_order->Symbol(order->Symbol());
|
|
|
|
|
- new_order->Type(order->Type());
|
|
|
|
|
- new_order->Digits(order->Digits());
|
|
|
|
|
- new_order->DigitsCurrency(order->DigitsCurrency());
|
|
|
|
|
- new_order->ContractSize(order->ContractSize());
|
|
|
|
|
- new_order->PriceOrder(order->PriceOrder());
|
|
|
|
|
- new_order->PriceCurrent(order->PriceCurrent());
|
|
|
|
|
- new_order->StateSet(order->State());
|
|
|
|
|
- new_order->TimeSetup(order->TimeSetup());
|
|
|
|
|
- new_order->TimeSetupMsc(order->TimeSetupMsc());
|
|
|
|
|
- new_order->TimeDone(order->TimeDone());
|
|
|
|
|
- new_order->TimeDoneMsc(order->TimeDoneMsc());
|
|
|
|
|
- new_order->PositionID(context.position_id);
|
|
|
|
|
-
|
|
|
|
|
- new_order->PriceSL(order->PriceSL());
|
|
|
|
|
- new_order->PriceTP(order->PriceTP());
|
|
|
|
|
- new_order->Comment(order->Comment());
|
|
|
|
|
- new_order->ActivationFlags(order->ActivationFlags());
|
|
|
|
|
- new_order->ActivationMode(order->ActivationMode());
|
|
|
|
|
- new_order->ActivationPrice(order->ActivationPrice());
|
|
|
|
|
- new_order->ActivationTime(order->ActivationTime());
|
|
|
|
|
- new_order->PriceTrigger(order->PriceTrigger());
|
|
|
|
|
- new_order->RateMargin(order->RateMargin()); //
|
|
|
|
|
- new_order->ReasonSet(order->Reason()); //
|
|
|
|
|
- new_order->TypeFill(order->TypeFill()); //
|
|
|
|
|
- new_order->TypeTime(order->TypeTime()); //
|
|
|
|
|
-
|
|
|
|
|
- MTAPIRES ret = m_api->HistoryAdd(new_order);
|
|
|
|
|
- if (ret != MT_RET_OK)
|
|
|
|
|
- {
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"%lld failed to add order, original order #%lld [%d]", login, order->Order(), ret);
|
|
|
|
|
- // FIXME: 如果做单失败该怎么办
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- new_order_id = new_order->Order();
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"%lld add order #%lld, original order #%lld", login, new_order_id, order->Order());
|
|
|
|
|
-
|
|
|
|
|
- // 完成之后,写入新纪录
|
|
|
|
|
- context.cur_ord = new_order_id;
|
|
|
|
|
- int direction = 1;
|
|
|
|
|
- if (order->Type() == IMTOrder::OP_SELL)
|
|
|
|
|
- direction = -1;
|
|
|
|
|
- context.volume += direction * order->VolumeInitial();
|
|
|
|
|
-
|
|
|
|
|
- m_api->LoggerOut(MTLogOK, L"write cache, key %s, field %s", s2ws(order_buf).c_str(), s2ws(login_buf).c_str());
|
|
|
|
|
-
|
|
|
|
|
- m_redis_client->hset(order_buf, login_buf, std::string((char*)&context, sizeof(position_context)), [this](cpp_redis::reply& r)
|
|
|
|
|
- {
|
|
|
|
|
- if (r.ko())
|
|
|
|
|
- {
|
|
|
|
|
- m_api->LoggerOut(MTLogErr, L"redis: %s", r.error().c_str());
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- // 下一次get会调用commit
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+//void CPluginInstance::OnOrderDelete(const IMTOrder * order)
|
|
|
|
|
+//{
|
|
|
|
|
+// if (order == nullptr) return;
|
|
|
|
|
+//
|
|
|
|
|
+// std::lock_guard<decltype(m_lock)> lk(m_lock);
|
|
|
|
|
+// if (!m_enable) return;
|
|
|
|
|
+// if (order->Login() != m_trader) return;
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"OnOrderDelete, login: %lld, ord: %lld, pos: %lld, state: %d, vol_init: %lld, vol_cur: %lld",
|
|
|
|
|
+// order->Login(), order->Order(), order->PositionID(), order->State(), order->VolumeInitial(), order->VolumeCurrent());
|
|
|
|
|
+//
|
|
|
|
|
+// if (order->Type() != IMTOrder::OP_BUY
|
|
|
|
|
+// && order->Type() != IMTOrder::OP_SELL)
|
|
|
|
|
+// {
|
|
|
|
|
+// // 不是buy或者sell,不跟,直接退出
|
|
|
|
|
+// return;
|
|
|
|
|
+// }
|
|
|
|
|
+//
|
|
|
|
|
+// char order_buf[128];
|
|
|
|
|
+// sprintf(order_buf, "%lld", order->PositionID());
|
|
|
|
|
+// UINT64 position = order->PositionID();
|
|
|
|
|
+// UINT64 order_id = order->Order();
|
|
|
|
|
+// IMTAccount* account = m_api->UserCreateAccount();
|
|
|
|
|
+// IMTOrder* new_order = m_api->OrderCreate();
|
|
|
|
|
+//
|
|
|
|
|
+// ScopeGuard guard([account, new_order, this]
|
|
|
|
|
+// {
|
|
|
|
|
+// if (account)
|
|
|
|
|
+// account->Release();
|
|
|
|
|
+// if (new_order)
|
|
|
|
|
+// new_order->Release();
|
|
|
|
|
+//
|
|
|
|
|
+// m_redis_client->commit();
|
|
|
|
|
+// });
|
|
|
|
|
+//
|
|
|
|
|
+// // 订单在进入filled状态时,也会产生一个order delete回调
|
|
|
|
|
+// if (order->Order() == order->PositionID())
|
|
|
|
|
+// {
|
|
|
|
|
+// // 如果是新建订单,那么写入新纪录
|
|
|
|
|
+// char login_buf[128] = { 0 };
|
|
|
|
|
+// char req_buf[128] = { 0 };
|
|
|
|
|
+// for (auto login : m_followers)
|
|
|
|
|
+// {
|
|
|
|
|
+// if (m_api->UserAccountGet(login, account) != MT_RET_OK)
|
|
|
|
|
+// {
|
|
|
|
|
+// // TODO: 这里失败直接跳过没有做其他处理,下一次进来可能依然会遇到一样的问题
|
|
|
|
|
+// continue;
|
|
|
|
|
+// }
|
|
|
|
|
+// sprintf(login_buf, "%lld", login);
|
|
|
|
|
+//
|
|
|
|
|
+// UINT level = (UINT)(account->Balance() / m_step);
|
|
|
|
|
+// UINT volume = round((double)level * order->VolumeCurrent() / 10000) * 100;
|
|
|
|
|
+// UINT volume_ext = round((double)level * order->VolumeCurrentExt() / 10000) * 100;
|
|
|
|
|
+// UINT init_volume = round((double)level * order->VolumeInitial() / 10000) * 100;
|
|
|
|
|
+// UINT init_volume_ext = round((double)level * order->VolumeInitialExt() / 10000) * 100;
|
|
|
|
|
+// UINT64 new_order_id = 0;
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"add order, vol_init: %lld, vol_cur: %lld", init_volume, volume);
|
|
|
|
|
+//
|
|
|
|
|
+// char msg[1024] = { 0 };
|
|
|
|
|
+// sprintf(msg, "orig_position=&lld&login=%lld&source_login=1005&symbol=%s&action=200&type=%d&volume=%lld&price_order=%lf",
|
|
|
|
|
+// order->PositionID(), login, ws2s(order->Symbol()).c_str(), order->Type(), init_volume, order->PriceOrder());
|
|
|
|
|
+// m_redis_client->publish("dealer_send", msg, [this, position, login, order_id](cpp_redis::reply& r)
|
|
|
|
|
+// {
|
|
|
|
|
+// // 记录下login order等信息
|
|
|
|
|
+// m_api->LoggerOut(MTLogErr, L"original position #%lld, original order #%lld, login %lld, failed to excute dealer_send",
|
|
|
|
|
+// );
|
|
|
|
|
+// });
|
|
|
|
|
+//
|
|
|
|
|
+// // dealer send之后需要另外一边记录request id
|
|
|
|
|
+//
|
|
|
|
|
+// // 尚未完成建仓,目前position id不填,仅完成订单后记录
|
|
|
|
|
+// new_order->Clear();
|
|
|
|
|
+// new_order->VolumeInitial(init_volume);
|
|
|
|
|
+// new_order->VolumeCurrent(volume);
|
|
|
|
|
+// new_order->Login(login);
|
|
|
|
|
+// new_order->Symbol(order->Symbol());
|
|
|
|
|
+// new_order->Type(order->Type());
|
|
|
|
|
+// new_order->Digits(order->Digits());
|
|
|
|
|
+// new_order->DigitsCurrency(order->DigitsCurrency());
|
|
|
|
|
+// new_order->ContractSize(order->ContractSize());
|
|
|
|
|
+// new_order->PriceOrder(order->PriceOrder());
|
|
|
|
|
+// new_order->PriceCurrent(order->PriceCurrent());
|
|
|
|
|
+// new_order->StateSet(order->State());
|
|
|
|
|
+// new_order->TimeSetup(order->TimeSetup());
|
|
|
|
|
+// new_order->TimeSetupMsc(order->TimeSetupMsc());
|
|
|
|
|
+// new_order->TimeDone(order->TimeDone());
|
|
|
|
|
+// new_order->TimeDoneMsc(order->TimeDoneMsc());
|
|
|
|
|
+// // --
|
|
|
|
|
+// new_order->PriceSL(order->PriceSL());
|
|
|
|
|
+// new_order->PriceTP(order->PriceTP());
|
|
|
|
|
+// new_order->Comment(order->Comment());
|
|
|
|
|
+// new_order->ActivationFlags(order->ActivationFlags());
|
|
|
|
|
+// new_order->ActivationMode(order->ActivationMode());
|
|
|
|
|
+// new_order->ActivationPrice(order->ActivationPrice());
|
|
|
|
|
+// new_order->ActivationTime(order->ActivationTime());
|
|
|
|
|
+// new_order->PriceTrigger(order->PriceTrigger());
|
|
|
|
|
+// new_order->RateMargin(order->RateMargin()); //
|
|
|
|
|
+// new_order->ReasonSet(order->Reason()); //
|
|
|
|
|
+// new_order->TypeFill(order->TypeFill()); //
|
|
|
|
|
+// new_order->TypeTime(order->TypeTime()); //
|
|
|
|
|
+//
|
|
|
|
|
+// MTAPIRES ret = m_api->HistoryAdd(new_order);
|
|
|
|
|
+// if (ret != MT_RET_OK)
|
|
|
|
|
+// {
|
|
|
|
|
+// m_api->LoggerOut(MTLogErr, L"%lld failed to add order, original order #%lld [%d]", login, order->Login(), ret);
|
|
|
|
|
+// }
|
|
|
|
|
+// else
|
|
|
|
|
+// {
|
|
|
|
|
+// new_order_id = new_order->Order();
|
|
|
|
|
+// }
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"%lld add order #%lld, original order #%lld [%d]", login, new_order_id, order->Order());
|
|
|
|
|
+//
|
|
|
|
|
+// // TODO: 现在做法是,如果level为0,后面都不管
|
|
|
|
|
+// // 如果跟单失败,那么position id也为0,所以后面也不应该处理
|
|
|
|
|
+// position_context context;
|
|
|
|
|
+// context.level = level;
|
|
|
|
|
+// context.cur_ord = new_order_id;
|
|
|
|
|
+// context.position_id = new_order_id; // 建仓,order id = position id
|
|
|
|
|
+// int direction = 1;
|
|
|
|
|
+// if (order->Type() == IMTOrder::OP_SELL)
|
|
|
|
|
+// direction = -1;
|
|
|
|
|
+// context.volume = direction * order->VolumeInitial();
|
|
|
|
|
+//
|
|
|
|
|
+// m_redis_client->hset(order_buf, login_buf, std::string((char*)&context, sizeof(position_context)), [this](cpp_redis::reply& r)
|
|
|
|
|
+// {
|
|
|
|
|
+// if (r.ko())
|
|
|
|
|
+// {
|
|
|
|
|
+// m_api->LoggerOut(MTLogErr, L"redis: %s", r.error().c_str());
|
|
|
|
|
+// }
|
|
|
|
|
+// });
|
|
|
|
|
+//
|
|
|
|
|
+// // 可以在退出前提交
|
|
|
|
|
+// // m_redis_client->commit();
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// else
|
|
|
|
|
+// {
|
|
|
|
|
+// // 如果不是新建订单,先使用position id先检查记录是否存在
|
|
|
|
|
+// char login_buf[128];
|
|
|
|
|
+// for (auto login : m_followers)
|
|
|
|
|
+// {
|
|
|
|
|
+// sprintf(login_buf, "%lld", login);
|
|
|
|
|
+// auto fut = m_redis_client->hget(order_buf, login_buf);
|
|
|
|
|
+// m_redis_client->sync_commit();
|
|
|
|
|
+// auto reply = fut.get();
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"request cache, key %s, field %s", s2ws(order_buf).c_str(), s2ws(login_buf).c_str());
|
|
|
|
|
+//
|
|
|
|
|
+// // 如果不存在,忽略
|
|
|
|
|
+// if (reply.ko()) continue;
|
|
|
|
|
+// if (reply.is_null()) continue;
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"get context, login: %lld", login);
|
|
|
|
|
+//
|
|
|
|
|
+// // 获取context
|
|
|
|
|
+// position_context context;
|
|
|
|
|
+// memcpy(&context, reply.as_string().c_str(), sizeof(position_context));
|
|
|
|
|
+//
|
|
|
|
|
+// // 按建仓时的叙述,如果level或者position为0,亦忽略该记录
|
|
|
|
|
+// if (context.level == 0) continue;
|
|
|
|
|
+// if (context.position_id == 0) continue;
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"get context, order: #%lld, position: #%lld", context.cur_ord, context.position_id);
|
|
|
|
|
+//
|
|
|
|
|
+// // 如果存在,则继续操作
|
|
|
|
|
+// UINT volume = round((double)context.level * order->VolumeCurrent() / 10000) * 100;
|
|
|
|
|
+// UINT volume_ext = round((double)context.level * order->VolumeCurrentExt() / 10000) * 100;
|
|
|
|
|
+// UINT init_volume = round((double)context.level * order->VolumeInitial() / 10000) * 100;
|
|
|
|
|
+// UINT init_volume_ext = round((double)context.level * order->VolumeInitialExt() / 10000) * 100;
|
|
|
|
|
+// UINT64 new_order_id = 0;
|
|
|
|
|
+//
|
|
|
|
|
+// new_order->Clear();
|
|
|
|
|
+// new_order->VolumeInitial(init_volume);
|
|
|
|
|
+// new_order->VolumeCurrent(volume); // 这里是状态START,如果是状态4的FILLED时,volume current为0
|
|
|
|
|
+// //new_order->VolumeCurrent(init_volume);
|
|
|
|
|
+// new_order->Login(login);
|
|
|
|
|
+// new_order->Symbol(order->Symbol());
|
|
|
|
|
+// new_order->Type(order->Type());
|
|
|
|
|
+// new_order->Digits(order->Digits());
|
|
|
|
|
+// new_order->DigitsCurrency(order->DigitsCurrency());
|
|
|
|
|
+// new_order->ContractSize(order->ContractSize());
|
|
|
|
|
+// new_order->PriceOrder(order->PriceOrder());
|
|
|
|
|
+// new_order->PriceCurrent(order->PriceCurrent());
|
|
|
|
|
+// new_order->StateSet(order->State());
|
|
|
|
|
+// new_order->TimeSetup(order->TimeSetup());
|
|
|
|
|
+// new_order->TimeSetupMsc(order->TimeSetupMsc());
|
|
|
|
|
+// new_order->TimeDone(order->TimeDone());
|
|
|
|
|
+// new_order->TimeDoneMsc(order->TimeDoneMsc());
|
|
|
|
|
+// new_order->PositionID(context.position_id);
|
|
|
|
|
+//
|
|
|
|
|
+// new_order->PriceSL(order->PriceSL());
|
|
|
|
|
+// new_order->PriceTP(order->PriceTP());
|
|
|
|
|
+// new_order->Comment(order->Comment());
|
|
|
|
|
+// new_order->ActivationFlags(order->ActivationFlags());
|
|
|
|
|
+// new_order->ActivationMode(order->ActivationMode());
|
|
|
|
|
+// new_order->ActivationPrice(order->ActivationPrice());
|
|
|
|
|
+// new_order->ActivationTime(order->ActivationTime());
|
|
|
|
|
+// new_order->PriceTrigger(order->PriceTrigger());
|
|
|
|
|
+// new_order->RateMargin(order->RateMargin()); //
|
|
|
|
|
+// new_order->ReasonSet(order->Reason()); //
|
|
|
|
|
+// new_order->TypeFill(order->TypeFill()); //
|
|
|
|
|
+// new_order->TypeTime(order->TypeTime()); //
|
|
|
|
|
+//
|
|
|
|
|
+// MTAPIRES ret = m_api->HistoryAdd(new_order);
|
|
|
|
|
+// if (ret != MT_RET_OK)
|
|
|
|
|
+// {
|
|
|
|
|
+// m_api->LoggerOut(MTLogErr, L"%lld failed to add order, original order #%lld [%d]", login, order->Order(), ret);
|
|
|
|
|
+// // FIXME: 如果做单失败该怎么办
|
|
|
|
|
+// continue;
|
|
|
|
|
+// }
|
|
|
|
|
+//
|
|
|
|
|
+// new_order_id = new_order->Order();
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"%lld add order #%lld, original order #%lld", login, new_order_id, order->Order());
|
|
|
|
|
+//
|
|
|
|
|
+// // 完成之后,写入新纪录
|
|
|
|
|
+// context.cur_ord = new_order_id;
|
|
|
|
|
+// int direction = 1;
|
|
|
|
|
+// if (order->Type() == IMTOrder::OP_SELL)
|
|
|
|
|
+// direction = -1;
|
|
|
|
|
+// context.volume += direction * order->VolumeInitial();
|
|
|
|
|
+//
|
|
|
|
|
+// m_api->LoggerOut(MTLogOK, L"write cache, key %s, field %s", s2ws(order_buf).c_str(), s2ws(login_buf).c_str());
|
|
|
|
|
+//
|
|
|
|
|
+// m_redis_client->hset(order_buf, login_buf, std::string((char*)&context, sizeof(position_context)), [this](cpp_redis::reply& r)
|
|
|
|
|
+// {
|
|
|
|
|
+// if (r.ko())
|
|
|
|
|
+// {
|
|
|
|
|
+// m_api->LoggerOut(MTLogErr, L"redis: %s", r.error().c_str());
|
|
|
|
|
+// }
|
|
|
|
|
+// });
|
|
|
|
|
+// // 下一次get会调用commit
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+//}
|
|
|
|
|
|
|
|
//void CPluginInstance::OnOrderClean(const UINT64 login)
|
|
//void CPluginInstance::OnOrderClean(const UINT64 login)
|
|
|
//{
|
|
//{
|
|
@@ -575,7 +575,8 @@ void CPluginInstance::OnOrderDelete(const IMTOrder * order)
|
|
|
// }
|
|
// }
|
|
|
//}
|
|
//}
|
|
|
|
|
|
|
|
-void CPluginInstance::OnTradeRequestAdd(const IMTRequest * request, const IMTConGroup * group, const IMTConSymbol * symbol, const IMTPosition * position, const IMTOrder * order)
|
|
|
|
|
|
|
+void CPluginInstance::OnTradeRequestProcess(const IMTRequest* request, const IMTConfirm* confirm, const IMTConGroup* group,
|
|
|
|
|
+ const IMTConSymbol* symbol, const IMTPosition* position, const IMTOrder* order, const IMTDeal* deal)
|
|
|
{
|
|
{
|
|
|
if (request == nullptr
|
|
if (request == nullptr
|
|
|
|| group == nullptr
|
|
|| group == nullptr
|