// A - B를 진행한다. public static Position_KtbSkel GetForwardMinusBackward( Position_KtbSkel forward, Position_KtbSkel backward) { if (forward.SignedSpotCount <= 0 || backward.SignedSpotCount >= 0) { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } if (Math.Abs(forward.SignedSpotCount) <= Math.Abs(backward.SignedSpotCount)) { return null; } String cSpotCode = forward.SpotCode; String cFutureCode = forward.FutureCode; double cSpotAvgPrice = forward.SpotAvgPriceTimeAdjust; double cFutureAvgPrice = forward.FutureAvgPrice; // c.SignedSpotCount이 양수라면 a > b 이었고 아직도 남아있는 것을 의미한다. // c.SignedSpotCount이 음수라면 a < b 이었고 지우고도 b가 남아있는 것을 의미한다. long cSignedSpotCount = forward.SignedSpotCount + backward.SignedSpotCount; long cSignedFutureCount = forward.SignedFutureCount + backward.SignedFutureCount; Position_KtbSkel c = new Position_KtbSkel( cSpotCode, cSignedSpotCount, cSpotAvgPrice, cFutureCode, cSignedFutureCount, cFutureAvgPrice, forward.TradingDate, forward.TimeRising); return c; }
private void button3_Click(object sender, EventArgs e) { try { long spotCount = Convert.ToInt32(textBox15.Text); // spot count double spotAvgPrice = Convert.ToDouble(textBox16.Text); // spot price double futureAvgPrice = Convert.ToDouble(textBox14.Text); // future price long futureCount = Convert.ToInt32(textBox13.Text); // future count // 포지션 등록 Position_KtbSkel target = _parent.GetTargetPosition(); String spotCode = target.SpotCode; String futureCode = target.FutureCode; DateTime tradingDate = CoreLib.DateUtil.GetTodayDateTime(0, 0, 0); Position_KtbSkel real = new Position_KtbSkel( spotCode, spotCount, spotAvgPrice, futureCode, futureCount, futureAvgPrice, tradingDate, 0); _parent.SetRealPosition(real); this.Close(); } catch (System.Exception ex) { logger.Warn(ex.ToString()); } }
public double GetOneUnitPnL( Position_KtbSkel position, RawMarketData spotRmdClone, RawMarketData futureRmdClone) { double spotProfit = spotRmdClone.BidPrice1 - position.SpotAvgPriceTimeAdjust; double futureProfit = (position.FutureAvgPrice - futureRmdClone.AskPrice1) * 100; double pnl = spotProfit + futureProfit; return pnl; }
public Boolean IsExitChance( Position_KtbSkel position, RawMarketData spotRmdClone, RawMarketData futureRmdClone) { double pnl = GetOneUnitPnL(position, spotRmdClone, futureRmdClone); if (pnl >= kProfitPoint) { return true; } return false; }
public void TestKtbSkelPosition() { List<Position_KtbSkel> data = new List<Position_KtbSkel>(); // 가장 싸게 사고 비싸게 판 경우 Position_KtbSkel datum1 = new Position_KtbSkel( "", 10, 8888, "", -10, 107.01); Position_KtbSkel datum2 = new Position_KtbSkel( "", 10, 8889, "", -10, 107.01); // 가장 비싸게 사고 싸게 판 경우 Position_KtbSkel datum3 = new Position_KtbSkel( "", 10, 8889, "", -10, 107.00); data.Add(datum1); data.Add(datum2); data.Add(datum3); data.Sort(delegate(Position_KtbSkel mine, Position_KtbSkel other) { double mineValue = (mine.FutureAvgPrice * 100.0 - mine.SpotAvgPriceTimeAdjust); double otherValue = (other.FutureAvgPrice * 100.0 - other.SpotAvgPriceTimeAdjust); // 값 의미 0보다 // 작음 이 개체는 other 매개 변수보다 작습니다. // 0 이 개체는 other와 같습니다. 0보다 큼 이 개체는 other보다 큽니다. if (mineValue < otherValue) { return -1; } else if (mineValue == otherValue) { return 0; } return 1; }); Assert.AreEqual(data[0], datum3); Assert.AreEqual(data[1], datum2); Assert.AreEqual(data[2], datum1); }
void TestPositionUtil_BigMinusBig() { Position_KtbSkel big1 = new Position_KtbSkel( "", 20, 8888, "", -20, 107.01); Position_KtbSkel big2 = new Position_KtbSkel( "", -20, 8887, "", 20, 107.00); Position_KtbSkel a = PositionUtil_KtbSkel.GetForwardMinusBackward(big1, big2); Assert.AreEqual(a, null); Position_KtbSkel b = PositionUtil_KtbSkel.GetBackwardMinusForward(big1, big2); Assert.AreEqual(b, null); Assert.AreEqual(PositionUtil_KtbSkel.IsZero(b), true); }
public static Boolean IsZero(Position_KtbSkel pos) { if (pos == null || pos.SignedSpotCount == 0) { return true; } return false; }
public static Boolean IsPlus(Position_KtbSkel pos) { if (pos == null) { return false; } if (pos.SignedSpotCount > 0) { return true; } return false; }
public static PositionShareDivision_KtbSkel GetShareDivision( Position_KtbSkel forward, Position_KtbSkel backward) { // A가 기존에 있는 값이고 B는 Reverse를 의미한다. if (forward.SignedSpotCount <= 0 || backward.SignedSpotCount >= 0) { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } PositionShareDivision_KtbSkel sd = new PositionShareDivision_KtbSkel(); sd.DivisionForward = GetForwardMinusBackward(forward, backward); sd.Share = GetShare(forward, backward); sd.DivisionBackward = GetBackwardMinusForward(forward, backward); if (IsZero(sd.DivisionForward) && IsZero(sd.DivisionBackward)) { sd.DivisionType = PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.RemainEmpty; } if (sd.DivisionForward != null && sd.DivisionBackward != null) { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } if (sd.DivisionForward != null) { sd.DivisionType = PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.ForwardRemained; } if (sd.DivisionBackward != null) { sd.DivisionType = PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.BackwardRemained; } return sd; }
public static DonePosition_KtbSkel GetShare(Position_KtbSkel forward, Position_KtbSkel backward) { long spotUnsignedCount = Math.Min( Math.Abs(forward.SignedSpotCount), Math.Abs(backward.SignedSpotCount)); long futureUnsignedCount = Math.Min( Math.Abs(forward.SignedFutureCount), Math.Abs(backward.SignedFutureCount)); DonePosition_KtbSkel ret = new DonePosition_KtbSkel( forward.SpotCode, spotUnsignedCount, forward.SpotAvgPriceTimeAdjust, backward.SpotAvgPriceTimeAdjust, forward.FutureCode, futureUnsignedCount, forward.FutureAvgPrice, backward.FutureAvgPrice); return ret; }
public void Push(Position_KtbSkel position) { if (PositionUtil_KtbSkel.IsZero(position)) { return; } CheckValidData(position, true); _stack.Add(position); SortStack(); }
void TestTakeOverPosition() { string strategyName = "unittest_position"; long maxNotional = 100; double downBoundary = 0F; double upBoundary = 10F; StrategyManager.Ins().UnRegister(strategyName); AgentManager.Ins().Clear(); STR_KtbSkel factory = new STR_KtbSkel(); Input_KtbSkel input = new Input_KtbSkel(); input.MaxNotional = maxNotional; input.Spot10yrCode = "KR1035027161"; input.Future10yrCode = "167FC000"; Serializer serializer = new Serializer(typeof(Input_KtbSkel)); String jsonText = serializer.Serialize(input); STR_KtbSkel strategy = StrategyBuilder_KtbSkel.CreateStrategy(jsonText, strategyName); PrivateObject po = new PrivateObject(strategy); STR_KtbSkel_Accessor strategyAcc = new STR_KtbSkel_Accessor(po); strategyAcc.SetAccountOrderLimit(); ProcessController_KtbSkel controller = strategyAcc.Controller; String spotCode = KtbSpotUtil.Ins().KtbSpot_10yr.Code; String futureCode = KtbFutureUtil.Ins().KtbFuture_10yr_1.Code; SortedPositionStack_KtbSkel target = new SortedPositionStack_KtbSkel(controller, strategyName, spotCode, futureCode, maxNotional, downBoundary, upBoundary); SortedPositionStack_KtbSkel_Accessor acc = new SortedPositionStack_KtbSkel_Accessor( new PrivateObject(target)); acc._stack.Clear(); acc.DeleteTable(); int i = 1; Position_KtbSkel pos1 = new Position_KtbSkel( spotCode, 50 * i, 8888, futureCode, (-50) * i, 107.00); ++i; Position_KtbSkel pos2 = new Position_KtbSkel( spotCode, 50 * i, 8888, futureCode, (-50) * i, 107.04); ++i; Position_KtbSkel pos3 = new Position_KtbSkel( spotCode, 50 * i, 8888, futureCode, (-50) * i, 107.02); ++i; Position_KtbSkel pos4 = new Position_KtbSkel( spotCode, 50 * i, 8888, futureCode, (-50) * i, 107.03); acc.Push(pos1); acc.ToDB(); acc._stack.Clear(); acc.TakeOverPositionFromDB(); Assert.AreEqual(1, acc._stack.Count); acc.DeleteTable(); acc._stack.Clear(); acc.Push(pos1); acc.Push(pos2); acc.Push(pos3); acc.Push(pos4); acc.ToDB(); acc._stack.Clear(); Assert.AreEqual(0, acc._stack.Count); acc.TakeOverPositionFromDB(); Assert.AreEqual(4, acc._stack.Count); Assert.AreEqual(acc.Peek().SignedSpotCount, 100); }
// 포지션을 꺾을 때의 손익이다. public static double GetPnLIfExit(Position_KtbSkel pos) { RawMarketData rmdSpot = RmdManager.Ins().GetData(pos.SpotCode); RawMarketData rmdFuture = RmdManager.Ins().GetData(pos.FutureCode); double spotOutPrice = rmdSpot.BidPrice1; double futureOutPrice = rmdFuture.AskPrice1; double spotInPrice = pos.SpotAvgPriceTimeAdjust; double futureInPrice = pos.FutureAvgPrice; long spotUnsignedCount = Math.Abs(pos.SignedSpotCount); long futureUnsignedCount = Math.Abs(pos.SignedFutureCount); double spotPnL = (spotOutPrice - spotInPrice) * (double)spotUnsignedCount * CommonConst._10_000; double futureOnePointAmount = ProductUtil.Ins().GetOnePointAmount(pos.FutureCode); double futurePnL = (futureInPrice - futureOutPrice) * (double)futureUnsignedCount * futureOnePointAmount; return spotPnL + futurePnL; }
public void Erase(Position_KtbSkel backward) { if (KtbSpotUtil.Ins().IsDirtyNotional(backward.SignedSpotCount)) { String ex = "Dirty notional"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } CheckValidData(backward, false); while (true) { if (PositionUtil_KtbSkel.IsZero(backward)) { break; } Position_KtbSkel top = Peek(); if (top == null) { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); break; } PositionShareDivision_KtbSkel sd = PositionUtil_KtbSkel.GetShareDivision(top, backward); backward = sd.DivisionBackward; if (sd.Share != null) { _donePositions.Add(sd.Share); } switch (sd.DivisionType) { case PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.ForwardRemained: { // 양수, top > reversePosition Position_KtbSkel remainTop = sd.DivisionForward; Pop(); Push(remainTop); break; } case PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.RemainEmpty: { // 지우고 끝 Pop(); break; } case PositionShareDivision_KtbSkel.ForwardBackwardDivisionType.BackwardRemained: { // 지우고 또 지운다. Pop(); break; } default: String ex = "여기에 오면 안된다."; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); break; } } }
Boolean IsEmpty(Position_KtbSkel pos) { if (pos.SignedSpotCount == 0 && pos.SignedFutureCount == 0) { return true; } return false; }
void InsertToDB_Raw(Position_KtbSkel pos) { String queryTemplate = "insert into ktb_skel_position " + "(strategy_name, spot_code, spot_count, spot_avg_price, " + "future_code, future_count, future_avg_price, trading_date) values " + "('{0}', '{1}', {2}, {3}, '{4}', {5}, {6}, '{7}')"; String query = String.Format( queryTemplate, StrategyName, pos.SpotCode, pos.SignedSpotCount, pos.SpotAvgPriceTimeAdjust - pos.TimeRising, pos.FutureCode, pos.SignedFutureCount, pos.FutureAvgPrice, pos.TradingDate.ToString("yyyy-MM-dd")); int ret = DBUtil.Execute(query, CommonConst.DATABASE_MADVIPER); if (ret != 1) { logger.Warn("Delete query error. Insert fail"); } }
void CheckValidData(Position_KtbSkel position, Boolean bForward) { String ex = "Invalid Data"; if (position.SpotCode.CompareTo(this.SpotCode) != 0) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } if (position.FutureCode.CompareTo(this.FutureCode) != 0) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } if (bForward) { if (position.SignedSpotCount < 0 || position.SignedFutureCount > 0) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } } else { if (position.SignedSpotCount > 0 || position.SignedFutureCount < 0) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } } }
public Boolean TakeOverPositionFromDB() { String query = String.Format( "select * from ktb_skel_position where strategy_name = '{0}'", this.StrategyName); DataRowCollection rows = DBUtil.SelectFromDB(query, CommonConst.DATABASE_MADVIPER); long notionalTotal = 0; for (int i = 0; i < rows.Count; ++i) { DataRow row = rows[i]; String spotCode = Convert.ToString(row["spot_code"]); long spotCount = Convert.ToInt64(row["spot_count"]); double spotAvgPrice = Convert.ToDouble(row["spot_avg_price"]); String futureCode = Convert.ToString(row["future_code"]); long futureCount = Convert.ToInt64(row["future_count"]); double futureAvgPrice = Convert.ToDouble(row["future_avg_price"]); DateTime tradingDate = Convert.ToDateTime(row["trading_date"]); if (spotCount <= 0) { String ex = "국채현물 수량 이상."; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } long timeRising = (DateTime.Now - tradingDate).Days; spotAvgPrice += timeRising; Position_KtbSkel pos = new Position_KtbSkel( spotCode, spotCount, spotAvgPrice, futureCode, futureCount, futureAvgPrice, tradingDate, timeRising); double reqPrice = KtbSpotUtil.Ins().RoundProductPrice(spotAvgPrice); RawMarketData rmd = RmdManager.Ins().KtbSpot.GetData(spotCode); RawMarketData rmdClone = rmd.Clone() as RawMarketData; Push(pos); notionalTotal += spotCount; } if (notionalTotal <= this.MaxNotional) { return true; } else { return false; } }
void TestErase_Raw(SortedPositionStack_KtbSkel_Accessor acc) { Assert.AreEqual(acc._stack.Count, 3); { // 3억에서 1억만 지운다. Position_KtbSkel erase = new Position_KtbSkel( "", -10, 8899, "", 10, 107.0); acc.Erase(erase); CheckRateAndNotional(acc, 0, 0, 0, 50); } Assert.AreEqual(acc._stack.Count, 3); { // 3억을 지운다. Position_KtbSkel erase = new Position_KtbSkel( "", -30, 8899, "", 30, 107.0); acc.Erase(erase); CheckRateAndNotional(acc, 0, 0, 0, 20); } Assert.AreEqual(acc._stack.Count, 2); { // 1억을 지운다. Position_KtbSkel erase = new Position_KtbSkel( "", -10, 8899, "", 10, 107.0); acc.Erase(erase); CheckRateAndNotional(acc, 0, 0, 0, 10); } Assert.AreEqual(acc._stack.Count, 1); }
void TestPositionUtil_BigMinusSmall() { Position_KtbSkel forward = new Position_KtbSkel( "", 20, 8888, "", -20, 107.01); Position_KtbSkel small = new Position_KtbSkel( "", -10, 8887, "", 10, 107.00); Position_KtbSkel big = new Position_KtbSkel( "", -30, 8886, "", 30, 106.99); Position_KtbSkel a = PositionUtil_KtbSkel.GetForwardMinusBackward(forward, small); Assert.AreEqual(a.SpotAvgPriceTimeAdjust, forward.SpotAvgPriceTimeAdjust); Assert.AreEqual(a.FutureAvgPrice, forward.FutureAvgPrice); Assert.AreEqual(a.SignedSpotCount, 10); Assert.AreEqual(a.SignedFutureCount, -10); Position_KtbSkel b = PositionUtil_KtbSkel.GetBackwardMinusForward(forward, big); Assert.AreEqual(b.SpotAvgPriceTimeAdjust, big.SpotAvgPriceTimeAdjust); Assert.AreEqual(b.FutureAvgPrice, big.FutureAvgPrice); Assert.AreEqual(b.SignedSpotCount, -10); Assert.AreEqual(b.SignedFutureCount, 10); Assert.AreEqual(PositionUtil_KtbSkel.IsPlus(a), true); Assert.AreEqual(PositionUtil_KtbSkel.IsPlus(b), false); Assert.AreEqual(PositionUtil_KtbSkel.IsZero(b), false); }
public void TestSortedPositionStack_KtbSkel() { long maxNotional = 100; double downBoundary = 0F; double upBoundary = 10F; String spotCode = KtbSpotUtil.Ins().KtbSpot_10yr.Code; String futureCode = KtbFutureUtil.Ins().KtbFuture_10yr_1.Code; SortedPositionStack_KtbSkel target = new SortedPositionStack_KtbSkel(null, "unittest", spotCode, futureCode, maxNotional, downBoundary, upBoundary); Assert.AreEqual(target.MaxNotional, maxNotional); Assert.AreEqual(target.DownBoundary, downBoundary); Assert.AreEqual(target.UpBoundary, upBoundary); SortedPositionStack_KtbSkel_Accessor acc = new SortedPositionStack_KtbSkel_Accessor( new PrivateObject(target)); // 미만 CheckRateAndNotional(acc, -0.1F, 0.0F, 0, 0); CheckRateAndNotional(acc, -10.0F, 0.0F, 0, 0); // 정상상태 CheckRateAndNotional(acc, 0.0F, 0.0F, 0, 0); CheckRateAndNotional(acc, 1.0F, 0.1F, (long)(maxNotional * 0.1), 0); CheckRateAndNotional(acc, 3.0F, 0.3F, (long)(maxNotional * 0.3), 0); CheckRateAndNotional(acc, 10.0F, 1.0F, maxNotional, 0); // 오버 CheckRateAndNotional(acc, 11.0F, 1.0F, maxNotional, 0); CheckRateAndNotional(acc, 100.0F, 1.0F, maxNotional, 0); CheckRateAndNotional(acc, 0.1F, 0.01F, 0, 0); CheckRateAndNotional(acc, 0.25F, 0.025F, 0, 0); //push pos1 Position_KtbSkel pos1 = new Position_KtbSkel( spotCode, 10, 8889, futureCode, -10, 107.00); acc.Push(pos1); CheckRateAndNotional(acc, 0, 0, 0, 10); //push pos2 Position_KtbSkel pos2 = new Position_KtbSkel( spotCode, 20, 8888, futureCode, -20, 107.00); acc.Push(pos2); CheckRateAndNotional(acc, 0, 0, 0, 30); //push pos3 Position_KtbSkel pos3 = new Position_KtbSkel( spotCode, 30, 8887, futureCode, -30, 107.10); acc.Push(pos3); // pos3가 top CheckRateAndNotional(acc, 0, 0, 0, 60); TestErase_Raw(acc); TestReverseSweeperAfterTakeOverPosition(); }
void TestPositionUtil_SmallMinusBig() { Position_KtbSkel small = new Position_KtbSkel( "", 10, 8888, "", -10, 107.01); Position_KtbSkel big = new Position_KtbSkel( "", -20, 8887, "", 20, 107.00); Position_KtbSkel a = PositionUtil_KtbSkel.GetForwardMinusBackward(small, big); Assert.AreEqual(a, null); Position_KtbSkel b = PositionUtil_KtbSkel.GetBackwardMinusForward(small, big); Assert.AreEqual(b.SpotAvgPriceTimeAdjust, big.SpotAvgPriceTimeAdjust); Assert.AreEqual(b.FutureAvgPrice, big.FutureAvgPrice); Assert.AreEqual(b.SignedSpotCount, -10); Assert.AreEqual(b.SignedFutureCount, 10); Assert.AreEqual(PositionUtil_KtbSkel.IsPlus(b), false); Assert.AreEqual(PositionUtil_KtbSkel.IsZero(b), false); }