Files
zszq-trs/YLErpDAL/Modules/TradeRiskCalcModule/RealTimeMarginService.cs
2024-05-09 14:06:26 +08:00

210 lines
6.9 KiB
C#

using YLErp.BLL.MarginCalculation;
namespace YLErp.Modules.TradeRiskCalcModule
{
/// <summary>
/// 实时预付金计算服务
/// </summary>
public class RealTimeMarginService : YLBaseService
{
static int _runingFlag;
static IEnumerable<RealTimeMarginResult> _results;
public RealTimeMarginService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 获取实时预付金计算结果(1分钟执行一次)
/// </summary>
public IEnumerable<RealTimeMarginResult> GetRealTimeMarginResult()
{
if (Interlocked.Increment(ref _runingFlag) == 1)
{
Task.Run(() => InnerGetRealTimeMarginResult());
}
return _results ?? Enumerable.Empty<RealTimeMarginResult>();
}
private void InnerGetRealTimeMarginResult()
{
try
{
var query = from t in DbContext.trade.AsNoTracking()
where t.ClientId > 0 && t.TradeType != "远期"&& t.TradeType != "现金流交易" && t.ValidState != "Invalid"
&& !ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus)
select t;
var tds = query.ToArray();
var results = new List<RealTimeMarginResult>(tds.Length);
foreach (var td in tds)
{
var result = new RealTimeMarginResult
{
BuySell = td.BuySell,
ClientName = td.ClientName,
ExerciseDate = td.ExerciseDate?.ToString("yyyy-MM-dd"),
SpotPrice = td.SpotPrice,
Strike = td.Strike,
TradeDate = td.TradeDate?.ToString("yyyy-MM-dd"),
TradeType = td.TradeType,
TradeNumber = td.TradeNumber,
UnderlyingCode = td.UnderlyingCode,
StockEqvNotionalReal = td.StockEqvNotionalReal
};
try
{
var countRatio = UnderlyingDataProvider.GetCountRatio(td.UnderlyingCode);
var notional = td.SpotPrice.HasValue && td.SpotPrice.Value != 0
? td.StockEqvNotionalReal / td.SpotPrice.Value : 0;
result.TradeAmount = notional / countRatio;
var PositionAmountPercent = 0d;
if (td.OriginalStockEqvNotional.HasValue && td.OriginalStockEqvNotional != 0)
{
PositionAmountPercent = td.StockEqvNotional / td.OriginalStockEqvNotional.Value;
result.PositionAmountPercent = PositionAmountPercent.ToString("P4");
}
if (td.IsUsePremiumRate == true)
{
result.PositionAmount = result.TradeAmount * PositionAmountPercent;
}
else
{
result.PositionAmount = td.TradeAmount;
}
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
if (underlying == null)
{
result.ErrorMsg = "找不到标的信息";
}
else
{
var buysell = td.BuySell;
td.BuySell = "买入";
td.VolType = "报价Bid";
//关于交易id的多义性: 1.组合交易需要真实的交易id;2.考虑到波动率不能获取持仓波动率,将id赋值为0;3.定价页面结构化交易子交易id会赋值-1和-2
var req = new GetTradeMarginReq
{
realTradeId = td.id,
trade = td,
hasOptionInfo = true,
price = (underlying.Price ?? 0)
};
result.Margin = MarginDefault.GetTradeMargin(req);
}
}
catch (Exception ex)
{
LogFactory.GetLogger("RealTimeMarginService").Error("计算实时预付金", ex);
result.ErrorMsg = ex.GetBaseException().Message;
}
results.Add(result);
}
_results = results;
}
catch (Exception ex)
{
LogFactory.GetLogger("RealTimeMarginService").Error("计算实时预付金", ex);
}
finally
{
Thread.Sleep(30 * 1000);
Interlocked.Exchange(ref _runingFlag, 0);
}
}
}
/// <summary>
/// 实时预付金数据
/// </summary>
public class RealTimeMarginResult
{
/// <summary>
/// 交易编号
/// </summary>
public string TradeNumber { get; set; }
/// <summary>
/// 交易对手方
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// 交易日期
/// </summary>
public string TradeDate { get; set; }
/// <summary>
/// 到期日期
/// </summary>
public string ExerciseDate { get; set; }
/// <summary>
/// 交易方向
/// </summary>
public string BuySell { get; set; }
/// <summary>
/// 结构类型
/// </summary>
public string TradeType { get; set; }
/// <summary>
/// 标的代码
/// </summary>
public string UnderlyingCode { get; set; }
/// <summary>
/// 期初价格
/// </summary>
public double? SpotPrice { get; set; }
/// <summary>
/// 行权价
/// </summary>
public double? Strike { get; set; }
/// <summary>
/// 交易数量
/// </summary>
public double? TradeAmount { get; set; }
/// <summary>
/// 实际名义金额
/// </summary>
public double? StockEqvNotionalReal { get; set; }
/// <summary>
/// 持仓数量
/// </summary>
public double? PositionAmount { get; set; }
/// <summary>
/// 持仓比例
/// </summary>
public string PositionAmountPercent { get; set; }
/// <summary>
/// 预付金
/// </summary>
public double Margin { get; set; }
/// <summary>
/// 计算预付金错误信息
/// </summary>
public string ErrorMsg { get; set; }
}
}