Files
zszq-trs/YLErpDAL/Modules/SwapModule/SwapConsumerService.cs
T
2024-05-09 14:06:26 +08:00

1392 lines
63 KiB
C#

using BaseOUDAL;
using Confluent.Kafka;
using DocumentFormat.OpenXml.Wordprocessing;
using Microsoft.Office.Interop.Excel;
using CsvHelper;
using Newtonsoft.Json;
using Qdp.Foundation.Utilities;
using YLErp.Abstract;
using YLErp.BLL;
using YLErp.BLL.Eod;
using YLErp.Commons;
using YLErp.DBModels;
using YLErp.DBModels.Enums;
using YLErp.Enums;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.HengTaiModel;
using YLErp.Models;
using YLErp.Modules.AppModule;
using YLErp.Modules.ClientModule;
using YLErp.Modules.ExchangeTradeModule;
using YLErp.Modules.TradeModule;
using static YLErp.ConsGlobal;
namespace YLErp.Modules.SwapModule
{
public class SwapConsumerService : YLBaseService
{
static readonly IYcLogger logger = LogFactory.GetLogger<SwapConsumerService>();
private IKafkaProduce kafkaProduceHelper;
private string reqMarginInsert = string.Empty;
public SwapConsumerService(OptUserInfo optUser) : base(optUser)
{
reqMarginInsert = Environment.GetEnvironmentVariable("KafkaConfig_ReqMarginInsertTopic");
}
public void SetKafKaProduce(IKafkaProduce kafkaProduce)
{
kafkaProduceHelper = kafkaProduce;
}
/// <summary>
/// 4.8.1. 消费收益互换回执交易接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTradeResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<RequestBaseWithHead<SwapTradeReq>>(msg);
var pushLogService = new PushLogService(UserInfo);
var serialNo = result.HEADER.SERIAL_NO;
var extNo = result.HEADER.EXT_NO;
var pushLog = pushLogService.GetLogBySerialNo(serialNo, (int)SwapPushDataEnum.收益互换交易回执);
var resultState = SwapPushDataStateEnum.接收处理成功;
if (pushLog != null && pushLog.data_state == (int)resultState)
{
return;
}
string dealResult = "";
if (result.RECORD == null)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = "收益互换信息不能为空";
}
else
{
if (string.IsNullOrEmpty(extNo) && result.RECORD.BASEINFO != null)
{
extNo = result.RECORD.BASEINFO.EXT_NO;
}
try
{
var trade = DbContext.trade.FirstOrDefault(x => x.TradeNumber == extNo);
if (trade != null)
{
var HTStatus = TryFormatInt(result.RECORD.BASEINFO.ORDSTATUS);
trade.HTStatus = HTStatus;
DbContext.SaveChanges();
if (HTStatus != 7)
{
return;
}
DealUpdateConsumerTrade(result.RECORD, trade);
}
else
{
throw new Exception($"交易{extNo}不存在");
}
}
catch (Exception e)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = e.Message;
LogFactory.GetLogger("SwapConsumerService").Error("消费收益互换回执交易接口", e);
}
}
pushLogService.SaveConsumerLog(serialNo, extNo, SwapPushDataEnum.收益互换交易回执, resultState, msg, dealResult);
}
});
}
/// <summary>
/// 4.8.2. 消费互换资产交易回执接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTradePosiResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<RequestBaseWithHead<SwapPosiReq>>(msg);
var pushLogService = new PushLogService(UserInfo);
var serialNo = result.HEADER.SERIAL_NO;
var extNo = result.HEADER.EXT_NO;
var pushLog = pushLogService.GetLogBySerialNo(serialNo, (int)SwapPushDataEnum.互换资产交易回执);
var resultState = SwapPushDataStateEnum.接收处理成功;
string dealResult = "";
if (pushLog != null && pushLog.data_state == (int)resultState)
{
return;
}
if (result.RECORD == null || result.RECORD.BASEINFO == null)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = "找不到合约编号";
}
else
{
try
{
var account = result.RECORD.BASEINFO.SECU_INT;
var HTAccounts = DbContext.exchange_account.Where(x => !string.IsNullOrEmpty(x.AccountCode)).Select(s => s.AccountCode).Distinct().ToList();
if (HTAccounts.Contains(account))
{
PrepareExchangeTradeData(result.RECORD,"衡泰同步");
return;
}
if (OtcAppConfigHelper.HTUpdate != 1)
{
return;
}
var tradeNumber = result.RECORD.BASEINFO.TRD_RELATED_NO;
var HTStatus = TryFormatInt(result.RECORD.BASEINFO.ORDSTATUS);
var trade = CheckTradeExist(tradeNumber);
// 衡泰状态不是成交确认或者 当前交易有平仓,不给修改,如日内平仓,或者dma部分平仓
if (HTStatus != 7)
{
return;
}
if (pushLog == null && !CheckPositionNumber(extNo))
{
if (long.TryParse(extNo, out long dataId))//平仓
{
pushLog = pushLogService.GetLogByDataId(dataId);
if (pushLog != null)//我方平仓,不做操作
{
extNo = pushLog.data_number;
}
}
else //衡泰平仓
{
var posiGrossPrice = TryFormatDecimal(result.RECORD.TRADEINFO.ORDPRICE) / 100;
var orderDate = TryFormatDate(result.RECORD.BASEINFO.ORDDATE).Date;
dealResult = DealUnwindPosiEvent(posiGrossPrice, trade, orderDate);
}
}
else if (trade.UnWindDate == null)
{
PreparePosiData(result.RECORD, trade, extNo);
}
}
catch (Exception e)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = e.Message;
LogFactory.GetLogger("SwapConsumerService").Error("消费互换资产交易回执接口", e);
}
}
new PushLogService(UserInfo).SaveConsumerLog(serialNo, extNo, SwapPushDataEnum.互换资产交易回执, resultState, msg, dealResult);
}
});
}
/// <summary>
/// 对冲交易回执接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerExchangeTradeResp(KafkaConsumerHelper _kafkaConsumer,string tradeSource)
{
_kafkaConsumer.Subscribe(msg =>
{
var hedgingSource = OtcAppConfigHelper.HedgingSource == 2 || OtcAppConfigHelper.HedgingSource == 0;
if (hedgingSource)
{
return;
}
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<SwapAsset>(msg);
if (result == null)
{
return;
}
try
{
var account = result.SECU_INT;
var HTAccounts = DbContext.exchange_account.Where(x => !string.IsNullOrEmpty(x.AccountCode)).Select(s => s.AccountCode).Distinct().ToList();
if (HTAccounts.Contains(account))
{
PrepareExchangeTradeData(result, tradeSource);
return;
}
}
catch (Exception e)
{
LogFactory.GetLogger("SwapConsumerService").Error("对冲交易回执接口", e);
}
}
});
}
/// <summary>
/// Trs对冲交易接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTrsExchangeTradeResp(KafkaConsumerHelper _kafkaConsumer, string tradeSource)
{
_kafkaConsumer.Subscribe(msg =>
{
var hedgingSource = OtcAppConfigHelper.HedgingSource==1|| OtcAppConfigHelper.HedgingSource==0;
if (hedgingSource)
{
return;
}
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<SwapAsset>(msg);
if (result == null)
{
return;
}
try
{
var account = result.SECU_INT;
var HTAccounts = DbContext.exchange_account.Where(x => !string.IsNullOrEmpty(x.AccountCode)).Select(s => s.AccountCode).Distinct().ToList();
if (HTAccounts.Contains(account))
{
PrepareExchangeTradeData(result, tradeSource);
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
});
return;
}
}
catch (Exception e)
{
LogFactory.GetLogger("SwapConsumerService").Error("TRS对冲交易回执接口", e);
}
}
});
}
/// <summary>
/// 4.8.3. 消费预付金交易回执接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTradeMarginResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<RequestBaseWithHead<SwapMarginReq>>(msg);
var pushLogService = new PushLogService(UserInfo);
var serialNo = result.HEADER.SERIAL_NO;
var extNo = result.HEADER.EXT_NO;
var pushLog = pushLogService.GetLogBySerialNo(serialNo, (int)SwapPushDataEnum.预付金交易回执);
var resultState = SwapPushDataStateEnum.接收处理成功;
if (pushLog != null && pushLog.data_state == (int)resultState)
{
return;
}
string dealResult = "";
if (result.RECORD == null || result.RECORD.RESERVE == null)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = "找不到合约编号";
}
else
{
try
{
if (OtcAppConfigHelper.HTUpdate != 1)
{
return;
}
//处理回执
var trade = CheckTradeExist(result.RECORD.RESERVE.CONTRACT_CODE);
var HTStatus = TryFormatInt(result.RECORD.BASEINFO.ORDSTATUS);
// 衡泰状态不是成交确认或者 当前交易有平仓,不给修改,如日内平仓,或者dma部分平仓
if (HTStatus != 7)
{
return;
}
if (pushLog == null && !CheckPositionNumber(extNo))//可能平仓
{
if (long.TryParse(extNo, out long dataId))//平仓
{
pushLog = pushLogService.GetLogByDataId(dataId);
if (pushLog != null)// 我方平仓
{
extNo = pushLog.data_number;
}
}
else //衡泰平仓
{
PrepareUnwindMarginData(result.RECORD, trade);
}
}
else if (trade.UnWindDate == null)
{
PrepareMarginData(result.RECORD, trade, extNo);
}
}
catch (Exception e)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = e.Message;
LogFactory.GetLogger("SwapConsumerService").Error("消费预付金交易回执接口", e);
}
}
new PushLogService(UserInfo).SaveConsumerLog(serialNo, extNo, SwapPushDataEnum.预付金交易回执, resultState, msg, dealResult);
}
});
}
/// <summary>
/// 4.8.4. 消费合约终止交易回执接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTradeUnwindResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<RequestBase<SwapUnwindReq>>(msg);
var pushLogService = new PushLogService(UserInfo);
var serialNo = result.SERIAL_NO;
var pushLog = pushLogService.GetLogBySerialNo(serialNo, (int)SwapPushDataEnum.合约终止交易回执);
var resultState = SwapPushDataStateEnum.接收处理成功;
if (pushLog != null && pushLog.data_state == (int)resultState)
{
return;
}
string dealResult = "";
string extNo = result.EXT_NO;
try
{
//处理回执
if (result.RECORD.ACCTSWAP_TERMINATE==null)
{
return;
}
extNo = result.RECORD.ACCTSWAP_TERMINATE.CONTRACT_CODE;
var trade = CheckTradeExist(extNo);
var HTStatus = TryFormatInt(result.RECORD.ACCTSWAP_TERMINATE.ORDSTATUS);
if (HTStatus!=7)
{
return;
}
PrepareUnwindData(result.RECORD, trade);
}
catch (Exception e)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = e.Message;
LogFactory.GetLogger("SwapConsumerService").Error("消费合约终止交易回执接口", e);
}
pushLogService.SaveConsumerLog(serialNo, result.EXT_NO, SwapPushDataEnum.合约终止交易回执, resultState, msg, dealResult);
}
});
}
/// <summary>
/// 4.8.6. 消费收益互换资金流水数据回执接口
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerTradeCashResp(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<RequestBaseWithHead<SwapCashReq>>(msg);
var pushLogService = new PushLogService(UserInfo);
var serialNo = result.HEADER.SERIAL_NO;
var pushLog = pushLogService.GetLogBySerialNo(serialNo, (int)SwapPushDataEnum.收益互换资金流水数据回执);
var resultState = SwapPushDataStateEnum.接收处理成功;
if (pushLog != null && pushLog.data_state == (int)resultState)
{
return;
}
string dealResult = "";
List<int> clientIds = new List<int>();
try
{
var extNos = result.RECORD.ACCTSWAP_CASH_LIST.Where(x => !string.IsNullOrEmpty(x.EXT_NO)).Select(s => s.EXT_NO).ToList();
var trades = CheckTradeExistByList(extNos);
//处理回执
clientIds = PrepareTradeCashData(result.RECORD, trades);
}
catch (Exception e)
{
resultState = SwapPushDataStateEnum.接收处理失败;
dealResult = e.Message;
LogFactory.GetLogger("SwapConsumerService").Error("消费收益互换资金流水数据回执接口", e);
}
pushLogService.SaveConsumerLog(serialNo, "", SwapPushDataEnum.收益互换资金流水数据回执, resultState, msg, dealResult);
//if (clientIds.Count>0)
//{
// PushClientCash(clientIds, onRspAccountCapitalTopicTopic);
//}
}
});
}
public bool CheckPositionNumber(string extNo)
{
return DbContext.swap_position.Any(x => x.PosiNumber == extNo);
}
/// <summary>
/// 收盘 收益互换回执查衡泰库返回
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerIRSDb(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<IRDbRespBase>(msg);
var respMappers = GetHTDbRespMapperData<ReqQryIRSDbResp>(result);
}
});
}
/// <summary>
/// 客户资金推送
/// </summary>
/// <param name="_kafkaConsumer"></param>
public void ConsumerCashNotice(KafkaConsumerHelper _kafkaConsumer)
{
_kafkaConsumer.Subscribe(msg =>
{
if (!string.IsNullOrEmpty(msg))
{
var result = JsonHelper.Deserialize<CashNoticeReq>(msg);
if (result!=null)
{
PushCashToHT(result.cashId, null);
}
}
});
}
/// <summary>
/// 对返回数据库数据进行映射
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="iRDbResp"></param>
/// <returns></returns>
private List<T> GetHTDbRespMapperData<T>(IRDbRespBase iRDbResp) where T : new()
{
List<T> values = new List<T>();
string[] fields = iRDbResp.Header.Split(',');
var records = iRDbResp.Records;
for (int j = 0; j < records.Count; j++)
{
string[] recordFields = records[j].Split(',');
T iRSDb = Activator.CreateInstance<T>();
for (int i = 0; i < fields.Length; i++)
{
string fieldName = fields[i];
string fieldValue = recordFields[i];
typeof(T).GetProperty(fieldName)?.SetValue(iRSDb, fieldValue);
values.Add(iRSDb);
}
}
return values;
}
#region 交易回执相关私有方法
/// <summary>
/// 修改交易
/// </summary>
/// <param name="swapTradeReq"></param>
private void DealUpdateConsumerTrade(SwapTradeReq swapTradeReq, trade trade)
{
var HTStatus = trade.HTStatus;
if (OtcAppConfigHelper.HTUpdate != 1)
{
return;
}
//0新建、-4交易执行中、-3风险预审中、7成交确认、9交易撤单、1审批中、5审批通过、4审批拒绝、10交易终止
if (HTStatus == 9)
{
new SwapTradeService(UserInfo).deleteTrade(trade.id, false);
return;
}
// 衡泰状态不是成交确认或者 当前交易有平仓,不给修改,如日内平仓,或者dma部分平仓
if (trade.UnWindDate!=null)
{
throw new Exception($"交易{trade.TradeNumber}已经产生平仓信息,不支持再修改");
}
ValidateTrade(swapTradeReq, trade);
trade.trade_extend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == trade.id);
PrepareTradeData(swapTradeReq, trade, false);
if (trade.TradeStatus == ConsTrade.确认成交)
{
AfterUpdateDeal(trade, (int)SwapEventTypeEnum.修改交易, "接口修改交易");
}
}
/// <summary>
/// 互换交易数据准备
/// </summary>
/// <param name="swapTradeReq"></param>
/// <param name="trade"></param>
private void PrepareTradeData(SwapTradeReq swapTradeReq, trade trade, bool isAdd)
{
var tradeDirection = swapTradeReq.BASEINFO.TRDTYPE == "151" ? (int)SwapDirectionEnum.收取 : (int)SwapDirectionEnum.支付;
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == trade.id && x.IsInitial && !x.Invalid).ToList();
positions.ForEach(x =>
{
x.PosiStartDate = trade.StartDate.Value;
x.PosiMatuirityDate = trade.ExerciseDate.Value;
});
var interestList = positions.Where(x => ConsTrade.InterestModels.Contains(x.InterestMode)).ToList();
var posiList = positions.Where(x => x.InterestDirection == 0).ToList();
interestList.ForEach(x =>
{
x.PosiStartDate = trade.StartDate.Value;
x.PosiMatuirityDate = trade.ExerciseDate.Value;
});
var floatRateInterest = positions.FirstOrDefault(x => !string.IsNullOrEmpty(x.FloatRateUnderlyingCode));
swap_position interest;
if (interestList.Any())
{
interest = interestList[0];
}
else
{
throw new Exception($"交易{trade.TradeNumber}找不到固定端信息");
}
var rate = swapTradeReq.ACCTSWAP.REGULAR_INFO.SPREAD;
if (!string.IsNullOrEmpty(swapTradeReq.ACCTSWAP.REGULAR_INFO.RATE))
{
var rated= TryFormatDecimal(rate);
if (rated!=0)
{
rate = swapTradeReq.ACCTSWAP.REGULAR_INFO.RATE;
}
}
interest.InterestRateDefault = TryFormatDecimal(rate);
interest.InterestDirection = tradeDirection;
if (!string.IsNullOrEmpty(swapTradeReq.ACCTSWAP.IR_I_CODE))
{
interest.FloatRateUnderlyingCode = swapTradeReq.ACCTSWAP.IR_I_CODE;
interest.IsAnnualized = true;
}
else
{
interest.IsAnnualized = interest.InterestRateDefault != 0;
}
interest.InterestType = swapTradeReq.ACCTSWAP.FLOAT_METHOD == "0" ? (int)InterestTypeEnum.单利 : (int)InterestTypeEnum.复利;
if (trade.trade_extend != null)
{
var calcMode = GetInterestRule(swapTradeReq.ACCTSWAP.FIXED_INTEREST_RULE);
TradeExtendJson tradeExtendJson = trade.trade_extend.ExtendObj;
tradeExtendJson.InterestCalcMode = calcMode;
trade.trade_extend.ExtendJson = JsonHelper.Serialize(tradeExtendJson);
if (isAdd)
{
DbContext.trade_extend.Add(trade.trade_extend);
}
}
var rateDate = TryFormatDate(swapTradeReq.ACCTSWAP.REGULAR_INFO.INTEREST_END_DAY);
IntervalModel intervalModel = new IntervalModel()
{
Date = rateDate,
Rate = interest.InterestRateDefault,
Settlement = 0
};
List<IntervalModel> intervalModels = new List<IntervalModel>
{
intervalModel
};
interest.InterestSwapInterval = JsonHelper.Serialize(intervalModels);
if (interest.id == 0)
{
DbContext.swap_position.Add(interest);
}
DbContext.SaveChanges();
var observation = DbContext.trade_obervation.FirstOrDefault(x => x.PositionId == interest.id);
if (observation == null)
{
observation = new TradeObervation()
{
PositionId = interest.id,
IsDeductPrincipal = true,
ObservationAlignEnd = true,
ObservationNum = 1,
ObservationUnit = "D",
ObservationHolidayType = "Following",
ObservationStart = trade.TradeDate
};
}
observation.ObservationInterval = interest.InterestSwapInterval;
if (observation.id == 0)
{
DbContext.trade_obervation.Add(observation);
}
DbContext.SaveChanges();
}
/// <summary>
/// 校验交易信息
/// </summary>
/// <param name="swapTradeReq"></param>
/// <param name="td"></param>
/// <exception cref="ServiceException"></exception>
private Client ValidateTrade(SwapTradeReq swapTradeReq, trade td)
{
//CheckTradeStatus(td);
if (string.IsNullOrEmpty(swapTradeReq.BASEINFO.PARTY_NAME))
{
throw new ServiceException($"参数PARTY_NAME为空");
}
Client client = null;
string partyNo = string.Empty;
client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.Name == swapTradeReq.BASEINFO.PARTY_NAME);
partyNo = swapTradeReq.BASEINFO.PARTY_NAME;
if (client == null)
{
throw new ServiceException($"交易对手方{partyNo}信息不存在");
}
td.ClientId = client.id;
td.ClientName = client.Name;
td.ClientNumber = client.Number;
var orddDate = TryFormatDate(swapTradeReq.BASEINFO.ORDDATE);
var endDate = TryFormatDate(swapTradeReq.ACCTSWAP.END_DAY);
var stockNotional = TryFormatDouble(swapTradeReq.ACCTSWAP.PRINCIPAL);
td.TradeDate = orddDate.Date;
td.ExerciseDate = endDate.Date;
td.OriginalStockEqvNotional = stockNotional;
td.StockEqvNotional = td.OriginalStockEqvNotional.Value;
return client;
}
/// <summary>
/// 创建交易
/// </summary>
/// <returns></returns>
private trade CreateTrade(SwapTradeReq swapTradeReq)
{
TradeExtendJson tradeExtendJson = new TradeExtendJson()
{
FlowBookMode = (int)FlowBookModeEnum.重置,
FloatingPnlAnnualized = false,
NeedOpenFee = false,
OpenFeeType = 0,
Direction = 2,
};
var r = new trade()
{
TradeType = "收益互换",
BuySell = "卖出",
UnderlyingInstrumentType = "Stock",
StartDate = valuedateBLL.ValueDate,
TradeDate = valuedateBLL.ValueDate,
TraderId = UserId,
TraderName = UserName,
MarginTemplateName = "系统默认",
OpponentRole = "乙方",
OriginalStockEqvNotional = 0,
StructureType = "普通债券类收益互换",
InitialMargin = 0,
TradeStatus = "确认成交"
};
r.ExerciseDate = r.TradeDate.Value.AddDays(7);
r.trade_extend = new trade_extend()
{
ExtendJson = JsonHelper.Serialize(tradeExtendJson)
};
//山证衡泰互换簿记
var client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.Name == swapTradeReq.BASEINFO.PARTY_NAME);
if (client == null)
{
throw new ServiceException($"找不到名称为{swapTradeReq.BASEINFO.PARTY_NAME}的交易对手方");
}
var etradeRule = new EtradingRuleService(UserInfo).GetEtradingRuleAccont(client.BoundSide, client.Number);
if (etradeRule == null || string.IsNullOrEmpty(etradeRule.AssetAccount_0))
{
throw new ServiceException($"{client.Number}未设置TRS对客簿记账户");
}
string clearingAgency = etradeRule.ClearingAgency_0;
var asset = DataCacheProvider.GetAssetUnitDataSource().AsQueryable(x => x.Name == etradeRule.AssetAccount_0).FirstOrDefault();//取对客簿记账户
if (asset == null)
{
throw new ServiceException($"找不到名为{etradeRule.AssetAccount_0}的簿记账户信息");
}
if (asset.TraderIdsInt.Count == 0)
{
throw new ServiceException($"{etradeRule.AssetAccount_0}的簿记账户未设置交易员");
}
r.AssetBookName = asset.Name;
r.AssetId = asset.id;
r.TraderId = asset.TraderIdsInt.FirstOrDefault();
r.TraderName = asset.TraderNamesList.FirstOrDefault();
r.TradeOldStatus = ConsTrade.新增待确认;
r.OptId = UserId;
r.OptName = UserName;
r.OptDate = OptDate;
r.CreateDate = OptDate;
r.ValidState = ConsGlobal.Valid;
r.TradeSource = "系统交易";
r.TradeNumber = swapTradeReq.BASEINFO.EXT_NO;
return r;
}
private trade CheckTradeExist(string extNo)
{
var trade = DbContext.trade.FirstOrDefault(x => x.TradeNumber == extNo);
if (trade == null)
{
Thread.Sleep(5000);
trade = DbContext.trade.FirstOrDefault(x => x.TradeNumber == extNo);
if (trade == null)
{
throw new ServiceException($"不存在交易编号为{extNo}的交易,无法修改");
}
}
return trade;
}
/// <summary>
/// 批量校验交易是否存在
/// </summary>
/// <param name="extNos"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
private List<trade> CheckTradeExistByList(List<string> extNos)
{
List<trade> tradeList = new List<trade>();
var trades = DbContext.trade.Where(x => extNos.Contains(x.TradeNumber)).AsNoTracking();
foreach (var extNo in extNos)
{
var trade = trades.FirstOrDefault();
//if (trade==null)
//{
// throw new ServiceException($"交易编号为{extNo}的交易不存在");
//}
if (trade != null)
{
tradeList.Add(trade);
}
}
return tradeList;
}
/// <summary>
/// 校验交易状态
/// </summary>
/// <param name="trade"></param>
/// <exception cref="ServiceException"></exception>
private void CheckTradeStatus(trade trade)
{
if (trade.UnWindDate.HasValue)
{
throw new ServiceException($"交易已经产生平仓或收益结算,无法修改");
}
}
/// <summary>
/// 保存交易后需要做的处理
/// </summary>
/// <param name="td"></param>
/// <param name="eventType"></param>
/// <param name="msg"></param>
private void AfterUpdateDeal(trade td, int eventType, string msg)
{
SwapTradeService swapTradeService = new SwapTradeService(this);
swapTradeService.ClearSwapPositions(td);
DbContext.SaveChanges();
swapTradeService.InitialPosition(td, true);
swapTradeService.AddPositionEvent(td,"衡泰同步");
DbContext.SaveChanges();
//new SwapEodPositionService(this).InitSaveEodSwapPosition(td);
var swapEventService = new SwapEventService(this);
swapEventService.AddSwapEventDate(td.TradeDate.Value, td.id, eventType, "", 0, true, msg + "确认");
swapEventService.AddSwapEventDate(td.TradeDate.Value, td.id, (int)SwapEventTypeEnum.确认交易, "", 0, true, msg + "确认");
}
private void DeleteSwapEvent(int tradeId)
{
new SwapEventService(this).DeleteEvent(tradeId);
}
/// <summary>
/// 添加交易元数据
/// </summary>
private void AddTradeMeta(bool saveChanges, int tradeId, string metaKey, string metaValue)
{
DbContext.TradeMeta.Add(new TradeMeta
{
TradeId = tradeId,
MetaKey = metaKey,
MetaValue = metaValue,
CreateTime = DateTime.Now
});
if (saveChanges)
{
DbContext.SaveChanges();
}
}
#endregion
#region 互换资产回执相关私有方法
private void PreparePosiData(SwapPosiReq swapPosiReq, trade td, string extNo)
{
var underlying = CheckUnderlying(swapPosiReq.TRADEINFO.I_CODE, swapPosiReq.TRADEINFO.MARKET);
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == td.id && x.PosiDirection > 0 && !x.Invalid).ToList();
var position = positions.Where(x => x.PosiNumber == extNo && x.IsInitial).FirstOrDefault();
var realPosition = positions.Where(x => x.PosiNumber == extNo && !x.IsInitial).FirstOrDefault();
if (position == null)
{
throw new Exception($"交易{td.TradeNumber}找不到持仓信息");
}
decimal price = Convert.ToDecimal(underlying.Price ?? 100);
bool init = swapPosiReq.TRADEINFO.OCFLAG == "0";
if (swapPosiReq.TRADEINFO.OCFLAG == "0")
{
position.UnderlyingCode= underlying.UnderlyingCode;
position.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType;
position.PositionType = swapPosiReq.BASEINFO.TRDTYPE == "10" ? (int)PositionTypeFlag.Long : (int)PositionTypeFlag.Short;
position.PosiQuantity = TryFormatDecimal(swapPosiReq.TRADEINFO.PARVALUE);
position.PosiGrossPrice = TryFormatDecimal(swapPosiReq.TRADEINFO.ORDPRICE) / price;
int tradeSide = position.PositionType == (int)EnumDirection.Long ? 1 : -1;
position.PosiNetPrice = position.PosiQuantity == 0 ? position.PosiGrossPrice : position.PosiGrossPrice + position.PosiTradingFee * tradeSide / position.PosiQuantity;
td.OriginalNotional = Convert.ToDouble(position.PosiQuantity);
td.Notional = td.OriginalNotional ?? 0;
td.UnderlyingCode = underlying.UnderlyingCode;
td.UnderlyingAssetName = underlying.UnderlyingInstrumentTypeCn;
td.UnderlyingName = underlying.UnderlyingName;
td.SpotPrice = Convert.ToDouble(position.PosiNetPrice);
td.TradePrice = Convert.ToDouble(position.PosiTradingFee);
td.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType;
position.PosiNotionalValue = position.PosiQuantity * position.ContractSize;
if (realPosition!=null)
{
realPosition.UnderlyingCode = underlying.UnderlyingCode;
realPosition.UnderlyingInstrumentType= underlying.UnderlyingInstrumentType;
realPosition.PositionType = position.PositionType;
realPosition.PosiQuantity= position.PosiQuantity;
realPosition.PosiGrossPrice = position.PosiGrossPrice;
realPosition.PosiNetPrice = position.PosiNetPrice;
realPosition.PosiNotionalValue = position.PosiNotionalValue;
}
var flowEvent = DbContext.swap_flow_event.FirstOrDefault(x => x.PositionId == position.id &&x.EventType==(int)SwapFlowEventTypeEnum.开仓 && x.DataState == (int)SwapFlowDateStateEnum.完成);
if (flowEvent!=null)
{
flowEvent.PositionQty = position.PosiQuantity;
flowEvent.UnderlyingCode = position.UnderlyingCode;
flowEvent.UnderlyingInstrumentType= position.UnderlyingInstrumentType;
flowEvent.PositionType= position.PositionType;
flowEvent.Quantity= position.PosiQuantity;
flowEvent.TradingAmount= position.PosiNotionalValue;
}
DbContext.SaveChanges();
}
}
/// <summary>
/// 修改衡泰平仓明细价格
/// </summary>
/// <param name="price"></param>
/// <param name="td"></param>
/// <param name="valueDate"></param>
private string DealUnwindPosiEvent(decimal price,trade td,DateTime valueDate)
{
var posi = DbContext.swap_position.Where(x=>!x.Invalid&&x.IsInitial&&x.PosiDirection>0).FirstOrDefault();
if (posi==null)
{
throw new Exception("找不到资产端信息");
}
var flowEvent = GetSwapFlowEvent(posi.id,valueDate);
if (flowEvent==null)
{
throw new Exception("找不到资产端平仓事件明细信息");
}
flowEvent.TradingAmountAvg = price;
int tradeSide = posi.PositionType == (int)EnumDirection.Long ? 1 : -1;
flowEvent.TradingAmountFeeAvg = flowEvent.Quantity == 0 ? flowEvent.TradingAmountAvg : flowEvent.TradingAmountAvg + flowEvent.TradingFeePending * tradeSide / flowEvent.Quantity;
flowEvent.TradingAmountNetFeeAvg = flowEvent.Quantity == 0 ? flowEvent.TradingAmountNetAvg : flowEvent.TradingAmountNetAvg + flowEvent.TradingFeePending * tradeSide / flowEvent.Quantity;
DbContext.SaveChanges();
return "";
}
/// <summary>
/// 获取平仓明细
/// </summary>
/// <param name="posiId"></param>
/// <param name="valueDate"></param>
/// <param name="attempts"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private swap_flow_event GetSwapFlowEvent(long posiId,DateTime valueDate,int attempts=0)
{
var flowEvent = DbContext.swap_flow_event.FirstOrDefault(x=>x.PositionId== posiId&&x.EventDate==valueDate&&x.EventReason== "接口合约终止交易"&&x.DataState==(int)SwapFlowDateStateEnum.完成);
if (flowEvent==null)
{
attempts++;
if (attempts>10)
{
return null;
}
Thread.Sleep(1000* attempts);
return GetSwapFlowEvent(posiId, valueDate, attempts);
}
else
{
return flowEvent;
}
}
/// <summary>
/// 接入对冲标的
/// </summary>
/// <param name="swapPosiReq"></param>
private void PrepareExchangeTradeData(SwapPosiReq swapPosiReq,string tradeSource)
{
var underlying = CheckUnderlying(swapPosiReq.TRADEINFO.I_CODE, swapPosiReq.TRADEINFO.MARKET);
var orddDate = TryFormatDate(swapPosiReq.BASEINFO.ORDDATE);
var longType = swapPosiReq.BASEINFO.TRDTYPE == "10" ? "多头" : "空头";
var openType = swapPosiReq.TRADEINFO.OCFLAG == "0" ? "开仓" : "平仓";
if (string.IsNullOrEmpty(swapPosiReq.BASEINFO.TRD_RELATED_NO) || !double.TryParse(swapPosiReq.TRADEINFO.PARVALUE, out _) || !double.TryParse(swapPosiReq.TRADEINFO.ORDPRICE, out _))
{
logger.Error("同步场内交易失败,数据格式不正确:" + JsonHelper.Serialize(swapPosiReq));
return;
}
ExchangeTradeSaveApiReq req = new ExchangeTradeSaveApiReq
{
ExchangeAccountCode = swapPosiReq.BASEINFO.SECU_INT,
BuySell = longType + openType,
Commission = 0,
IsHistory = orddDate.Date < valuedateBLL.ValueDate ? true : false,
Lots = double.Parse(swapPosiReq.TRADEINFO.PARVALUE) / underlying.ContractSize,
TradeDate = orddDate.Date,
TradeNumber = swapPosiReq.BASEINFO.TRD_RELATED_NO,
TradePrice = double.Parse(swapPosiReq.TRADEINFO.ORDPRICE) / (underlying.Price ?? 100),
TradeType = underlying.UnderlyingInstrumentTypeCn,
UnderlyingCode = underlying.UnderlyingCode
};
var service = new ExchangeTradeSyncApiService(UserInfo);
service.Save(req, tradeSource);
}
/// <summary>
/// 接入对冲标的
/// </summary>
/// <param name="swapPosiReq"></param>
private void PrepareExchangeTradeData(SwapAsset swapPosiReq,string tradeSource)
{
var underlying = CheckUnderlying(swapPosiReq.I_CODE, swapPosiReq.MARKET);
var orddDate = TryFormatDate(swapPosiReq.ORD_DATE);
var longType = swapPosiReq.TRD_TYPE == "10" ? "多头" : "空头";
var openType = swapPosiReq.OC_FLAG == "0" ? "开仓" : "平仓";
if (string.IsNullOrEmpty(swapPosiReq.EXT_NO) || !double.TryParse(swapPosiReq.PAR_VALUE, out _) || !double.TryParse(swapPosiReq.ORD_PRICE, out _))
{
logger.Error("同步场内交易失败,数据格式不正确:" + JsonHelper.Serialize(swapPosiReq));
return;
}
ExchangeTradeSaveApiReq req = new ExchangeTradeSaveApiReq
{
ExchangeAccountCode = swapPosiReq.SECU_INT,
BuySell = longType + openType,
Commission = 0,
IsHistory = orddDate.Date < valuedateBLL.ValueDate ? true : false,
Lots = double.Parse(swapPosiReq.PAR_VALUE) / underlying.ContractSize,
TradeDate = orddDate.Date,
TradeNumber = swapPosiReq.EXT_NO,
TradePrice = double.Parse(swapPosiReq.ORD_PRICE) / (underlying.Price ?? 100),
TradeType = underlying.UnderlyingInstrumentTypeCn,
UnderlyingCode = underlying.UnderlyingCode
};
var service = new ExchangeTradeSyncApiService(UserInfo);
service.Save(req, tradeSource);
}
#endregion
#region 预付金交易回执相关私有方法
private void PrepareMarginData(SwapMarginReq swapMarginReq, trade td, string extNo)
{
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == td.id && x.PosiNumber == extNo).ToList();
var position = positions.FirstOrDefault(x => x.IsInitial);
var realPosition = positions.FirstOrDefault(x => !x.IsInitial);
if (position == null)
{
throw new Exception($"找不到持仓编码{extNo}的信息");
}
var marginDirection = swapMarginReq.BASEINFO.TRDTYPE == "128" ? (int)SwapDirectionEnum.收取 : (int)SwapDirectionEnum.支付;
position.InterestDirection = marginDirection;
position.InterestPrincipalFix = TryFormatDecimal(swapMarginReq.TRADEINFO.PARVALUE);
position.InterestRateDefault = TryFormatDecimal(swapMarginReq.RESERVE.RATE);
position.IsAnnualized = position.InterestRateDefault != 0;
position.Currency = swapMarginReq.RESERVE.CURRENCY;
IntervalModel intervalModel = new IntervalModel()
{
Date = td.ExerciseDate.Value,
Rate = position.InterestRateDefault,
Settlement = 0
};
List<IntervalModel> intervalModels = new List<IntervalModel>
{
intervalModel
};
var marginDateStr = swapMarginReq.BASEINFO.ORDDATE;
if (!string.IsNullOrEmpty(swapMarginReq.BASEINFO.SETDATE))
{
marginDateStr = swapMarginReq.BASEINFO.SETDATE;
}
var marginDate = TryFormatDate(marginDateStr);
position.HappenDate=marginDate;
position.InterestSwapInterval = JsonHelper.Serialize(intervalModels);
var observation = DbContext.trade_obervation.FirstOrDefault(x => x.PositionId == position.id);
if (observation == null)
{
observation = new TradeObervation()
{
PositionId = position.id,
IsDeductPrincipal = true,
ObservationAlignEnd = true,
ObservationNum = 1,
ObservationUnit = "D",
ObservationHolidayType = "Following",
ObservationStart = td.TradeDate
};
}
observation.ObservationInterval = position.InterestSwapInterval;
if (observation.id == 0)
{
DbContext.trade_obervation.Add(observation);
}
if (realPosition!=null)
{
realPosition.InterestDirection = position.InterestDirection;
realPosition.InterestPrincipalFix = position.InterestPrincipalFix;
realPosition.InterestRateDefault = position.InterestRateDefault;
realPosition.InterestSwapInterval = position.InterestSwapInterval;
realPosition.HappenDate = position.HappenDate;
realPosition.IsAnnualized = position.IsAnnualized;
realPosition.Currency = realPosition.Currency;
}
var flowEvent = DbContext.swap_flow_event.FirstOrDefault(x => x.PositionId == position.id && x.EventType == (int)SwapFlowEventTypeEnum.开仓&&x.DataState==(int)SwapFlowDateStateEnum.完成);
if (flowEvent != null)
{
flowEvent.InterestDirection = position.InterestDirection;
flowEvent.InterestPrincipal = position.InterestPrincipalFix;
flowEvent.InterestRate = position.InterestRateDefault;
flowEvent.InterestSwapInterval = position.InterestSwapInterval;
}
DbContext.SaveChanges();
// AfterUpdateDeal(td, (int)SwapEventTypeEnum.修改交易, $"接口预付金{msg}交易", true);
AddMarginCash(position, td);
}
private void PrepareUnwindMarginData(SwapMarginReq swapMarginReq, trade td)
{
var posi = DbContext.swap_position.Where(x => !x.Invalid && x.IsInitial && ConsTrade.InterestMarginModels.Contains(x.InterestMode)).FirstOrDefault();
if (posi == null)
{
throw new Exception($"{td.TradeNumber}找不到持仓信息");
}
var marginDate = TryFormatDate(swapMarginReq.BASEINFO.ORDDATE);
var flowEvent = GetSwapFlowEvent(posi.id, marginDate);
if (flowEvent == null)
{
throw new Exception($"{posi.PosiNumber}找不到平仓事件");
}
var swapEvent = DbContext.swap_event.Where(x=>x.id==flowEvent.EventId).FirstOrDefault();
if (swapEvent==null|| string.IsNullOrEmpty(swapEvent.EventData))
{
throw new Exception($"{td.TradeNumber}找不到平仓事件");
}
swapEvent.unwindData = JsonConvert.DeserializeObject<UnwindData>(swapEvent.EventData);
decimal unwindMarginMoney = 0;
unwindMarginMoney = TryFormatDecimal(swapMarginReq.TRADEINFO.PARVALUE);
var interestAmount = TryFormatDecimal(swapMarginReq.TRADEINFO.INTEREST_AMOUNT);
var currentMarginMoney = posi.InterestPrincipalFix;
var origamount = currentMarginMoney * swapEvent.unwindData.ClosePercent;
var difMarginMoney = currentMarginMoney- (unwindMarginMoney> origamount? unwindMarginMoney: origamount);
posi.InterestPrincipalFix = difMarginMoney;
flowEvent.InterestPrincipal = unwindMarginMoney;
flowEvent.TdInterestAmount = interestAmount;
flowEvent.InterestAmount = interestAmount;
flowEvent.InterestClosePnL = interestAmount;
DbContext.SaveChanges();
UpdateUnwindMarginCash(posi, td, -unwindMarginMoney, marginDate, ClientCashInCashOut.系统操作_应付预付金);
new SwapTradeBaseService(this).AddClientCashInCashOut(td, Convert.ToDouble(-interestAmount), ClientCashInCashOut.系统操作_预付金返息, marginDate);
}
/// <summary>
/// 添加预付金资金记录
/// </summary>
/// <param name="marginPosition"></param>
/// <param name="td"></param>
private void AddMarginCash(swap_position marginPosition, trade td)
{
var cashService = new ClientCashInCashOutService(this);
var marginAmount = marginPosition.InterestPrincipalFix * (marginPosition.InterestDirection == 1 ? -1 : 1);
cashService.SaveSwapTradeClientCash(td, Convert.ToDouble(marginAmount), marginPosition.HappenDate.HasValue ? marginPosition.HappenDate.Value : td.TradeDate.Value, marginPosition.id, ClientCashInCashOut.系统操作_应付预付金);
}
/// <summary>
/// 修改预付金返息记录
/// </summary>
/// <param name="marginPosition"></param>
/// <param name="td"></param>
/// <param name="marginAmount"></param>
/// <param name="marginDate"></param>
private void UpdateUnwindMarginCash(swap_position marginPosition, trade td, decimal marginAmount, DateTime marginDate,string actionName)
{
var cashService = new ClientCashInCashOutService(this);
cashService.SaveSwapTradeClientCash(td, Convert.ToDouble(marginAmount), marginDate, marginPosition.id, actionName);
}
#endregion
#region 合约终止回执相关私有方法
private void PrepareUnwindData(SwapUnwindReq swapUnwindReq, trade td)
{
var eventIdStr = swapUnwindReq.ACCTSWAP_TERMINATE.EXT_NO;
bool allClose = swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_TYPE == "1";
var closeQty = TryFormatDecimal(swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_COUNT);
var unwindDate = TryFormatDate(swapUnwindReq.ACCTSWAP_TERMINATE.TERMINATE_DAY).Date;
var payDate = TryFormatDate(swapUnwindReq.ACCTSWAP_TERMINATE.PAY_DAY).Date;
var markClosePnl = TryFormatDecimal(swapUnwindReq.ACCTSWAP_TERMINATE.ZCD_AMOUNT);
var interestAmount= TryFormatDecimal(swapUnwindReq.ACCTSWAP_TERMINATE.GDD_AMOUNT);
var tradeinfFee = TryFormatDecimal(swapUnwindReq.ACCTSWAP_TERMINATE.ASSET_FEE);
var fixFee = TryFormatDecimal(swapUnwindReq.ACCTSWAP_TERMINATE.FIX_FEE);
interestAmount -= fixFee;
markClosePnl += tradeinfFee;
swap_event swapEvent;
if (!long.TryParse(eventIdStr, out long eventId))//不识别,为衡泰新增的平仓信息
{
swapEvent = null;
}
else
{
swapEvent = DbContext.swap_event.FirstOrDefault(x => x.id == eventId);
}
// 先不支持衡泰修改平仓信息
if (swapEvent == null&& OtcAppConfigHelper.HTUpdate == 1&&td.TradeStatus!= ConsTrade.已平仓)
{
new SwapDealService(this).AutoSwapUnwindFromConsumer(td, unwindDate, payDate, markClosePnl, tradeinfFee, interestAmount, fixFee, closeQty, allClose);
}
}
#endregion
#region 互换资金流水回执相关私有方法
private List<int> PrepareTradeCashData(SwapCashReq swapCashReq, List<trade> trades)
{
var tradenumbers = trades.Select(s => s.TradeNumber).ToList();
List<int> clientIds = new List<int>();
foreach (var cashItem in swapCashReq.ACCTSWAP_CASH_LIST)
{
var money = cashItem.CASH_AMOUNT;
var backCard = cashItem.BANK_ACC_CODE;
var bankCardInfo = new ClientBankCardService(UserInfo).GetBankCardByBankCode(backCard);
if (bankCardInfo == null)
{
throw new ServiceException("根据银行卡信息找不到对应客户");
}
var trade = trades.FirstOrDefault(x => x.TradeNumber == cashItem.EXT_NO);
var client = DataCacheProvider.GetClientDataSource().GetData(bankCardInfo.ClientId ?? 0);
var cash = new ClientCashInCashOut();
cash.ClientId = bankCardInfo.ClientId;
cash.ClientName = client?.Name;
cash.ClientNumber = client?.Number;
cash.Direction = money > 0 ? "入金" : "出金";
cash.Money = Math.Abs(money);
cash.TradeId = trade?.id;
cash.TradeNumber = trade?.TradeNumber;
cash.HappenDate = TryFormatDate(cashItem.SETDATE_REAL).Date;
cash.OptDate = TryFormatDate(cashItem.SETDATE);
cash.CurrencyCode = "CNY";
cash.Number = UniqueTimeId.GetStr();
cash.State = "未确认";
cash.SetOpt(UserInfo);
cash.Comments = "互换资金流水回执";
cash.OpenBankCard = backCard;
cash.OpenBankId = bankCardInfo?.id;
DbContext.ClientCashInCashOut.Add(cash);
if (client?.SwapTradeType == 1)
{
clientIds.Add(cash.ClientId ?? 0);
}
}
DbContext.SaveChanges();
return clientIds.Distinct().ToList();
}
/// <summary>
/// 推送客户资金信息到客户端
/// </summary>
/// <param name="clientIds"></param>
/// <param name="onRspAccountCapitalTopicTopic"></param>
private void PushClientCash(List<int> clientIds, string onRspAccountCapitalTopicTopic)
{
try
{
var clientSettles = new RealTimeClientBanlanceService(new OptUserInfo(0, "实时客户资金服务", OptUserFrom.Service)).GetBanlances(clientIds, valuedateBLL.ValueDate);
foreach (var cb in clientSettles)
{
Result result = new Result();
try
{
var obj = new ClientBalanceForTrsResponse
{
TotalAmountTotal = cb.RoundedTotalAmountTotal,
AvailableAmount = Math.Round(cb.AvailableAmount, 2),
PositionPv = cb.RoundedPositionPv,
PositionPnl = cb.RoundedPositionPnl,
DaliyPnl = Math.Round(cb.DaliyPnl, 2),
ClientId = cb.ClientId,
ClientType = cb.ClientType,
Credit = cb.TotalCredit
};
result.success = true;
result.obj = obj;
}
catch (Exception ex)
{
result.msg = ex.Message;
result.success = false;
}
kafkaProduceHelper.Produce(onRspAccountCapitalTopicTopic, JsonConvert.SerializeObject(result));
}
}
catch (Exception ex)
{
}
}
#endregion
#region 出入金相关私有方法
public void PushCashToHT(int cashId, PushLog pushLog)
{
//var cash= DbContext.ClientCashInCashOut.FirstOrDefault(x=>x.id==cashId);
// if (cash==null)
// {
// return;
// }
// var req = new RequestBase<SwapMarginReq>();
// var pushService = new PushLogService(UserInfo);
// var enumType = cash.Direction=="出金"? SwapPushDataEnum.客户出金新增: SwapPushDataEnum.客户入金新增;
// if (pushLog==null)
// {
// pushLog = pushService.AddLog(cashId, enumType, cash.Number);
// }
// req.RECORD = PrepareTradeMarginReq(cash);
// if (req.RECORD == null)
// {
// return;
// }
// req.EXT_NO = cash.Number;
// req.SERIAL_NO = pushLog.id.ToString();
// req.ACTION = "2043";
// var data_req = JsonHelper.Serialize(req);
// pushService.UpdateLogReq(pushLog.id, data_req);
// kafkaProduceHelper.Produce(reqMarginInsert, data_req);
}
/// <summary>
/// 互换预付金请求数据组装
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private SwapMarginReq PrepareTradeMarginReq(ClientCashInCashOut model)
{
SwapMarginReq swapMarginReq = new SwapMarginReq();
var etradeAccount = DbContext.etrade_account.FirstOrDefault();
#region BASEINFO
swapMarginReq.BASEINFO.ORDDATE = model.HappenDate.Value.ToString("yyyy-MM-dd");
swapMarginReq.BASEINFO.SETDATE = swapMarginReq.BASEINFO.ORDDATE;
swapMarginReq.BASEINFO.PARTY_NAME = model.ClientName;
swapMarginReq.BASEINFO.ORDSTATUS = "1";
swapMarginReq.BASEINFO.TRDTYPE = model.Direction == "入金" ? "128" : "127";
swapMarginReq.BASEINFO.TRADER_ID = etradeAccount?.trader_account;
swapMarginReq.BASEINFO.SECU_INT = etradeAccount?.balance_account_trade;
#endregion
#region TRADEINFO
swapMarginReq.TRADEINFO.PARVALUE = model.Money.OtcFormatMoney(false, 4);
#endregion
return swapMarginReq;
}
#endregion
/// <summary>
/// 校验标的信息
/// </summary>
/// <param name="underlyingCode"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
private underlying_manager CheckUnderlying(string underlyingCode, string market)
{
var underlying = DbContext.underlying_manager.FirstOrDefault(x => x.UnderlyingCode.StartsWith(underlyingCode + ".") && x.MarketCode == market);
if (underlying == null)
{
throw new ServiceException($"标的代码{underlyingCode}不存在");
}
return underlying;
}
private DateTime TryFormatDate(string val)
{
if (!DateTime.TryParse(val, out DateTime formatDate))
{
throw new ServiceException($"参数{val}不是正确的日期格式");
}
return formatDate;
}
private double TryFormatDouble(string val)
{
if (!double.TryParse(val, out double doubleVal))
{
throw new ServiceException($"参数{val}不是数字");
}
return doubleVal;
}
private decimal TryFormatDecimal(string val)
{
if (!decimal.TryParse(val, out decimal decimalVal))
{
throw new ServiceException($"参数{val}不是数字");
}
return decimalVal;
}
private int TryFormatInt(string val)
{
if (!int.TryParse(val, out int intVal))
{
throw new ServiceException($"参数{val}不是数字");
}
return intVal;
}
private string GetInterestRule(string interestRule)
{
switch (interestRule)
{
case "1":
return "01";
case "2":
return "11";
default:
return "10";
}
}
private string GetTradeStatus(string orderStatus)
{
switch (orderStatus)
{
//0新建、-4交易执行中、-3风险预审中、7成交确认、9交易撤单、1审批中、5审批通过、4审批拒绝、10交易终止
case "0":
return ConsTrade.新增待确认;
case "1":
return ConsTrade.审批中;
case "4":
case "9"://撤单
return "";
case "10":
return ConsTrade.已平仓;
default:
return ConsTrade.确认成交;
}
}
}
}