public Position_KtbSkel GetPosition() { if (IsDone()) { String futureCode = this.TargetPosition.FutureCode; double futureAvgPrice = GetAvgFuturePrice(); long tmpFutureCount = GetFutureMaxPossibleCount(); LongShortCount tmpFutureLsc = new LongShortCount(this.TargetPosition.SignedFutureCount); LongShortCount futureLsc = new LongShortCount(tmpFutureLsc.LongShort, Convert.ToUInt64(tmpFutureCount)); long signedFutureCount = futureLsc.GetSignedCount(); String spotCode = this.TargetPosition.SpotCode; double spotAvgPrice = this.TargetPosition.SpotAvgPriceTimeAdjust; LongShortCount tmpSpotLsc = new LongShortCount(this.TargetPosition.SignedSpotCount); LongShortCount spotLsc = new LongShortCount(tmpSpotLsc.LongShort, Convert.ToUInt64(this.UnsignedSpotContractedCount)); long signedSpotCount = spotLsc.GetSignedCount(); DateTime tradingDate = CoreLib.DateUtil.GetTodayDateTime(0, 0, 0); Position_KtbSkel position = new Position_KtbSkel( spotCode, signedSpotCount, spotAvgPrice, futureCode, signedFutureCount, futureAvgPrice, tradingDate, 0); return position; } else { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return null; }
// 신규 주문을 낼 때 public LongShortCount GetRemainLongShortCount() { // 타겟 수량 - 체결된 수량 LongShortCount lsc = new LongShortCount(this.LongShort, Convert.ToUInt64(this.UnsignedTargetCount)); long targetSignedCount = lsc.GetSignedCount(); long totalSignedContractedCount = GetTotalSignedContractedCount(); long signedRemainCount = targetSignedCount - totalSignedContractedCount; LongShortCount remainLongShortCount = new LongShortCount(signedRemainCount); if (remainLongShortCount.LongShort != this.LongShort) { // 이렇게 될리가 없다. String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return remainLongShortCount; }
List<PriceLongShortCount> GetPrice_Count_ForReqOrders(LongShortCount lsc, RawMarketData rmd, Boolean bOverAging) { List<PriceLongShortCount> arr = new List<PriceLongShortCount>(); if (lsc.Count < 2 || bOverAging) { double price = 0; if (lsc.LongShort == TradingDirection.Long) { price = ProductUtil.Ins().RoundProductPrice(rmd.Code, ProductUtil.Ins().GetOneTickUpPrice(rmd.Code, rmd.BidPrice1)); } else { price = ProductUtil.Ins().RoundProductPrice(rmd.Code, ProductUtil.Ins().GetOneTickDownPrice(rmd.Code, rmd.AskPrice1)); } PriceLongShortCount pc = new PriceLongShortCount(price, lsc); arr.Add(pc); } else { long count1 = (long)(lsc.Count / 2); long count2 = (long)lsc.Count - count1; double price1 = 0; double price2 = 0; if (lsc.LongShort == TradingDirection.Long) { price1 = ProductUtil.Ins().RoundProductPrice(rmd.Code, ProductUtil.Ins().GetOneTickUpPrice(rmd.Code, rmd.BidPrice1)); price2 = rmd.BidPrice1; } else { price1 = rmd.AskPrice1; price2 = ProductUtil.Ins().RoundProductPrice(rmd.Code, ProductUtil.Ins().GetOneTickDownPrice(rmd.Code, rmd.AskPrice1)); } PriceLongShortCount pc1 = new PriceLongShortCount(price1, new LongShortCount(lsc.LongShort, (ulong)count1)); PriceLongShortCount pc2 = new PriceLongShortCount(price2, new LongShortCount(lsc.LongShort, (ulong)count2)); if (pc1.LSC.Count > 0) { arr.Add(pc1); } if (pc2.LSC.Count > 0) { arr.Add(pc2); } } return arr; }
public void SetTarget(LongShortCount lsc) { this.CurSignedTargetCount = lsc.GetSignedCount(); if (this.InitSignedGoalCount * this.CurSignedTargetCount < 0) { // 부호가 반대이다. logger.Error( "Target count twisted(sign is different) {0:n0}, {1:n0}", this.CurSignedTargetCount, this.InitSignedGoalCount); Util.KillWithNotice("Target count twisted(sign is different)"); Trace.Assert(false); } if (Math.Abs(this.InitSignedGoalCount) < Math.Abs(this.CurSignedTargetCount)) { logger.Error( "Target count twisted(goal count) {0:n0}, {1:n0}", this.CurSignedTargetCount, this.InitSignedGoalCount); Util.KillWithNotice("Target count twisted(goal count)"); Trace.Assert(false); } }
public Boolean RequestSweepOrders(Boolean bOverAging, Boolean bCompleteQuickly) { try { // 현재 체결된 수량을 구한 뒤 TargetCount와의 차이를 통해 주문해야 하는 수량을 구하고 주문한다. long curContractedCount = POrderUtil.GetSignedContractedCount(this.RealOrders); long remainSignedCount = this.CurSignedTargetCount - curContractedCount; if (remainSignedCount == 0) { return true; // done } LongShortCount lsc = new LongShortCount(remainSignedCount); RawMarketData rmd = RmdManager.Ins().GetDataClone(this.Code); if (!Util.IsValidRMDTimeAndPrice(rmd)) { return false; } List<PriceLongShortCount> pcs = GetPrice_Count_ForReqOrders(lsc, rmd, bOverAging); List<POrder> orders = new List<POrder>(); foreach (PriceLongShortCount pc in pcs) { POrder o = new POrder(lsc.LongShort, this.Code, (long)pc.LSC.Count, pc.Price, this.AccountFO, rmd); orders.Add(o); } POrderUtil.RequestOrder(orders, this.RealOrders); return true; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return false; }
public Boolean Run() { try { if (this.SweepUnit.CurState == SweepUnitTemplate.StateEnum._4_WaitingRunSign) { _signedTargetCount = this.SweepUnit.Context.GetSignedContractedCount(); logger.Info("TestHTSSweeper [{0}] start ResumeSweep Target {1:n0}", SweepUnit.ID, _signedTargetCount); LongShortCount lsc = new LongShortCount(_signedTargetCount); SweepUnit.ResumeSweep(lsc); } Boolean bRunComplete1 = SweepUnit.Run(); if (bRunComplete1) { logger.Info( "TestHTSSweeper [{0}] {1} complete...", SweepUnit.ID, SweepUnit.Context.GetSignedContractedCount()); _bDone = true; return true; } if (SweepUnit.IsException()) { // 에러가 났다. logger.Error("TestHTSSweeper [{0}] Exception", SweepUnit.ID); Util.KillWithNotice("TestHTSSweeper Exception"); _bDone = true; return true; } return false; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); return true; } }
List<long> GetReqCounts(LongShortCount lsc, MarketType marketType) { List<long> list = new List<long>(); if (marketType == MarketType._0_Bond_일반) { // 한큐에 주문을 낸다. list.Add((long)lsc.Count); } else if (marketType == MarketType._1_Bond_소액) { long curCount = (long)lsc.Count; const long k50_000_000 = 50 * CommonConst._1_000 * CommonConst._1_000; while (true) { if (curCount <= 0) { break; } if (curCount <= k50_000_000) { list.Add(curCount); break; } list.Add(k50_000_000); curCount -= (k50_000_000); } } else if (marketType == MarketType._2_Bond_소매) { // 소매시장인 경우라면 한큐에 몽땅낸다. list.Add((long)lsc.Count); } return list; }
public Boolean RequestSweepOrders(Boolean bOverAging, Boolean bCompleteQuickly) { try { if (IsStateDone()) { return true; // done; } if (bOverAging) { // 이런일 없도록 해놓았다. Trace.Assert(false); } if (bCompleteQuickly) { // 이런일 없도록 해놓았다. Trace.Assert(false); } long curShortContractedCount = POrderUtil.GetSignedContractedCount(this.RealOrdersShort); long remainSignedCount = this.CurSignedTargetCount - curShortContractedCount; if (remainSignedCount == 0) { return true; // done } if (this.CurSignedTargetCount > 0) { // 매수였는데 여기로 오면 정말 이상한 것이다. logger.Error("매수인 경우 Sweep에서 바로 done상태가 되어야 정상이다."); Util.KillWithNotice("매수인 경우 Sweep에서 바로 done상태가 되어야 정상이다."); } LongShortCount lsc = new LongShortCount(remainSignedCount); // 매수인 것이 남아있을 수가 없다. Trace.Assert(lsc.LongShort == TradingDirection.Short); List<POrder> sweepOrders = GetSweepOrders(lsc); POrderUtil.RequestOrder(sweepOrders, this.RealOrdersShort); return true; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return false; }
public void SetTarget(LongShortCount lsc) { this.CurSignedTargetCount = lsc.GetSignedCount(); if (this.CurSignedTargetCount < 0) { Trace.Assert(false); } }
public void SyncWithMaxCompletePercent(double maxCompletePercent) { if (_State != State._1_MuteFewSecsForInitOrders) { return; } Trace.Assert(maxCompletePercent >= 0 && maxCompletePercent <= 100); double diffPercent = maxCompletePercent - GetPercent_AttemptOfTarget(); if (diffPercent <= 0) { // 이미 max complete percent보다 많이 시도한 상태이다. return; } long attempCount = POrderUtil.GetSignedMaxPossibleExposureCount(this.RealOrders); Trace.Assert(attempCount * this.CurSignedTargetCount >= 0); long newEnterAttemptCount = (long)((maxCompletePercent * this.CurSignedTargetCount) / 100) - attempCount; if (newEnterAttemptCount == 0) { return; } Trace.Assert(newEnterAttemptCount * this.CurSignedTargetCount >= 0); // newEnterAttempCount만큼 매매를 한다. if (this.RealOrders.Count >= 4) { // 4개 이상 내는 것은 이상하다. logger.Warn(String.Format("RealOrders.Count >= 4")); return; } LongShortCount lsc = new LongShortCount(newEnterAttemptCount); RawMarketData rmdClone = RmdManager.Ins().GetDataClone(this.Code); POrder o = new POrder(lsc.LongShort, this.Code, (long)lsc.Count, this.InitEnterPrice, this.AccountFO, rmdClone); o.AddComment("SweepUnit_FO.SyncWithMaxCompletePErcent"); if (o.ReqCount > 0) { RequestOrder_Raw(o, RealOrders); } else { o.Free(); } }
LongShortCount GetNewReqLongShortCount() { long futureMaxPossibleCount = Math.Abs(GetFutureMaxPossibleCount()); long newFutReqCount = this.UnsignedSpotContractedCount - futureMaxPossibleCount; if (newFutReqCount < 0) { String ex = "Invalid"; logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } LongShortCount lsc = new LongShortCount(this.TargetPosition.SignedFutureCount); return new LongShortCount(lsc.LongShort, Convert.ToUInt64(newFutReqCount)); }
List<long> SplitCountForSweepOrdersViaMarketType(LongShortCount lsc, MarketType marketType) { List<long> list = new List<long>(); Trace.Assert(marketType != MarketType._0_Bond_일반); // 1000원보다 작은 단위일리가 없다. 1000으로 나눈 나머지는 0이어야한다. UInt64 remain = lsc.Count % CommonConst._1_000; Trace.Assert(remain == 0); if (marketType == MarketType._1_Bond_소액) { long curCount = (long)lsc.Count; const long k50_000_000 = 50 * CommonConst._1_000 * CommonConst._1_000; while (true) { Trace.Assert(curCount >= 0); if (curCount == 0) { break; } if (curCount <= k50_000_000) { list.Add(curCount); break; } list.Add(k50_000_000); curCount -= (k50_000_000); } } else if (marketType == MarketType._2_Bond_소매) { // 소매시장인 경우라면 한큐에 몽땅낸다. list.Add((long)lsc.Count); } return list; }
List<POrder> GetSweepOrders(LongShortCount lsc) { // 매도할 가격을 우선 구한다. // 두 시장에서 모두 매도할 수 있는 가격중에 큰 값에 주문을 내도록 한다. double reqPrice = GetShortSweepPrice(); // 매도할 것이다. TradingDirection ls = TradingDirection.Short; // 주문은 일반-소액인 경우에는 소액, 일반-소매인 경우에는 소매에 주문을 내도록 한다. String sweepCode = GetSweepCode(); MarketType sweepMarketType = GetSweepMarketType(); Trace.Assert(sweepMarketType != MarketType._0_Bond_일반); RawMarketData rmdClone = RmdManager.Ins().GetDataClone(sweepCode); List<POrder> orders = new List<POrder>(); List<long> reqCounts = SplitCountForSweepOrdersViaMarketType(lsc, sweepMarketType); foreach (long reqCount in reqCounts) { POrder o = new POrder(ls, sweepCode, reqCount, reqPrice, BondAccount, rmdClone, sweepMarketType, false); o.ShortCutTargetOfContractCallBack = this; orders.Add(o); } return orders; }
public void SetTarget(LongShortCount lsc) { }
void CreateInitOrders(BondPair pair) { Trace.Assert(this.LongShort == TradingDirection.Long); LongShortCount lsc = new LongShortCount(pair.Count); List<long> reqCounts = GetReqCounts(lsc, this._enterMarketType); double reqPrice = this._initEnterPrice; TradingDirection ls = TradingDirection.Long; _initOrders = new List<POrder>(); foreach (long reqCount in reqCounts) { POrder o = new POrder(ls, this.EnterCode, reqCount, reqPrice, this.BondAccount, pair.GetEnterRMD(), BondUtil.GetMarketType(this.EnterCode), false); o.ShortCutTargetOfContractCallBack = this; _initOrders.Add(o); } }
public PriceLongShortCount(double price, LongShortCount lsc) { this.Price = price; this.LSC = lsc; }
public Boolean Run() { try { if ((_sweepUnitLong.CurState == SweepUnitTemplate.StateEnum._4_WaitingRunSign && _sweepUnitShort.CurState == SweepUnitTemplate.StateEnum._4_WaitingRunSign) || (_sweepUnitLong.CurState == SweepUnitTemplate.StateEnum._7_Done && _sweepUnitShort.CurState == SweepUnitTemplate.StateEnum._4_WaitingRunSign) || (_sweepUnitLong.CurState == SweepUnitTemplate.StateEnum._4_WaitingRunSign && _sweepUnitShort.CurState == SweepUnitTemplate.StateEnum._7_Done)) { long signedLongContractedCount = _sweepUnitLong.Context.GetSignedContractedCount(); LongShortCount lscLong = new LongShortCount(signedLongContractedCount); _sweepUnitLong.ResumeSweep(lscLong); _sweepUnitShort.ResumeSweep(lscLong); logger.Info("[Resume BondArb Sweeper] #{0:n0}, '{1}' ({2:n0} -> {3:n0})", this.ID, BondUtil.GetCodeNoTail(this.EnterCodeWithMarketType), this.EnterPrice, this.PairPrice); } Boolean bRunComplete1 = _sweepUnitLong.Run(); Boolean bRunComplete2 = _sweepUnitShort.Run(); if (bRunComplete1 && bRunComplete2) { _bDone = true; logger.Info("[End BondArb Sweeper] #{0:n0}, pnl({4:n0}), '{1}' ({2:n0} -> {3:n0})", this.ID, BondUtil.GetCodeNoTail(this.EnterCodeWithMarketType), this.EnterPrice, this.PairPrice, GetPnLIfDone()); return true; } return false; // 아직 할일이 남아있다. } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); return true; } }