Boolean ExecuteElwParticle(long particle, ref List<POrder> output, RawMarketData rmdElw) { const int MIN_PARTICLE_COUNT = 200; if (particle == 0) { return true; } TradingDirection ls = particle > 0 ? TradingDirection.Short : TradingDirection.Long; long uParticle = Math.Abs(particle); try { if (uParticle < 10) { logger.Error("ExecuteElwParticle, particle({0}) < 10", uParticle); Util.KillWithNotice("ExecuteElwParticle, particle < 10"); return true; } // particle만큼을 없애야 한다. 따라서 patricle만큼을 매도로 주문을 내면 된다. List<double> priceCandidate = POrderUtil.GetPriceCandidate(ls, ElwOrderGoal, rmdElw); if (!IsValidPrices(priceCandidate)) { return false; } if (uParticle > MIN_PARTICLE_COUNT) { long particle1 = ElwUtil.RoundElwCount(uParticle / 2); long particle2 = ElwUtil.RoundElwCount(uParticle - particle1); double reqPrice1 = (double)priceCandidate[1]; double reqPrice2 = (double)priceCandidate[2]; reqPrice1 = AdjustPrice(ls, reqPrice1, rmdElw); reqPrice2 = AdjustPrice(ls, reqPrice2, rmdElw); POrder o1 = new POrder( ls, ElwOrderGoal.Code, particle1, reqPrice1, ElwOrderGoal.TargetAccount, rmdElw); o1.AddComment(String.Format("EOS#({0}), Sweeper 7", CurID)); POrder o2 = new POrder( ls, ElwOrderGoal.Code, particle2, reqPrice2, ElwOrderGoal.TargetAccount, rmdElw); o2.AddComment(String.Format("EOS#({0}), Sweeper 8", CurID)); output.Add(o1); output.Add(o2); } else { double reqPrice = (double)priceCandidate[2]; reqPrice = AdjustPrice(ls, reqPrice, rmdElw); POrder o = new POrder( ls, ElwOrderGoal.Code, ElwUtil.RoundElwCount(uParticle), reqPrice, ElwOrderGoal.TargetAccount, rmdElw); o.AddComment(String.Format("EOS#({0}), Sweeper 9", CurID)); output.Add(o); } } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return false; }
ElwArbSweepUnit EnterPosition_Raw( ElwInfo elwInfo, String elwCode, TradingDirection elwLS, long elwEnterCount, double elwPrice, RawMarketData rmdElw, TradingDirection optionLS, long optionEnterCount, double optionPrice, RawMarketData rmdOption) { POrder optionOrder = null; POrder elwOrder = null; try { { // ELW Long // 우선 ELW Long을 진행하도록 한다. Detail.ProductType pt = ProductUtil.Ins().GetProductType(elwCode); if (pt != Detail.ProductType.ELW) { logger.Error( "CRITICAL ERROR!!! 엄청 무서운 일이 벌어졌다. ELW가 아닌 {0} 종목이 {1} 가격에 {2} 개 사려고 했다.", elwCode, elwPrice, elwEnterCount); Util.KillWithNotice("error"); _bFinish = true; return null; } else { // ELW 롱 elwOrder = new POrder(elwLS, elwCode, elwEnterCount, elwPrice, _elwAccount, rmdElw); elwOrder.AddComment("EAE.EnterPosition_Raw.elwOrder"); elwOrder.Free(); if (!POrderLegalManager.Ins().IsLegalOrder(elwOrder, false)) { return null; } } } { // 옵션 숏 // 그럴리 없겠지만 무서우니까 최종적으로 확인을 한번 더 해보자. Detail.ProductType pt = ProductUtil.Ins().GetProductType(_KospiOptionInfo.Code); if (pt != Detail.ProductType.CallOption && pt != Detail.ProductType.PutOption) { logger.Error( "CRITICAL ERROR!!! 엄청 무서운 일이 벌어졌다. 옵션도 아닌 {0} 종목이 {1} 가격에 {2} 개 사려고 했다.", _KospiOptionInfo.Code, optionPrice, optionEnterCount); Util.KillWithNotice("CRITICAL ERROR!!!"); _bFinish = true; return null; } else { optionOrder = new POrder(optionLS, _KospiOptionInfo.Code, optionEnterCount, optionPrice, _optionAccount, rmdOption); optionOrder.AddComment("EAE.EnterPosition_Raw.optionOrder"); optionOrder.Free(); if (!POrderLegalManager.Ins().IsLegalOrder(optionOrder, false)) { return null; } } } if (optionOrder != null && elwOrder != null) { ElwArbSweepUnit eos = new ElwArbSweepUnit( _KospiOptionInfo, elwInfo, _optionAccount, optionOrder, _elwAccount, elwOrder, _parent, MonitoringEndDate); return eos; } else { logger.Error("Unexpected"); Util.KillWithNotice("Unexpected"); } } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return null; }
void CreateElwOrders(TradingDirection ls, long optionCount, double elwPrice1, double elwPrice2, ref ArrayList output, RawMarketData rmd) { if (optionCount >= 2) { double reqPrice1 = elwPrice1; double reqPrice2 = elwPrice2; reqPrice1 = AdjustPrice(ls, reqPrice1, rmd); reqPrice2 = AdjustPrice(ls, reqPrice2, rmd); long reqCount2 = optionCount / 2; long reqCount1 = optionCount - reqCount2; reqCount1 = ElwUtil.RoundElwCount(ElwOptionUtil.ConvertOptionCountToElwCount(_elwInfo, reqCount1)); reqCount2 = ElwUtil.RoundElwCount(ElwOptionUtil.ConvertOptionCountToElwCount(_elwInfo, reqCount2)); POrder o1 = new POrder( ls, ElwOrderGoal.Code, reqCount1, reqPrice1, ElwOrderGoal.TargetAccount, rmd); o1.AddComment(String.Format("EOS#({0}), Sweeper 1", CurID)); POrder o2 = new POrder( ls, ElwOrderGoal.Code, reqCount2, reqPrice2, ElwOrderGoal.TargetAccount, rmd); o2.AddComment(String.Format("EOS#({0}), Sweeper 2", CurID)); output.Add(o1); output.Add(o2); } else { double reqPrice1 = elwPrice1; reqPrice1 = AdjustPrice(ls, reqPrice1, rmd); long reqCount1 = ElwUtil.RoundElwCount(ElwOptionUtil.ConvertOptionCountToElwCount(_elwInfo, optionCount)); POrder o1 = new POrder( ls, ElwOrderGoal.Code, reqCount1, reqPrice1, ElwOrderGoal.TargetAccount, rmd); o1.AddComment(String.Format("EOS#({0}), Sweeper 3", CurID)); output.Add(o1); } }
void CreateOptionOrders(TradingDirection ls, long optionCount, double optionPrice1, double optionPrice2, ref List<POrder> output, RawMarketData rmd) { if (optionCount >= 2) { double reqPrice1 = optionPrice1; double reqPrice2 = optionPrice2; reqPrice1 = AdjustPrice(ls, reqPrice1, rmd); reqPrice2 = AdjustPrice(ls, reqPrice2, rmd); long reqCount2 = optionCount / 2; long reqCount1 = optionCount - reqCount2; POrder o1 = new POrder( ls, OptionOrderGoal.Code, reqCount1, reqPrice1, OptionOrderGoal.TargetAccount, rmd); o1.AddComment(String.Format("EOS#({0}), Sweeper 4", CurID)); POrder o2 = new POrder( ls, OptionOrderGoal.Code, reqCount2, reqPrice2, OptionOrderGoal.TargetAccount, rmd); o2.AddComment(String.Format("EOS#({0}), Sweeper 5", CurID)); output.Add(o1); output.Add(o2); } else { double reqPrice1 = optionPrice1; reqPrice1 = AdjustPrice(ls, reqPrice1, rmd); POrder o1 = new POrder( ls, OptionOrderGoal.Code, optionCount, reqPrice1, OptionOrderGoal.TargetAccount, rmd); o1.AddComment(String.Format("EOS#({0}), Sweeper 6", CurID)); output.Add(o1); } }
void RequestInitOrder(POrder goalOrder, List<POrder> realOrders) { POrder o = new POrder(goalOrder); o.AddComment(String.Format("EOS#({0}), GoalOrder", CurID)); o.SetAsLegalPrice(); o.ConvertOverPriceToInRMDPriceIfNotZero(); POrderUtil.RequestOrder(o, realOrders); }
public ElwArbSweepUnit( KospiOptionInfo koi, ElwInfo elwInfo, long optionCount, POrder optionOrder, POrder elwOrder, STR_ElwArb parent) { try { // 이 생성자는 인수인계를 받을 때만 사용하도록 한다. // 주의한다. _state = State._5_Done; if (optionOrder.LongShort == elwOrder.LongShort) { logger.Error("OptionOrder, ElwOrder same trading direction"); Util.KillWithNotice("OptionOrder, ElwOrder same trading direction"); throw new Exception(); } OptionAccount = null; ElwAccount = null; long elwCount = ElwOptionUtil.ConvertOptionCountToElwCount(elwInfo, optionCount); OptionOrderGoal = new POrder( TradingDirection.Short, optionOrder.Code, optionCount, optionOrder.ReqPrice, optionOrder.TargetAccount, optionOrder.RMDClone, MarketType._3_Default, true); OptionOrderGoal.AddComment("ElwOptionSweeper.TakeOver.OptionOrderGoal"); OptionOrderGoal.UpdateForRemain(OptionOrderGoal.ReqCount, OptionOrderGoal.InitReqPrice); ElwOrderGoal = new POrder( TradingDirection.Long, elwOrder.Code, elwCount, elwOrder.ReqPrice, elwOrder.TargetAccount, elwOrder.RMDClone, MarketType._3_Default, true); ElwOrderGoal.AddComment("ElwOptionSweeper.TakeOver.ElwOrderGoal"); ElwOrderGoal.UpdateForRemain(ElwOrderGoal.ReqCount, ElwOrderGoal.InitReqPrice); ElwOrdersReal = new List<POrder>(); OptionOrdersReal = new List<POrder>(); POrder elwOrderReal = new POrder(ElwOrderGoal); elwOrderReal.AddComment("ElwOptionSweeper.TakeOver.elwOrderReal"); elwOrderReal.UpdateForRemain(elwOrderReal.ReqCount, elwOrderReal.InitReqPrice); ElwOrdersReal.Add(elwOrderReal); POrder optionOrderReal = new POrder(OptionOrderGoal); optionOrderReal.AddComment("ElwOptionSweeper.TakeOver.optionOrderReal"); optionOrderReal.UpdateForRemain(optionOrderReal.ReqCount, optionOrderReal.InitReqPrice); OptionOrdersReal.Add(optionOrderReal); _parent = parent; KOI = koi; Key = String.Format("{0};{1}", OptionOrderGoal.Code, ElwOrderGoal.Code); IsBodySweepQuickly = false; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } }
public ElwArbSweepUnit( KospiOptionInfo koi, ElwInfo elwInfo, Account optionAccount, POrder optionOrder, Account elwAccount, POrder elwOrder, STR_ElwArb parent, DateTime dtEnd) { try { KOI = koi; CurID = ++ID_GENERATOR; OptionAccount = optionAccount; OptionOrderGoal = optionOrder; OptionOrderGoal.AddComment("EOS Constructor"); ElwAccount = elwAccount; ElwOrderGoal = elwOrder; ElwOrderGoal.AddComment("EOS Constructor"); _elwInfo = elwInfo; OptionOrdersReal = new List<POrder>(); ElwOrdersReal = new List<POrder>(); _state = State._1_MuteFewSecs; Key = String.Format("{0};{1}", OptionOrderGoal.Code, ElwOrderGoal.Code); ShowState(); _mute = new Timer(ENTER_POSITION_MUTE, ""); RequestInitOrder(ElwOrderGoal, ElwOrdersReal); _parent = parent; _parent.IncreaseEnteredArbCount(KOI.Code, OptionOrderGoal.ReqCount); _dtEnd = dtEnd; IsBodySweepQuickly = false; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } finally { ElwAccount.DiffFastExactPossibleShortCount(ElwOrderGoal.Code, "ElwOptionSweeper 생성자"); OptionOrderGoal.Free(); optionOrder.Free(); ElwOrderGoal.Free(); elwOrder.Free(); } }
void ReqOrderStepBehindPart(POrder goal, List<POrder> real, double targetExposurePercent, RawMarketData rmd) { double curExposurePercent = GetCurExposurePercent(goal, real); double diffExposure = targetExposurePercent - curExposurePercent; if (diffExposure <= 0) { return; } long goalCount = POrderUtil.GetSignedReqCount(goal); long reqCount = (long)(Math.Round(diffExposure * goalCount / 100, 0)); long curCount = POrderUtil.GetSignedMaxPossibleExposureCount(real); if (Math.Abs(goalCount) < Math.Abs(reqCount + curCount)) { //reqCount = goalCount - curCount; logger.Error("({0}, {1}, {2})", reqCount, goalCount, curCount); Util.KillWithNotice("error"); return; } if (reqCount != 0) { reqCount = Math.Abs(reqCount); if (goal.TargetAccount.LineType == Account.OrderLineType.StockSpotLine) { reqCount = ElwUtil.RoundElwCount(reqCount); } POrder o = new POrder( goal.LongShort, goal.Code, reqCount, goal.ReqPrice, goal.TargetAccount, rmd); o.AddComment(String.Format("EOS#({0}), StepBehindPart, {1}", CurID, o.Code)); o.SetAsLegalPrice(); o.ConvertOverPriceToInRMDPriceIfNotZero(); POrderUtil.RequestOrder(o, real); } }
void _bizServer_ReceiveResult(int nRowSize, int nColSize) { try { if (_bDone) { return; } _remainPOrders.Clear(); // 결과 처리 Array pArr = Array.CreateInstance(typeof(string), nRowSize, nColSize); _bizServer.GetRepeatResult(ref pArr); int rowCount = pArr.GetUpperBound(0); int colCount = pArr.GetUpperBound(1); if (rowCount == 0) { logger.Warn(String.Format("{0} No header info in account exposure query", _accountName)); _bDone = true; return; } Dictionary<String, int> _dic = new Dictionary<string, int>(); for (int iCol = 0; iCol <= colCount; iCol++) { String name = Convert.ToString(pArr.GetValue(0, iCol)).Trim(); _dic.Add(name, iCol); logger.Info(name); } // 여기서 원하는 Col을 알아낸다. for (int iRow = 1; iRow <= rowCount; iRow++) { String code = Convert.ToString(pArr.GetValue(iRow, _dic["종목코드"])); double reqPrice = Convert.ToDouble(pArr.GetValue(iRow, _dic["주문가격"])); long reqCount = Convert.ToInt64(pArr.GetValue(iRow, _dic["주문수량"])); int originOrderNumber = Convert.ToInt32(pArr.GetValue(iRow, _dic["원주문번호"])); int orderNumber = Convert.ToInt32(pArr.GetValue(iRow, _dic["주문번호"])); String 호가구분명 = Convert.ToString(pArr.GetValue(iRow, _dic["호가구분명"])); String 호가구분 = Convert.ToString(pArr.GetValue(iRow, _dic["호가구분"])); String 정정취소구분명 = Convert.ToString(pArr.GetValue(iRow, _dic["정정취소구분명"])); String 정정취소구분 = Convert.ToString(pArr.GetValue(iRow, _dic["정정취소구분"])); String 매매구분명 = Convert.ToString(pArr.GetValue(iRow, _dic["매매구분명"])); String 매도수구분 = Convert.ToString(pArr.GetValue(iRow, _dic["매도수구분"])); String 종목유형구분 = Convert.ToString(pArr.GetValue(iRow, _dic["종목유형구분"])); String 주문처리명 = Convert.ToString(pArr.GetValue(iRow, _dic["주문처리명"])); String 주문처리유형 = Convert.ToString(pArr.GetValue(iRow, _dic["주문처리유형"])); String 정정취소수량 = Convert.ToString(pArr.GetValue(iRow, _dic["정정/취소수량"])); String 정정취소가능수량 = Convert.ToString(pArr.GetValue(iRow, _dic["정정/취소가능수량"])); TradingDirection longShort = TradingDirection.Long; if (매도수구분.CompareTo("2") == 0) { longShort = TradingDirection.Long; } else if (매도수구분.CompareTo("1") == 0) { longShort = TradingDirection.Short; } else { logger.Error("Invalid long/short flag ({0})", 매도수구분); Util.KillWithNotice("Invalid long/short flag"); return; } RawMarketData rmd = RmdManager.Ins().GetData(code); POrder o = new POrder(longShort, code, reqCount, reqPrice, null, rmd); o.AddComment("ARHPO"); o.OrderNumber = orderNumber; _remainPOrders.Add(o); // 미체결이므로 ContractedCount = 0이다. } // 모두 잘 받았다. logger.Info("{0}의 기존 미체결 정보를 모두 받았습니다.", _accountName); _bDone = true; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } }
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(); } }
void MakePOrder() { foreach (RawPOrderData rpd in _elwRemains.Values) { RawMarketData rmd = RmdManager.Ins().GetData(rpd.Code); if (rmd == null) { logger.Warn(String.Format("{0} code does not exist. is is ok the day after maturity", rpd.Code)); continue; } POrder o = new POrder(TradingDirection.Long, rpd.Code, rpd.ReqCount, rpd.ReqPrice, _account, rmd); o.AddComment("ADHR_SPOT"); o.OrderNumber = 0; o.UpdateForRemain(rpd.ReqCount, rpd.ReqPrice); _remainPOrders.Add(o); } }
Boolean MakeOrder_Raw(RawMarketData rmd, long remainCount100k, Dictionary<String, long> blocksLB, ref List<POrder> newOrders, ref String log) { if (remainCount100k == 0) { log += "remainCount100k == 0"; return true; } long signedRealCount = ElwOptionUtil.Convert100KToRealCount(rmd.Code, remainCount100k); if (signedRealCount == 0 || remainCount100k - ElwOptionUtil.ConvertRealToCount100k(rmd.Code, signedRealCount) != 0) { log += String.Format("signRealCount({0}) remainCount100k({1}) code({2})|", signedRealCount, remainCount100k, rmd.Code); return false; } long reqCount = Math.Abs(signedRealCount); TradingDirection ls = TradingDirection.Long; if (signedRealCount < 0) { ls = TradingDirection.Short; if (!blocksLB.ContainsKey(rmd.Code)) { log += String.Format("[22], {0}|", rmd.Code); return false; } if (blocksLB[rmd.Code] < Math.Abs(signedRealCount)) { log += String.Format("[23] BlockLB[{2}]({0}) < signedRealCount({1})", blocksLB[rmd.Code], signedRealCount, rmd.Code); return false; } reqCount = Math.Abs(signedRealCount); long tmp = ProductUtil.Ins().RoundProductCount(Math.Abs(reqCount), rmd.DPT); if (tmp != reqCount) { logger.Error("tmp({0}) != reqCount({1}) in MakeOrder_Raw", tmp, reqCount); Util.KillWithNotice("tmp != reqCount in MakeOrder_Raw"); } } Account account = _accountFO; if (rmd.DPT == Detail.ProductType.ELW || rmd.DPT == Detail.ProductType.Stock) { account = _accountSpot; } double price = ProductUtil.Ins().GetMidPrice(rmd); price = AdjustPrice(ls, rmd, price); POrder o = new POrder(ls, rmd.Code, reqCount, price, account, rmd); o.AddComment("SweepUnit_OE.MakeOrder_Raw"); log += String.Format("[23], {0}|", o.ToString()); if (o.ReqCount > 0) { // 여기서 Reserve하고 법적 문제가 있는지 확인한다. o.SetAsLegalPrice(); o.ConvertOverPriceToInRMDPriceIfNotZero(); log += String.Format("[24], {0}|", o.ToString()); newOrders.Add(o); } else { o.Free(); log += String.Format("[24], ReqCount <= 0"); return false; } long ret = remainCount100k - ElwOptionUtil.ConvertRealToCount100k(rmd.Code, signedRealCount); if (ret != 0) { logger.Error( "CRITICAL ERROR!!! in MakeOrder_Raw ret != 0 ret({0}), remainCount100k({1}), signedRealCount({2}), Code({3})", ret, remainCount100k, signedRealCount, rmd.Code); Util.KillWithNotice("CRITICAL ERROR!!! in MakeOrder_Raw"); return false; } return true; }
public void SyncWithTargetOptionExposure(long targetOptionExposure) { try { if (_State != State._1_MuteFewSecs) { return; } double multipliedTargetOptionExposure = Math.Abs(targetOptionExposure) * _multiplier; double exposure = GetPossibleOptionExposure(); double remainTargetOption = multipliedTargetOptionExposure - exposure; long remainTargetOptionCount = (long)remainTargetOption; logger.Info( "[key({3}) SyncWithTOE] {0:n} + {1:n} = {2:n}", multipliedTargetOptionExposure, exposure, remainTargetOption, ID); if ((remainTargetOption > 0 && GoalOrder.LongShort == TradingDirection.Long) || (remainTargetOption < 0 && GoalOrder.LongShort == TradingDirection.Short)) { long reqCount = ElwOptionUtil.ConvertFOCountToReal(GoalOrder.Code, Math.Abs(remainTargetOptionCount)); if (reqCount > GoalOrder.ReqCount) { logger.Error("ReqCount({0:n}) > GoalCount({1:n})", reqCount, GoalOrder.ReqCount); Util.KillWithNotice("ReqCount > GoalCount"); return; } if (RealOrders.Count >= 4) { // 4개 이상 내는 것은 이상하다. logger.Warn(String.Format("RealOrders.Count >= 4")); return; } POrder o = new POrder( GoalOrder.LongShort, GoalOrder.Code, reqCount, GoalOrder.ReqPrice, GoalOrder.TargetAccount, GoalOrder.RMDClone); o.AddComment("SweepUnit_OE.SyncWithTargetOptionExposure"); if (o.ReqCount > 0) { RequestOrder_Raw(o, RealOrders); } else { o.Free(); } } } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } }