public IEDoorEachMonitorEnterState Run( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData) { MonitorState.MonitorDataThisTurn monitorData = EDoorUtil.CreateThisTurnInput(eachData); return Run(centerData, eachData, monitorData); }
public PassiveSweepState(POrder o, EDoorCenterData centerData) { _enterOrder = o; _enterOrder.ShortCutTargetOfContractCallBack = this; // 주문을 취소한다. _enterOrder.CancelRemains(); // 채널을 하나 사용한다. // 여기서 등록한 채널은 centerData에서 알아서 완료되면 처리한다. centerData.IncreaseUsedChannelCount(_enterOrder); }
public IEDoorEachMonitorEnterState Run( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData) { Trace.Assert(eachData.LiveOrder != null); if (eachData.LiveOrder.IsCompleteGotOrderNumber()) { centerData.RemoveSweepStateOrder(eachData.LiveOrder); logger.Info("Change State Entering to Rebalance {0}", eachData.EI.Name); RebalanceState next = new RebalanceState(_parent); return next; } return this; }
Boolean IsOrderHigherThanKoi_2( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData, MonitorState.MonitorDataThisTurn monitorData) { double reqPrice = ElwOptionUtil.ConvertToOptionPrice( eachData.EI.Code, eachData.LiveOrder.ReqPrice); double bidPriceOfKoi_2 = monitorData.RmdKoi_2.BidPrice1; if (reqPrice > bidPriceOfKoi_2) { return true; } return false; }
Boolean IsRebalanceCondition( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData, MonitorState.MonitorDataThisTurn monitorData, ref String log) { if (_parent.Parent.BlockAfterCancel) { return true; } // 1. 옵션시세가 정상적인지 확인한다. if (EDoorUtil.IsAllValid(monitorData) && EDoorUtil.IsAllRefOK(monitorData)) { // 2. koi 2's bidPrice < optionPriceOfReqPrice라면 리밸런스 if (IsOrderHigherThanKoi_2(centerData, eachData, monitorData)) { log += "IsOrderHigherThanKoi_2 is true, "; return true; } // 3. 최전방 주문이 아니고 // 최전방 주문 + 1tick가격이 koi 3's bidPrice보다 작으면 // 리밸런싱 if (!IsFrontBidPrice(eachData, monitorData) && IsReqPricePlusOneLowerThanKoi_3(eachData, monitorData)) { log += "!IsFrontBidPrice and IsReqPricePlusOneLowerThanKoi_3 is true, "; return true; } return false; } else { // 옵션 시세가 정상적이지 않으면 리밸런스 케이스이다. log += "Market data is not valid, "; return true; } }
long CalculateReqCount(EDoorCenterData centerData, EDoorEachMonitorEnterData eachData) { long reqCount = 0; switch (centerData.CurEnterCountType) { case EDoorCenterData.EnterCountType.Ten: reqCount = 10; break; case EDoorCenterData.EnterCountType.Maximum: reqCount = eachData.EI.MaxPossibleOrderCount; break; default: break; } return reqCount; }
IEDoorEachMonitorEnterState Run( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData, MonitorDataThisTurn monitorData) { if (_parent.Parent.BlockAfterCancel) { // 취소후 더이상 집입 못한다. 따라서 그냥 리턴 return this; } // 1. Reference에 시세가 모두 있는지 확인한다. // 2. Reference사이에 가격 상태가 정상적인지 확인한다. if (EDoorUtil.IsAllValid(monitorData) && EDoorUtil.IsAllRefOK(monitorData)) { // 3. 진입할 가격을 구한다. double reqPrice = CalculateElwReqPrice(monitorData, eachData); // 4. 진입할 수량을 구한다. long reqCount = CalculateReqCount(centerData, eachData); if (reqPrice <= 0.0 || reqCount < 10) { // 가격 수량이 이상하다. return this; } // 5. 진입한다. if (EnterNewPosition(centerData, eachData, reqPrice, reqCount, monitorData.RmdElw, monitorData.RmdKoi_0)) { // 6. Entering state로 변환한다. String askPrice = (monitorData.RmdElw.AskPrice1 == double.MaxValue) ? "NaN" : "" + monitorData.RmdElw.AskPrice1; String bidPrice = (monitorData.RmdElw.BidPrice1 == double.MinValue) ? "NaN" : "" + monitorData.RmdElw.BidPrice1; logger.Info("Change State Monitor to Entering {0} ({1} ; {2:n0} ; {3})", eachData.EI.Name, bidPrice, reqPrice, askPrice); EnteringState state = new EnteringState(this._parent); return state; } } return this; }
Boolean EnterNewPosition(EDoorCenterData centerData, EDoorEachMonitorEnterData eachData, double reqPrice, long reqCount, RawMarketData rmdElw, RawMarketData rmdOption_0) { try { // 1. LiveOrder가 없는 상태인 것을 다시한번 확인한다. Trace.Assert(eachData.LiveOrder == null); Trace.Assert(eachData.CurEDoorOrderState == EDoorEachMonitorEnterData.EDoorOrderState.Idle); String elwCode = eachData.EI.Code; Account account = centerData.ElwAccount; POrder order = new POrder(TradingDirection.Long, elwCode, reqCount, reqPrice, account, rmdElw); // 2. 주문을 넣는다. OrderLimitReferenceOOR limitReference = new OrderLimitReferenceOOR( OrderLimitReferenceOOR.OrderType.OOR, rmdOption_0); order.LimitOrderReference = limitReference; order.ShortCutTargetOfContractCallBack = _parent; POrderUtil.RequestOrder(order, null); // 3. eachData의 LiveOrder를 설정한다. eachData.RequestOrderComplete(order); // 4. centerData의 사용 수량을 늘린다. centerData.IncreaseUsedChannelCount(order); return true; } catch (System.Exception ex) { logger.Error(ex.ToString()); Util.KillWithNotice(ex.ToString()); } return false; }
IEDoorEachMonitorEnterState Run( EDoorCenterData centerData, EDoorEachMonitorEnterData eachData, MonitorState.MonitorDataThisTurn monitorData) { // 리밸런스 해야 하는 상황인지 확인한다. String log = ""; if (IsRebalanceCondition(centerData, eachData, monitorData, ref log)) { // sweeper로 남은 주문 처리하고 모리터링 다시 시작 EDoorEachSweeperController sweeper = new EDoorEachSweeperController( eachData.LiveOrder, _parent.Parent.Parent.GetCenterData()); // sweeper 등록 _parent.Parent.Parent.GetSweeperController().Add(sweeper); eachData.ClearLiveOrder(); logger.Info("Change State Rebalance to MonitorState {0} ({1})", eachData.EI.Name, log); IEDoorEachMonitorEnterState next = new MonitorState(_parent); return next; } return this; }