168 lines
7.7 KiB
C#
168 lines
7.7 KiB
C#
using BaseOUDAL;
|
|
using YLErp.BLL;
|
|
using YLErp.BLL.Eod;
|
|
using YLErp.Model;
|
|
using YLErp.Modules.DataProviderModule;
|
|
|
|
namespace YLErp.Modules.RiskModule
|
|
{
|
|
public class HedgingMonitorService : YLBaseService
|
|
{
|
|
public HedgingMonitorService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
public HedgingMonitorService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
}
|
|
|
|
public HedgingMonitorService(OptUserInfo optUser, YLContext dbContext) : base(optUser, dbContext)
|
|
{
|
|
}
|
|
|
|
public SearchHedgingMonitorResult Query(HedgingMonitorReq req)
|
|
{
|
|
var umCodesQuery = DbContext.underlying_manager.AsQueryable();
|
|
if (req.VarietyIds != null)
|
|
{
|
|
umCodesQuery = umCodesQuery.Where(O => req.VarietyIds.Contains(O.UnderlyingTypeId));
|
|
}
|
|
if (req.UnderlyingIds != null)
|
|
{
|
|
umCodesQuery = umCodesQuery.Where(O => req.UnderlyingIds.Contains(O.id));
|
|
}
|
|
var lastSetDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
|
|
IQueryable<HedgingMonitor> query = null;
|
|
if (req.SettlementDate > lastSetDate)
|
|
{
|
|
var tpQuery = DbContext.TradePosition.AsQueryable();
|
|
if (req.VarietyIds != null || req.UnderlyingIds != null)
|
|
{
|
|
tpQuery = from tp in tpQuery
|
|
join um in umCodesQuery
|
|
on tp.UnderlyingCode equals um.UnderlyingCode
|
|
select tp;
|
|
}
|
|
query = from position in tpQuery
|
|
where position.Position != 0
|
|
//group position by position.UnderlyingCode into groupP
|
|
group position by position.InstrumentCode ?? position.UnderlyingCode into groupP
|
|
select new HedgingMonitor()
|
|
{
|
|
UnderlyingCode = groupP.FirstOrDefault().UnderlyingCode,
|
|
TradeCode = groupP.Key,
|
|
PositionNotional = groupP.Sum(O => O.Position),
|
|
TradeType = groupP.FirstOrDefault().TradeType
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var tpQuery = DbContext.eod_trade_position.Where(O => O.ValueDate == req.SettlementDate && ConsTrade.TradeTypesForHedge.Contains(O.TradeType));
|
|
if (req.VarietyIds != null || req.UnderlyingIds != null)
|
|
{
|
|
tpQuery = from tp in tpQuery
|
|
join um in umCodesQuery
|
|
on tp.UnderlyingCode equals um.UnderlyingCode
|
|
select tp;
|
|
}
|
|
query = from position in tpQuery
|
|
where position.Amount != 0
|
|
//group position by position.UnderlyingCode into groupP
|
|
group position by position.ExchangeOptionCode ?? position.UnderlyingCode into groupP
|
|
select new HedgingMonitor()
|
|
{
|
|
UnderlyingCode = groupP.FirstOrDefault().UnderlyingCode,
|
|
TradeCode = groupP.Key,
|
|
PositionNotional = groupP.Sum(O => O.Amount),
|
|
TradeType = groupP.FirstOrDefault().TradeType
|
|
};
|
|
}
|
|
|
|
var temp = query.ToSearchList(req);
|
|
var codes = temp.rows.Select(O => O.UnderlyingCode);
|
|
|
|
var DealQuery = (from trade in DbContext.ExchangeTrade
|
|
where trade.TradeDate == req.SettlementDate && codes.Contains(trade.UnderlyingCode)
|
|
select new
|
|
{
|
|
UnderlyingCode = trade.OptionCode ?? trade.UnderlyingCode,
|
|
trade.TradeSide,
|
|
trade.Notional,
|
|
trade.TradeSinglePrice
|
|
}).ToArray();
|
|
ExchangeOptionPriceProvider exchangePrice = null;
|
|
|
|
var buySides = new[] { "买入", "多头开仓", "空头平仓" };
|
|
foreach (var item in temp.rows)
|
|
{
|
|
if (item.TradeType == "场内期权")
|
|
{
|
|
if (exchangePrice == null)
|
|
{
|
|
exchangePrice = new ExchangeOptionPriceProvider();
|
|
}
|
|
item.Price = exchangePrice.GetPrice(item.TradeCode);
|
|
}
|
|
else
|
|
{
|
|
item.Price = DataCacheProvider.GetUnderlyingDataSource().GetPrice(item.UnderlyingCode);
|
|
}
|
|
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode);
|
|
item.PositionNotional = item.PositionNotional / um.CountRatio;
|
|
item.PositionNotional = item.PositionNotional.OtcFormatValue(OtcFormatFlag.notional);
|
|
item.Pv = Commons.OtcFormatHelper.GetTradePriceDouble(item.PositionNotional * item.Price ?? 0);
|
|
var underlyings = DealQuery.Where(O => item.TradeCode == O.UnderlyingCode);
|
|
|
|
var buyUm = underlyings.Where(O => buySides.Contains(O.TradeSide));
|
|
item.BuyNotional = buyUm.Sum(O => O.Notional).OtcFormatValue(OtcFormatFlag.notional);
|
|
if (buyUm.Any())
|
|
{
|
|
item.BuyLowPrice = buyUm.Min(O => O.TradeSinglePrice).OtcFormatValue(OtcFormatFlag.umprice);
|
|
item.BuyTradePrice = buyUm.Sum(O => O.Notional * O.TradeSinglePrice);
|
|
item.BuyAvgPrice = (item.BuyTradePrice / item.BuyNotional).OtcFormatValue(OtcFormatFlag.umprice);
|
|
}
|
|
else
|
|
{
|
|
item.BuyTradePrice = double.NaN;
|
|
item.BuyLowPrice = double.NaN;
|
|
item.BuyAvgPrice = double.NaN;
|
|
}
|
|
|
|
var sellUm = underlyings.Where(O => !buySides.Contains(O.TradeSide));
|
|
item.SellNotional = sellUm.Sum(O => O.Notional);
|
|
if (sellUm.Any())
|
|
{
|
|
item.SellTradePrice = sellUm.Sum(O => O.Notional * O.TradeSinglePrice);
|
|
item.SellLowPrice = sellUm.Min(O => O.TradeSinglePrice).OtcFormatValue(OtcFormatFlag.umprice);
|
|
item.SellHighPrice = sellUm.Max(O => O.TradeSinglePrice).OtcFormatValue(OtcFormatFlag.umprice);
|
|
item.SellAvgPrice = (item.SellTradePrice / item.SellNotional).OtcFormatValue(OtcFormatFlag.umprice);
|
|
}
|
|
else
|
|
{
|
|
item.SellTradePrice = double.NaN;
|
|
item.SellLowPrice = double.NaN;
|
|
item.SellHighPrice = double.NaN;
|
|
item.SellAvgPrice = double.NaN;
|
|
}
|
|
|
|
item.TradePrice = Commons.OtcFormatHelper.GetTradePriceDouble(NumberHelper.Normalize(item.BuyTradePrice) - NumberHelper.Normalize(item.SellTradePrice));
|
|
item.MarketTradePrice = double.NaN;
|
|
item.NotionalRate = item.TradePrice / item.MarketTradePrice;
|
|
item.CountRatio = um.CountRatio;
|
|
}
|
|
|
|
var result = new SearchHedgingMonitorResult
|
|
{
|
|
Msg = temp.Msg,
|
|
page = temp.page,
|
|
records = temp.records,
|
|
rows = temp.rows,
|
|
Sum = temp.Sum,
|
|
total = temp.total
|
|
};
|
|
result.SetUserData();
|
|
return result;
|
|
}
|
|
}
|
|
}
|