从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using YLErp.Modules.TradeModule.OrderModule;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace YLErp.Modules.TradeModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 场外期权交易导入测试
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class OtcTradeImportServiceTest : UnitTestBase
|
||||
{
|
||||
[TestMethod("测试场外期权雪球交易导入")]
|
||||
public void TestImportSnowBallTrade()
|
||||
{
|
||||
List<OtcOptionTradeFullEx> trades = null;
|
||||
var path = Path.Combine(AppContext.BaseDirectory, "Resources\\场外期权导入\\场外期权交易导入(雪球).xlsx");
|
||||
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
trades = new OtcTradeImportService(CurUser).ReadOptionTradesFromExcel(stream);
|
||||
}
|
||||
|
||||
var td = trades[0];
|
||||
Assert.AreEqual(td.TradeNumber, "FH0001");
|
||||
Assert.AreEqual(td.AssetBookName, "FH0001");
|
||||
Assert.AreEqual(td.TraderName, "FH0001");
|
||||
Assert.AreEqual(td.TradeType, "雪球期权");
|
||||
Assert.AreEqual(td.BuySell, "买入");
|
||||
Assert.AreEqual(td.ExerciseMode, "European");
|
||||
Assert.AreEqual(td.TradeDate, new DateTime(2020, 8, 8));
|
||||
Assert.AreEqual(td.ExerciseDate, new DateTime(2021, 2, 1));
|
||||
Assert.AreEqual(td.SettlementDate, new DateTime(2021, 2, 1));
|
||||
Assert.AreEqual(td.UnderlyingCode, "FH0001");
|
||||
Assert.AreEqual(td.SpotPrice, 888.88);
|
||||
Assert.AreEqual(td.IsMoneynessOption, "是");
|
||||
Assert.AreEqual(td.Strike, 1.01);
|
||||
|
||||
Assert.AreEqual(td.TradeSinglePrice, 55.55);
|
||||
Assert.AreEqual(td.TradePrice, 555500);
|
||||
Assert.AreEqual(td.PremiumRate, 0.07);
|
||||
Assert.AreEqual(td.Notional, 1000);
|
||||
Assert.AreEqual(td.StockEqvNotional, 800000);
|
||||
Assert.AreEqual(td.StockEqvNotionalReal, 800000);
|
||||
|
||||
Assert.AreEqual(td.IsAnnualized, false);
|
||||
Assert.AreEqual(td.AnnualizeFactor, 1);
|
||||
Assert.AreEqual(td.MetaDic[nameof(td.AnnualizeFactor)], null);
|
||||
|
||||
Assert.AreEqual(td.IsAnnualized2, true);
|
||||
Assert.AreEqual(td.AnnualizeFactor2, 33.0 / 244);
|
||||
Assert.AreEqual(td.MetaDic[nameof(td.AnnualizeFactor2)], "33/244");
|
||||
|
||||
Assert.AreEqual(td.PrincipalRate, 0.1);
|
||||
Assert.AreEqual(td.ParticipationRate, 0.9);
|
||||
Assert.AreEqual(td.DividendRate, 0.01);
|
||||
Assert.AreEqual(td.NoRiskRate, 0.02);
|
||||
Assert.AreEqual(td.TradeOpenVolatility, 0.33);
|
||||
Assert.AreEqual(td.TradeCloseVolatility, 0.23);
|
||||
Assert.AreEqual(td.NumOfSmoothingDays, 50);
|
||||
Assert.AreEqual(td.SettlementType, 0);
|
||||
|
||||
Assert.AreEqual(td.Comments, "1111");
|
||||
|
||||
Assert.AreEqual(td.KOBarrier, 1.05);
|
||||
Assert.AreEqual(td.KOPayoffType, DBModels.KOPayoffTypeEnum.Rebate);
|
||||
Assert.AreEqual(td.IsFixedCoupon, false);
|
||||
Assert.AreEqual(td.KORebate, 0.1);
|
||||
Assert.AreEqual(td.SpreadStrikeAtKO1, null);
|
||||
Assert.AreEqual(td.SpreadStrikeAtKO, null);
|
||||
Assert.AreEqual(td.AnnualizedPremiumRate, 0.01);
|
||||
Assert.AreEqual(td.KORebateType, DBModels.RebateTypeEnum.AtHit);
|
||||
|
||||
Assert.AreEqual(td.KIBarrier, 0.98);
|
||||
Assert.AreEqual(td.KIPayoffType, DBModels.KIPayoffTypeEnum.ToCallOption);
|
||||
Assert.AreEqual(td.SpreadStrike1, 0.97);
|
||||
Assert.AreEqual(td.SpreadStrike, null);
|
||||
Assert.AreEqual(td.Coupon, 0.01);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCreateImportExcel()
|
||||
{
|
||||
using (var fs = new FileStream("d:\\www999test.xlsx", FileMode.Create, FileAccess.ReadWrite))
|
||||
{
|
||||
CreateImportExcel("雪球期权", fs);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateImportExcel(string tradeType, Stream streamIn)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("交易导入");
|
||||
|
||||
var basicFields = new MyField[] { "交易编号", "簿记账户名称", "交易员名称", "交易对手方名称",
|
||||
new MyField("结构类型"){ SetCell=cc=>cc.SetDataValidation().List("香草期权,亚式期权,合成价差期权,二元期权,障碍期权,双鲨期权,区间累积期权,凤凰期权,雪球期权,气囊结构,收益增强结构,自定义交易") },
|
||||
new MyField("交易方向"){ SetCell=cc=>cc.SetDataValidation().List("买入,卖出") },
|
||||
new MyField("行权方式"){ SetCell=cc=>cc.SetDataValidation().List("欧式,美式") },
|
||||
new MyField("看涨看跌"){ SetCell=cc=>cc.SetDataValidation().List("看涨,看跌") },
|
||||
"交易日期","到期日期","结算日期","标的代码", "标的价格",
|
||||
new MyField("相对行权价"){ SetCell=cc=>cc.SetDataValidation().List("是,否") },
|
||||
"执行价格",
|
||||
new MyField("权利金单价"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,255,230,153);
|
||||
}},
|
||||
new MyField("权利金总额"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,255,230,153);
|
||||
}},
|
||||
new MyField("期权费率%"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,255,230,153);
|
||||
cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%");
|
||||
}},
|
||||
new MyField("交易份额"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,189,215,238);
|
||||
}},
|
||||
new MyField("名义本金"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,189,215,238);
|
||||
}},
|
||||
new MyField("实际名义本金"){ SetCell=cc=>{
|
||||
cc.Style.Fill.BackgroundColor=XLColor.FromArgb(255,189,215,238);
|
||||
}},
|
||||
new MyField("期权年化"){ SetCell=cc=>cc.SetDataValidation().List("是,否") },
|
||||
"年化系数",
|
||||
new MyField("保底收益率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
new MyField("参与率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
new MyField("分红率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
new MyField("无风险利率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
new MyField("成交波动率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
new MyField("目标波动率%"){ SetCell=cc=>cc.WorksheetColumn().Style.NumberFormat.SetFormat("0.00%")},
|
||||
"平滑过渡天数",
|
||||
new MyField("收益结算"){ SetCell=cc=>cc.SetDataValidation().List("收盘价,结算价") },
|
||||
"销售员",
|
||||
new MyField("提成方式"){ SetCell=cc=>cc.SetDataValidation().List("绝对值,比例") },
|
||||
"提成金额", "备注" };
|
||||
var cell = ws.Row(2).FirstCell();
|
||||
WriteExcelHeader("基本要素", basicFields, ws, ref cell, null);
|
||||
|
||||
//了结信息字段
|
||||
|
||||
|
||||
//奇异期权要素
|
||||
MyField[] exoticFields = null;
|
||||
|
||||
switch (tradeType)
|
||||
{
|
||||
case "雪球期权":
|
||||
exoticFields = new MyField[] { "敲出障碍价格", "敲出赔付类别", "票息年化", "票息率%", "敲出行权价1", "敲出行权价2", "年化期权费率%", "敲出支付方式", "票息支付日期", "敲入障碍价格", "敲入到期支付类别", "敲入行权价1", "敲入行权价2", "非敲入到期支付票息%" };
|
||||
break;
|
||||
}
|
||||
|
||||
if (exoticFields != null)
|
||||
{
|
||||
WriteExcelHeader(tradeType, exoticFields, ws, ref cell, null);
|
||||
}
|
||||
|
||||
WriteExcelHeader("敲入观察日设置", new MyField[] { "自定义观察日", "使用规则生成观察日" }, ws, ref cell, null);
|
||||
WriteExcelHeader("敲出观察日设置", new MyField[] { "观察日", "障碍价格", "票息率" }, ws, ref cell, null);
|
||||
|
||||
wb.SaveAs(streamIn);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteExcelHeader2(string mainCol, string[] subCols, IXLWorksheet ws, ref IXLCell firstCell)
|
||||
{
|
||||
var cell = firstCell;
|
||||
|
||||
foreach (var str in subCols)
|
||||
{
|
||||
cell.SetValue(str);
|
||||
cell = cell.CellRight();
|
||||
}
|
||||
|
||||
var above = firstCell.CellAbove().SetValue(mainCol);
|
||||
var wr = ws.Range(above, cell.CellLeft().CellAbove()).Merge();
|
||||
firstCell = cell;
|
||||
}
|
||||
|
||||
private void WriteExcelHeader(MyField mainCell, MyField[] subCells, IXLWorksheet ws, ref IXLCell firstCell, MyStyle myStyle)
|
||||
{
|
||||
var cell = firstCell;
|
||||
|
||||
foreach (var col in subCells)
|
||||
{
|
||||
cell.SetValue(col.Text);
|
||||
cell.Style.Font.Bold = true;
|
||||
if (myStyle != null)
|
||||
{
|
||||
cell.Style.Font.FontColor = myStyle.fgcolor;
|
||||
cell.Style.Fill.BackgroundColor = myStyle.bgcolor;
|
||||
}
|
||||
col.SetCell?.Invoke(cell);
|
||||
cell.WorksheetColumn().AdjustToContents();
|
||||
cell = cell.CellRight();
|
||||
}
|
||||
|
||||
var above = firstCell.CellAbove().SetValue(mainCell.Text);
|
||||
above.Style.Font.Bold = true;
|
||||
above.Style.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);
|
||||
if (myStyle != null)
|
||||
{
|
||||
above.Style.Font.FontColor = myStyle.fgcolor;
|
||||
above.Style.Fill.BackgroundColor = myStyle.bgcolor;
|
||||
}
|
||||
mainCell.SetCell?.Invoke(above);
|
||||
var wr = ws.Range(above, cell.CellLeft().CellAbove()).Merge();
|
||||
|
||||
firstCell = cell;
|
||||
}
|
||||
|
||||
class MyField
|
||||
{
|
||||
public string Text { get; private set; }
|
||||
|
||||
public Action<IXLCell> SetCell { get; set; }
|
||||
|
||||
public MyField(string text)
|
||||
{
|
||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
public static implicit operator MyField(string text)
|
||||
{
|
||||
return new MyField(text);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
|
||||
class MyStyle
|
||||
{
|
||||
public XLColor bgcolor = XLColor.White;
|
||||
public XLColor fgcolor = XLColor.Black;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
using KellermanSoftware.CompareNetObjects;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using YLErp.Commons;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.DBModels.Helpers;
|
||||
using YLErp.Model;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.OrderModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试交易保存服务
|
||||
/// </summary>
|
||||
|
||||
[TestClass]
|
||||
public class OtcTradeSaveServiceTest : YLUnitTestBase
|
||||
{
|
||||
readonly bool _delete = true;
|
||||
readonly CompareLogic _compareLogic;
|
||||
|
||||
public OtcTradeSaveServiceTest()
|
||||
{
|
||||
_compareLogic = new CompareLogic(new ComparisonConfig
|
||||
{
|
||||
MaxDifferences = 10,
|
||||
DoublePrecision = 5,
|
||||
MembersToIgnore = new List<string> { nameof(trade.id), nameof(trade.EncryptId),
|
||||
nameof(trade.CreateDate), nameof(trade.UnderlyingAssetClass) },
|
||||
CaseSensitive = false,
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod("测试保存香草期权交易")]
|
||||
public void TestSaveVanillaOption()
|
||||
{
|
||||
var asset = GetAssetUnit();
|
||||
var client = GetClient();
|
||||
var uly = GetUnderlyingManager(true);
|
||||
var valueDate = ValueDate;
|
||||
var td = new OtcOptionTradeFullEx
|
||||
{
|
||||
AssetBookName = asset.Name,
|
||||
TraderName = "Admin",
|
||||
ClientNumber = client.Number,
|
||||
ClientName = client.Name,
|
||||
TradeType = "香草期权",
|
||||
TradeNumber = "UAT-" + UniqueTimeId.GetStr(),
|
||||
UnderlyingCode= uly.UnderlyingCode,
|
||||
BuySell="买入",
|
||||
ExerciseMode= "European",
|
||||
OptionType="Put",
|
||||
SpotPrice=12900,
|
||||
IsMoneynessOption="否",
|
||||
Strike= 12900,
|
||||
TradeDate=valueDate,
|
||||
ExerciseDate=valueDate.AddMonths(3),
|
||||
SettlementDate = valueDate.AddMonths(3),
|
||||
Notional = 400,
|
||||
TradeSinglePrice=100,
|
||||
SettlementType=0,
|
||||
ParticipationRate=1,
|
||||
IsAnnualized=false,
|
||||
PrincipalRate=0,
|
||||
NoRiskRate=0.05,
|
||||
DividendRate=0,
|
||||
TradeOpenVolatility=0.1616,
|
||||
TradeCloseVolatility = 0.1616,
|
||||
NumOfSmoothingDays=1,
|
||||
Comments="测试API"
|
||||
};
|
||||
|
||||
var td2 = new OtcTradeSaveService(this.OptUser).SaveOptionTradeFromApiOrImport(td, Model.Enum.TradeSourceEnum.WebApiV2);
|
||||
|
||||
Assert.IsTrue(td.TradeSinglePrice==td2.TradeSinglePrice);
|
||||
}
|
||||
|
||||
[TestMethod("测试保存亚式期权交易")]
|
||||
public void TestSaveAsianOption()
|
||||
{
|
||||
InnerTest<trade_asian_option>("亚式期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存二元期权交易")]
|
||||
public void TestSaveBinaryOption()
|
||||
{
|
||||
InnerTest<trade_binary_option>("二元期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存障碍期权交易")]
|
||||
public void TestSaveBarrierOption()
|
||||
{
|
||||
InnerTest<trade_barrier_option>("障碍期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存双鲨期权交易")]
|
||||
public void TestSaveDoubleSharkfinOption()
|
||||
{
|
||||
InnerTest<trade_double_sharkfin_option>("双鲨期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存区间累积期权交易")]
|
||||
public void TestSaveRangeAccOption()
|
||||
{
|
||||
InnerTest<trade_rangeaccrual>("区间累积期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存气囊结构交易")]
|
||||
public void TestSaveAirBagOption()
|
||||
{
|
||||
InnerTest<trade_airbag>("气囊结构");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存收益增强结构交易")]
|
||||
public void TestSaveUnderlyingEnhanceOption()
|
||||
{
|
||||
InnerTest<trade_underlying_enhance>("收益增强结构");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存雪球期权交易")]
|
||||
public void TestSaveSnowballOption()
|
||||
{
|
||||
InnerTest<trade_snowball>("雪球期权");
|
||||
}
|
||||
|
||||
[TestMethod("测试保存凤凰期权交易")]
|
||||
public void TestSaveAutoCallOption()
|
||||
{
|
||||
InnerTest<trade_autocall>("凤凰期权");
|
||||
}
|
||||
|
||||
private void InnerTest<TExtend>(string tradeType) where TExtend : TradeExtendBase
|
||||
{
|
||||
var asset = GetAssetUnit();
|
||||
var client = GetClient();
|
||||
var uly = GetUnderlyingManager(true);
|
||||
var valueDate = ValueDate;
|
||||
var td = new OtcOptionTradeFull
|
||||
{
|
||||
AnnualizedEnhanceRate = 0.01,
|
||||
AnnualizedPremiumRate = 0.01,
|
||||
AnnualizeFactor = 100.0 / 244,
|
||||
AnnualizeFactor2 = 0.9,
|
||||
AssetBookName = asset.Name,
|
||||
AssetId = asset.id,
|
||||
AveragingPeriodStartDate = valueDate,
|
||||
BarrierHigh = 1.05,
|
||||
BarrierLow = 0.95,
|
||||
BarrierShift = 10,
|
||||
BarrierType = "双障碍敲出",
|
||||
BasisGap = 1,
|
||||
BasisUnderlyingCode = "RB00",
|
||||
BasisUnderlyingId = uly.id,
|
||||
BonusRate = 0.1,
|
||||
BuySell = "卖出",
|
||||
CalcFlag = 0,
|
||||
CalcId = "CalcId",
|
||||
OptionType = "看涨",
|
||||
CashOrNothingAmount = 500,
|
||||
CashOrNothingAmountHigh = 1000,
|
||||
CashOrNothingAmountHighRate = 0.1,
|
||||
CashOrNothingAmountRate = 0.05,
|
||||
CheckStatus = 0,
|
||||
CheckTradeUpdate = 0,
|
||||
ClientId = client.id,
|
||||
ClientName = client.Name,
|
||||
Comments = "单元测试",
|
||||
ContractVersion = "V2",
|
||||
Coupon = 0.1,
|
||||
CouponBarrier = 1.05,
|
||||
CouponPayType = CouponPayTypeEnum.AtMaturity,
|
||||
CreateDate = valueDate,
|
||||
DividendDate = DateTime.MinValue,
|
||||
DividendRate = 0.1,
|
||||
DurationDays = 10,
|
||||
ExerciseDate = valueDate.AddMonths(3),
|
||||
ExerciseMode = ConsGlobal.ExerciseMode.American,
|
||||
FinalPrice = 3700,
|
||||
GroupId = 1,
|
||||
GroupName = "Test",
|
||||
HasPartialUnWind = 0,
|
||||
HasPayoffLimit = true,
|
||||
HighStrike = 1.05,
|
||||
IncludeCouponAfterKI = true,
|
||||
InitialSpotPriceState = "期初价格已确认",
|
||||
IsAnnualized = true,
|
||||
IsAnnualized2 = true,
|
||||
IsDiscreteMonitored = true,
|
||||
IsFixedCoupon = false,
|
||||
IsMoneynessOption = "是",
|
||||
IsSingleContract = 1,
|
||||
IsTradePricePayType = false,
|
||||
IsUsePremiumRate = true,
|
||||
|
||||
InitialMargin = 100,
|
||||
KIBarrier = 0.9,
|
||||
KIParticipationRate = 0.1,
|
||||
KIPayoffType = KIPayoffTypeEnum.ToCallSpreadOption,
|
||||
KOBarrier = 1.05,
|
||||
KOObservationDates = valueDate.OtcFormatDate(),
|
||||
KOObservationSettleDates = valueDate.OtcFormatDate(),
|
||||
KOPayoffType = KOPayoffTypeEnum.ToSpreadOption,
|
||||
KORebate = 0.1,
|
||||
KORebateType = RebateTypeEnum.AtEnd,
|
||||
Lots = 10,
|
||||
LowerRange = 0.9,
|
||||
MaturityDate = uly.MaturityDate,
|
||||
MonitorType = "离散",
|
||||
NoRiskRate = 0.05,
|
||||
NumOfSmoothingDays = 10,
|
||||
Notional = 100,
|
||||
ObservationDates = valueDate.OtcFormatDate(),
|
||||
ObservationDateStr = valueDate.OtcFormatDate(),
|
||||
OptDate = OptDate,
|
||||
OptId = UserId,
|
||||
OptName = UserName,
|
||||
OriginalNotional = 100,
|
||||
OriginalStockEqvNotional = 0,
|
||||
PairTrade = "",
|
||||
ParentTradeId = 0,
|
||||
ParticipationRate = 0.5,
|
||||
PayoffType = "DoubleNoTouch",
|
||||
PremiumPayDate = valueDate.AddMonths(3),
|
||||
PremiumRate = 0.1,
|
||||
PricingModel = "",
|
||||
PrincipalRate = 0.05,
|
||||
ProcessOptDate = null,
|
||||
ProcessOrderId = 0,
|
||||
ProcessStatus = "",
|
||||
Rebate = 500,
|
||||
RebateHigh = 1000,
|
||||
RebateRate = 0.05,
|
||||
RebateHighRate = 0.1,
|
||||
RebateType = "AtHit",
|
||||
SentMailCount = 0,
|
||||
SettlementDate = valueDate.AddMonths(3),
|
||||
SettlementType = 0,
|
||||
SpreadStrike = 0.95,
|
||||
SpreadStrike1 = 0.9,
|
||||
SpreadStrikeAtKO = 1.06,
|
||||
SpreadStrikeAtKO1 = 1.01,
|
||||
StartDate = valueDate,
|
||||
StockEqvNotional = 0,
|
||||
StockEqvNotionalMax = 0,
|
||||
StockEqvNotionalReal = 100 * 3600,
|
||||
Strike = 1.002,
|
||||
StrikeGearingFactor = 1,
|
||||
StrikeHigh = 1.02,
|
||||
StrikeType = ConsTrade.AsiaStrikeType.Fixed,
|
||||
StructureIntroduction = "StructureIntroduction",
|
||||
StructureType = "",
|
||||
TradeAmount = 100,
|
||||
TradeDate = valueDate,
|
||||
TradeInstruction = "TradeInstruction",
|
||||
TradeCloseVolatility = 0.5,
|
||||
TradeNumber = "UT-" + Guid.NewGuid().ToString("N"),
|
||||
TradeOpenVolatility = 0.45,
|
||||
TradePremium = 0.03,
|
||||
TraderId = 1,
|
||||
TraderName = "Admin",
|
||||
TradeSavedVol = 0.4,
|
||||
TradeSource = "系统交易",
|
||||
TradeStatus = "新增待确认",
|
||||
TradeType = tradeType,
|
||||
TradeUnit = "吨",
|
||||
TTMDays = null,
|
||||
UnderlyingAssetClass = "螺纹钢",
|
||||
UnderlyingCode = uly.UnderlyingCode,
|
||||
UnderlyingId = uly.id,
|
||||
UnderlyingInstrumentType = uly.UnderlyingInstrumentType,
|
||||
UnderlyingAssetName = uly.UnderlyingName,
|
||||
UnderlyingPrice = null,
|
||||
UnWindDate = null,
|
||||
UnWindNotional = null,
|
||||
UpperRange = 1.1,
|
||||
ValidState = ConsGlobal.Valid,
|
||||
Vol = null,
|
||||
VolType = null,
|
||||
SpotPrice = 3600
|
||||
};
|
||||
|
||||
td.KOObservationDates += "," + td.ExerciseDate.OtcFormatDate();
|
||||
|
||||
if (tradeType == "雪球期权" || tradeType == "凤凰期权")
|
||||
{
|
||||
td.IsAnnualized = false;
|
||||
td.AnnualizeFactor = 1;
|
||||
td.MetaDic[nameof(td.AnnualizeFactor)] = "/";
|
||||
|
||||
td.ExerciseMode = ConsTrade.ExerciseType.European;
|
||||
td.StockEqvNotionalMax = td.OriginalStockEqvNotional = td.StockEqvNotional = td.StockEqvNotionalReal;
|
||||
|
||||
var spotPrice = Math.Abs(td.SpotPrice.Value);
|
||||
td.StockEqvNotionalReal = TradeHelper.GetStockEqvNotionalReal(td.StockEqvNotional, td.ParticipationRate, td.AnnualizeFactor);
|
||||
td.TradeAmount = td.Notional = spotPrice > 0 ? td.StockEqvNotionalReal / spotPrice : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
td.MetaDic[nameof(td.AnnualizeFactor)] = "100/244";
|
||||
|
||||
if (tradeType == "双鲨期权")
|
||||
{
|
||||
td.ExerciseMode = ConsTrade.ExerciseType.European;
|
||||
}
|
||||
else if (tradeType == "亚式期权")
|
||||
{
|
||||
td.PayoffType = ConsTrade.AsianAverageType.ArithmeticAverage;
|
||||
}
|
||||
td.StockEqvNotionalMax = td.OriginalStockEqvNotional = td.StockEqvNotional = TradeHelper.GetStockEqvNotional(td.StockEqvNotionalReal, td.ParticipationRate, td.AnnualizeFactor);
|
||||
}
|
||||
|
||||
td.OriginalNotional = td.Notional;
|
||||
td.TradePrice = TradeHelper.GetTradePriceByPremiumRate(td.PremiumRate, td.StockEqvNotional, td.ParticipationRate, td.PrincipalRate, td.AnnualizeFactor,td.BuySell,td.TradeType,false);
|
||||
td.TradeSinglePrice = TradeHelper.GetTradeSinglePriceByPremiumRate(td.PremiumRate, td.SpotPrice);
|
||||
|
||||
var saved = new OtcTradeSaveService(this).SaveOptionTradesFromTradeEdit(td);
|
||||
|
||||
td.id = saved.id;
|
||||
|
||||
var dbTrade = new TradeDetailsQueryService(this).GetOtcTradeFull(saved.TradeNumber);
|
||||
|
||||
if (_delete)
|
||||
{
|
||||
AddClearSQL<trade>("id=" + td.id);
|
||||
AddClearSQL<TradeMeta>("TradeId=" + td.id);
|
||||
AddClearSQL<TExtend>("TradeId=" + td.id);
|
||||
}
|
||||
|
||||
var map1 = YLAutoMapper.Map<OtcTradeBase>(td);
|
||||
var map2 = YLAutoMapper.Map<OtcTradeBase>(dbTrade);
|
||||
ComparisonResult result = _compareLogic.Compare(map1, map2);
|
||||
Assert.IsTrue(result.AreEqual, result.DifferencesString);
|
||||
|
||||
var tdex1 = YLAutoMapper.Map<TExtend>(td);
|
||||
var tdex2 = YLAutoMapper.Map<TExtend>(dbTrade);
|
||||
Assert.IsTrue(tdex2.TradeId > 0, "TradeId映射失败");
|
||||
result = _compareLogic.Compare(tdex1, tdex2);
|
||||
Assert.IsTrue(result.AreEqual, result.DifferencesString);
|
||||
}
|
||||
|
||||
class VanillaTrade : TradeExtendBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using YLErp.DBModels;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.OrderModule
|
||||
{
|
||||
[TestClass]
|
||||
public class TradeAbstractServiceTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestGetTradeAbstractInfo()
|
||||
{
|
||||
var td = new trade
|
||||
{
|
||||
TradeType = "香草期权",
|
||||
UnderlyingCode = "RB2009",
|
||||
IsUsePremiumRate = true,
|
||||
Strike = 1.1,
|
||||
TradeAmount = 100,
|
||||
ExerciseMode = "American",
|
||||
TradeNumber = "Test-001",
|
||||
TradeDate = new DateTime(2020, 1, 12),
|
||||
ExerciseDate = new DateTime(2020, 3, 1),
|
||||
ClientName = "福建龙岩可乐公司",
|
||||
BuySell = "买入",
|
||||
SpotPrice = 3350,
|
||||
PremiumRate = 0.23,
|
||||
TradeSinglePrice = 356,
|
||||
TradePrice = 199999,
|
||||
StockEqvNotional = 256789012,
|
||||
StockEqvNotionalReal = 256789012,
|
||||
ParticipationRate = 0.9,
|
||||
IsMoneynessOption = "是"
|
||||
};
|
||||
|
||||
var items = TradeAbstractService.GetTradeAbstractInfoItems(td);
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(item.text + ":" + item.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user