210 lines
6.9 KiB
C#
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; }
|
|
}
|
|
}
|