242 lines
11 KiB
C#
242 lines
11 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|