示例#1
0
        public ElwArbReadyOrder(Account elwAccount, Account optionAccount)
        {
            try
            {
                this._elwAccount = elwAccount;
                this._optionAccount = optionAccount;

                List<double> strikes = OptionUtil.GetSortedStrikeList(CallPutFlag.Call);

                OptionTribe ot = null;

                foreach (double strike in strikes)
                {
                    ot = ElwOptionUtil.GetOptionTribe(strike, CallPutFlag.Call);
                    if (ot != null && ot.ElwInfos.Count > 0)
                    {
                        break;
                    }
                }

                if (ot == null)
                {
                    logger.Error("option tribe does not exist in ElwArbreadyOrder");
                    Util.KillWithNotice("option tribe does not exist in ElwArbreadyOrder");
                }

                this._elwInfo = ot.ElwInfos[0];

                if (this._elwInfo == null)
                {
                    logger.Error("elw info does not exist in ElwArbreadyOrder");
                    Util.KillWithNotice("elw info does not exist in ElwArbreadyOrder");
                }

                this._koi = ElwOptionUtil.GetKOIFromElwInfo(_elwInfo);

                if (this._koi == null)
                {
                    logger.Error("koi info does not exist in ElwArbreadyOrder");
                    Util.KillWithNotice("koi info does not exist in ElwArbreadyOrder");
                }
                this._elwLongPrice = 5;
                this._koiShortPrice = this._koi.UpLimit;
            }
            catch (System.Exception ex)
            {
                logger.Error(ex.ToString());
                Util.KillWithNotice(ex.ToString());
            }
        }
示例#2
0
        public static ElwOptionArbData GetElwOptionArbData(
            ElwInfo elw, 
            RawMarketData rmdElw, 
            KospiOptionInfo kospiOptionInfo, 
            RawMarketData rmdOption,
            long maxCountOfOptionPerOnce,
            double maxValueOfOptionPerOnce,
            Account optionAccount,
            Account elwAccount,
            Boolean bForward,
            Boolean bAgressiveReverseOn,
            long totalAttemptOptionCount)
        {
            PreData data = GetPreData(
                                elw,
                                rmdElw,
                                kospiOptionInfo,
                                rmdOption,
                                maxCountOfOptionPerOnce,
                                maxValueOfOptionPerOnce,
                                optionAccount,
                                elwAccount,
                                bForward,
                                bAgressiveReverseOn,
                                totalAttemptOptionCount);

            {
                ElwOptionArbData eoad = GetElwOptionArbData_WithProfit(data);
                if (eoad != null)
                {
                    return eoad;
                }
            }

            {
                ElwOptionArbData eoad = GetElwOptionArbData_WO_Profit(data);
                if (eoad != null)
                {
                    return eoad;
                }
            }

            return null;
        }
示例#3
0
        static Boolean IsCheapEnoughPassNabiTest(Boolean bForward, KospiOptionInfo koi, RawMarketData rmdElw, ElwInfo elw, long elwBookValue)
        {
            if (bForward)
            {
                // Long하려는 ELW가 싼지 결정해야 한다.

                double nextStrike = OptionUtil.GetNextStrike(koi.Strike);
                double nextStrike2 = OptionUtil.GetNextStrike(nextStrike);

                double preStrike = OptionUtil.GetPreStrike(koi.Strike);
                double preStrike2 = OptionUtil.GetPreStrike(preStrike);

                DateTime maturity = Util.GetSystemOptionMaturity();

                KospiOptionInfo koiNext = OptionUtil.GetKOI(nextStrike, koi.CallPut, maturity);
                KospiOptionInfo koiNext2 = OptionUtil.GetKOI(nextStrike2, koi.CallPut, maturity);

                KospiOptionInfo koiPre = OptionUtil.GetKOI(preStrike, koi.CallPut, maturity);
                KospiOptionInfo koiPre2 = OptionUtil.GetKOI(preStrike2, koi.CallPut, maturity);

                if (koiNext == null || koiNext2 == null || koiPre == null || koiPre2 == null)
                {
                    return false;
                }

                RawMarketData rmdNext = RmdManager.Ins().GetData(koiNext.Code);
                RawMarketData rmdNext2 = RmdManager.Ins().GetData(koiNext2.Code);

                RawMarketData rmdPre = RmdManager.Ins().GetData(koiPre.Code);
                RawMarketData rmdPre2 = RmdManager.Ins().GetData(koiPre2.Code);

                // Cur, Next, Next2로 나비 구성해본다. 나비 구성되면 true
                if (Util.IsValidRMDTimeAndPrice(rmdNext) && Util.IsValidRMDTimeAndPrice(rmdNext2))
                {
                    long left = ElwOptionUtil.GetOneOptionValueOfOption(rmdNext.BidPrice1) * 2;
                    long right = ElwOptionUtil.GetOneOptionValueOfOption(rmdNext2.AskPrice1) + elwBookValue;

                    if (left >= right)
                    {
                        return true;
                    }
                }

                if (Util.IsValidRMDTimeAndPrice(rmdPre) && Util.IsValidRMDTimeAndPrice(rmdPre2))
                {
                    long left = ElwOptionUtil.GetOneOptionValueOfOption(rmdPre.BidPrice1) * 2;
                    long right = ElwOptionUtil.GetOneOptionValueOfOption(rmdPre2.AskPrice1) + elwBookValue;

                    if (left >= right)
                    {
                        return true;
                    }
                }
                return false;
            }
            else
            {
                // Option Long, Elw Short인 상황
                double nextStrike = OptionUtil.GetNextStrike(koi.Strike);
                double preStrike = OptionUtil.GetPreStrike(koi.Strike);

                if (koi == null)
                {
                    return false;
                }

                DateTime maturity = Util.GetSystemOptionMaturity();

                KospiOptionInfo koiNext = OptionUtil.GetKOI(nextStrike, koi.CallPut, maturity);
                KospiOptionInfo koiPre = OptionUtil.GetKOI(preStrike, koi.CallPut, maturity);

                if (koiNext == null || koiPre == null)
                {
                    return false;
                }

                RawMarketData rmdNext = RmdManager.Ins().GetData(koiNext.Code);
                RawMarketData rmdPre = RmdManager.Ins().GetData(koiPre.Code);

                if (!Util.IsValidRMDTimeAndPrice(rmdNext) || !Util.IsValidRMDTimeAndPrice(rmdPre))
                {
                    return false;
                }

                long left = elwBookValue * 2;
                long right = ElwOptionUtil.GetOneOptionValueOfOption(rmdPre.AskPrice1) + ElwOptionUtil.GetOneOptionValueOfOption(rmdNext.AskPrice1);

                // ELW를 BidPrice1으로 숏하고 양 옆의 옵션을 AskPrice1으로 롱해도 Arb이 되는 상황이다.
                if (left >= right)
                {
                    return true;
                }
                return false;
            }
        }
示例#4
0
        static PreData GetPreData(
            ElwInfo elw,
            RawMarketData rmdElw,
            KospiOptionInfo kospiOptionInfo,
            RawMarketData rmdOption,
            long maxCountOfOptionPerOnce,
            double maxValueOfOptionPerOnce,
            Account optionAccount,
            Account elwAccount,
            Boolean bForward,
            Boolean bAgressiveReverseOn,
            long totalAttemptOptionCount)
        {
            PreData data = new PreData();

            // 기본 input
            data.Elw = elw;
            data.RmdElw = rmdElw;

            data.KOI = kospiOptionInfo;
            data.RmdOption = rmdOption;

            data.MaxCountOfOptionPerOnce = maxCountOfOptionPerOnce;
            data.MaxValueOfOptionPerOnce = maxValueOfOptionPerOnce;

            data.OptionAccount = optionAccount;
            data.ElwAccount = elwAccount;

            data.IsForward = bForward;
            data.IsAgressiveReverseOn = bAgressiveReverseOn;

            data.TotalAttemptOptionCount = totalAttemptOptionCount;

            // 가공 데이터
            data.ElwPrice = bForward ? rmdElw.AskPrice1 : rmdElw.BidPrice1;
            data.ElwCount = bForward ? rmdElw.AskCount1 : rmdElw.BidCount1;
            data.ElwLS = bForward ? TradingDirection.Long : TradingDirection.Short;

            data.OptionPrice = bForward ? Math.Round(rmdOption.BidPrice1, 2) : Math.Round(rmdOption.AskPrice1, 2);
            data.OptionCount = bForward ? rmdOption.BidCount1 : rmdOption.AskCount1;
            data.OptionLS = bForward ? TradingDirection.Short : TradingDirection.Long;

            data.OptionCountOfElw = ElwOptionUtil.ConvertElwCountToOptionCount(elw, data.ElwCount);

            data.ElwOneOptionValue = ElwOptionUtil.GetOneOptionValueOfElw(elw, data.ElwPrice);
            data.OptionOneOptionValue = ElwOptionUtil.GetOneOptionValueOfOption(data.OptionPrice);

            data.Diff = data.OptionOneOptionValue - data.ElwOneOptionValue;
            if (!bForward)
            {
                data.Diff *= (-1); // forward가 아니라면 부호를 반대로
            }

            return data;
        }
示例#5
0
        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());
            }
        }
        Boolean EnterNewDoorOrder(ElwInfo targetElw, KospiOptionInfo targetKOI, KospiOptionInfo doorKOI)
        {
            try
            {
                const double kDownBarrier = 0.1;
                const double kMinBuffer = 0.5;

                RawMarketData targetOptionRMD = RmdManager.Ins().GetDataClone(targetKOI.Code);
                RawMarketData doorOptionRMD = RmdManager.Ins().GetDataClone(doorKOI.Code);

                if (!Util.IsValidPrice(targetOptionRMD.BidPrice1))
                {
                    return false;
                }

                if (!Util.IsValidPrice(doorOptionRMD.BidPrice1))
                {
                    return false;
                }

                if (doorOptionRMD.BidPrice1 <= kDownBarrier)
                {
                    return false;
                }

                if (targetOptionRMD.BidPrice1 <= doorOptionRMD.BidPrice1)
                {
                    logger.Warn("{0} {1} <= {2} {3}",
                        targetOptionRMD.Code,
                        targetOptionRMD.BidPrice1,
                        doorOptionRMD.Code,
                        doorOptionRMD.BidPrice1);
                    return false;
                }

                String elwCode = targetElw.Code;

                double reqPrice = ElwOptionUtil.ConvertOptionPriceToElwPrice(targetElw, doorOptionRMD.BidPrice1);

                // same strike의 bidPrice - kMinBuffer 가격에 해당하는 price
                double reqPrice2 = ElwOptionUtil.ConvertOptionPriceToElwPrice(targetElw, Math.Max(0, targetOptionRMD.BidPrice1 - kMinBuffer));

                // reference bidPrice와 target(같은 strike의 옵션)의 bidPrice - 0.5 중에 작은 값을 take
                reqPrice = Math.Min(reqPrice, reqPrice2);

                // 5원보다 작으면 정말 이상한 것이다.
                if (reqPrice < 4)
                {
                    return false;
                }

                long reqCount = targetElw.MaxPossibleOrderCount;

                if (_parent.EnterMinCount)
                {
                    reqCount = 10; // 테스트 경우 무조건 10개 주문
                }

                Account account = _parent.Parent.ElwAccount;

                RawMarketData rmdElw = RmdManager.Ins().GetDataClone(elwCode);

                POrder o = new POrder(TradingDirection.Long, elwCode, reqCount, reqPrice, account, rmdElw);
                OrderLimitReferenceOOR limitReference = new OrderLimitReferenceOOR(OrderLimitReferenceOOR.OrderType.OOR, targetOptionRMD);
                o.LimitOrderReference = limitReference;

                POrderUtil.RequestOrder(o, this._orders);

                _parent.Parent.AddFishingOrder(o, STR_Door.FishingOrderType.Active);

                return true;
            }
            catch (System.Exception ex)
            {
                logger.Error(ex.ToString());
                Util.KillWithNotice(ex.ToString());
            }
            return false;
        }
示例#7
0
        void TakeOverPosition_Raw(KospiOptionInfo koi, ElwInfo elw, long optionCount, POrder optionOrder, POrder elwOrder)
        {
            ElwArbSweepUnit eos = new ElwArbSweepUnit(koi, elw, optionCount, optionOrder, elwOrder, _parent);

            logger.Info(
                "{0}\t{1}\t{2}\t ElwArbEach EOS is created...",
                koi.Code,
                elw.Code,
                optionCount.ToString("n0"));

            _lives.Add(eos);
        }
示例#8
0
        public ElwArbSweepUnit EnterPosition(
            ElwInfo elwInfo,
            String elwCode,
            TradingDirection elwLS,
            double elwPrice,
            long elwCount,
            RawMarketData rmdElw,

            TradingDirection optionLS,
            double optionPrice,
            long optionCount,
            RawMarketData rmdOption)
        {
            long optionEnterCount = optionCount;
            long elwEnterCount = elwCount;

            return EnterPosition_Raw(
                elwInfo,
                elwCode,

                elwLS,
                elwEnterCount,
                elwPrice,
                rmdElw,

                optionLS,
                optionCount,
                optionPrice,
                rmdOption);
        }
示例#9
0
 static double ConvertElwPriceToOptionPrice(ElwInfo elw, double elwPrice)
 {
     long elwCountOfOneOption = GetElwCountOfOneOption(elw.ChangeRate);
     return OptionUtil.RoundOptionPrice(elwPrice * elwCountOfOneOption / CommonConst._100_000);
 }
示例#10
0
 public static long ConvertElwCountToOptionCount(ElwInfo elw, long elwCount)
 {
     long elwCountOfOneOption = GetElwCountOfOneOption(elw.ChangeRate);
     long optionCount = (long)(elwCount / elwCountOfOneOption);
     return optionCount;
 }
示例#11
0
        public static long GetSignedParticleElwCount(ElwInfo elwInfo, List<POrder> orders)
        {
            long signedMaxPossibleExposureElwCount = 0;

            foreach (POrder o in orders)
            {
                if (o.Code.CompareTo(elwInfo.Code) == 0)
                {
                    signedMaxPossibleExposureElwCount += POrderUtil.GetSignedMaxPossibleExposureCount(o);
                }
            }

            long elwCountOfOneOption = GetElwCountOfOneOption(elwInfo.ChangeRate);

            long particle = signedMaxPossibleExposureElwCount % elwCountOfOneOption;
            return particle;
        }
示例#12
0
 public static long ConvertElwCountTo100k(ElwInfo elw, long elwCount)
 {
     return elwCount * elw.ChangeRate;
 }
示例#13
0
 public static long GetOneOptionValueOfElw(ElwInfo elw, double elwPrice)
 {
     return (long)(elwPrice * GetElwCountOfOneOption(elw.ChangeRate));
 }
示例#14
0
 public static KospiOptionInfo GetKOIFromElwInfo(ElwInfo ei)
 {
     DateTime maturity = Util.ConvertToDate(ei.Maturity);
     return OptionUtil.GetKOI(ei.Strike, ei.CallPut, maturity);
 }
示例#15
0
 public static double ConvertOptionPriceToElwPrice(ElwInfo elw, double optionPrice)
 {
     double marketValue = optionPrice * CommonConst._100_000;
     long elwCountOfOneOption = GetElwCountOfOneOption(elw.ChangeRate);
     double elwPrice = marketValue / elwCountOfOneOption;
     return ElwUtil.RoundElwPrice(elwPrice);
 }
示例#16
0
        public ElwOptionArbData(
            ElwInfo elw,
            double elwPrice,
            TradingDirection elwLS,

            KospiOptionInfo koi,
            double optionPrice,
            TradingDirection optionLS,

            long minOptionCount,

            long diff,
            
            RawMarketData rmdOption,
            RawMarketData rmdElw,
            Boolean bForward)
        {
            OptionCode = koi.Code;
            ElwCode = elw.Code;

            OptionCount = minOptionCount;
            ElwCount = ElwOptionUtil.ConvertOptionCountToElwCount(elw, minOptionCount);

            OptionPrice = optionPrice;
            ElwPrice = elwPrice;

            Elw = elw;
            Diff = diff;

            ElwLS = elwLS;
            OptionLS = optionLS;

            IsForward = bForward;

            Key = String.Format("{0};{1}", koi.Code, elw.Code);

            RmdOption = rmdOption;
            RmdElw = rmdElw;
        }
示例#17
0
 public static double ConvertElwCountToOptionCount_Double(ElwInfo elw, long elwCount)
 {
     long elwCountOfOneOption = GetElwCountOfOneOption(elw.ChangeRate);
     double optionCount = (double)elwCount / elwCountOfOneOption;
     return optionCount;
 }
示例#18
0
        static List<ElwInfo> LoadValidatedElwInfos()
        {
            List<ElwInfo> ret = new List<ElwInfo>();

            DBManager dbManager = new DBManager();
            MySqlConnection con = null;

            try
            {
                String ip = ConfigManager.Ins().Config.GetValue(ConfigKeyConst.DB_SERVER_IP);
                con = dbManager.CreateConnection(ip, CommonConst.DATABASE_MADVIPER);
                con.Open();

                String query = "select * from validated_elw_list";

                MySqlCommand cmd = new MySqlCommand(query, con);
                MySqlDataAdapter dataAdapter = new MySqlDataAdapter(cmd);

                DataSet ds = new DataSet("validated_elw_list");

                dataAdapter.Fill(ds, "validated_elw_list");
                DataRowCollection drc = ds.Tables["validated_elw_list"].Rows;

                if (drc.Count <= 0)
                {
                    return ret;
                }

                for (int i = 0; i < drc.Count; ++i)
                {
                    DataRow dr = drc[i];

                    String code = dr["code"].ToString();
                    String name = dr["name"].ToString();
                    long maturity = Convert.ToInt64(dr["maturity"]);
                    double strike = Convert.ToDouble(dr["strike"]);
                    int changeRate = Convert.ToInt32(dr["change_rate"]);
                    String callPut = dr["call_put"].ToString();
                    long issuedCount = Convert.ToInt64(dr["issued_count"]);

                    ElwInfo ei = new ElwInfo();
                    ei.Code = code;
                    ei.Name = name;
                    ei.Maturity = maturity;
                    ei.Strike = strike;
                    ei.ChangeRate = changeRate;
                    ei.CallPut = callPut.CompareTo("Call") == 0 ? CallPutFlag.Call : CallPutFlag.Put;
                    ei.IssuedCount = issuedCount;

                    ei.IsValidated = true;
                    ret.Add(ei);
                }

                ds.Clear();
            }
            catch (System.Exception ex)
            {
                logger.Error(ex.ToString());
                Util.KillWithNotice(ex.ToString());
            }
            finally
            {
                dbManager.Close(con);
            }
            return ret;
        }
示例#19
0
        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;
        }
示例#20
0
        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();
            }
        }
示例#21
0
        public void Load()
        {
            if (_bLoaded)
            {
                return;
            }
            _bLoaded = true;

            Dictionary<String, ElwInfo> elwInfos = new Dictionary<string, ElwInfo>();
            Dictionary<String, String> codeMap = new Dictionary<string, string>();

            DateTime dtElwMaturity = Util.GetSystemOptionMaturity();
            logger.Info("Elw maturity is ({0}) loaded from CONFIG", dtElwMaturity);

            LoadingData_Elw loadingData = GetLoadingData(dtElwMaturity);

            foreach (CP_LoadingDatum_Elw datum in loadingData.Data)
            {
                String underlyingCode = datum.UnderlyingCode;
                String underlyingName = datum.UnderlyingName;
                String code = datum.Code;
                String name = datum.Name;
                String callPut = datum._CallPut;
                long maturity = datum.Maturity;
                double strike = datum.Strike;
                int changeRate = datum.ChangeRate;
                double bidPrice = datum.BidPrice;
                double askPrice = datum.AskPrice;
                double curPrice = datum.CurPrice;
                double gearing = datum.Gearing;
                long issuedCount = datum.IssuedCount;
                long remainDays = datum.RemainDays;
                String longCode = datum.LongCode;

                ElwInfo data = new ElwInfo();
                data.UnderlyingCode = underlyingCode;
                data.UnderlyingName = underlyingName;
                data.Name = name;
                data.Code = code;
                data.RemainDays = remainDays;
                data.IssuedCount = issuedCount;
                data.MaxPossibleOrderCount = ElwUtil.RoundElwCount((long)(issuedCount * 0.05));
                data.YesterdayLastPrice = curPrice;

                if (callPut.CompareTo("콜") == 0)
                {
                    data.CallPut = CallPutFlag.Call;
                }
                else if (callPut.CompareTo("풋") == 0)
                {
                    data.CallPut = CallPutFlag.Put;
                }
                else
                {
                    logger.Error("Unexpected");
                    Util.KillWithNotice("Unexpected");
                }

                data.Maturity = maturity;
                data.Strike = Math.Round(strike, 2);
                data.ChangeRate = changeRate;

                if (data.ChangeRate != 200 &&
                    data.ChangeRate != 100 &&
                    data.ChangeRate != 50 &&
                    data.ChangeRate != 25 &&
                    data.ChangeRate != 80 &&
                    data.ChangeRate != 40)
                {
                    logger.Warn(String.Format("{0} has {1} change rate (discard from ArbList)", code, changeRate));
                    continue;
                }

                // 일단 Validated 하지 않다. DB와 비교를 통해서 검증한다.
                data.IsValidated = false;

                elwInfos.Add(code, data);
                codeMap.Add(longCode, code);

                if (longCode.Length == 0)
                {
                    logger.Error("CRITICAL ERROR Can't create longCode!!! {0}", code);
                    Util.KillWithNotice("CRITICAL ERROR Can't create longCode!!!");
                }
                RmdManager.Ins().Register(code, name, Detail.ProductType.ELW);
            }

            ElwUtil.SetInfo(elwInfos, codeMap);

            logger.Info("({0:n0} / {1:n0}) Elw load", elwInfos.Count, loadingData.Data.Count);
        }
        Boolean CancelDangerousOrders_Raw(POrder order, ElwInfo targetElw, KospiOptionInfo targetKOI, KospiOptionInfo doorKOI)
        {
            try
            {
                const double kBuffer = 0.3;

                RawMarketData targetOptionRMD = RmdManager.Ins().GetDataClone(targetKOI.Code);
                RawMarketData doorOptionRMD = RmdManager.Ins().GetDataClone(doorKOI.Code);

                Boolean bTargetRMDBidPriceValid = Util.IsValidPrice(targetOptionRMD.BidPrice1);
                Boolean bDoorRMDBidPriceValid = Util.IsValidPrice(doorOptionRMD.BidPrice1);

                if (!bTargetRMDBidPriceValid && !bDoorRMDBidPriceValid)
                {
                    // 둘다 값이 없으면 위험해 보인다. 이런 경우에는 취소를 한다.
                    return true;
                }

                if (bDoorRMDBidPriceValid)
                {
                    // reference를 바로 옆 옵션으로 했다.
                    // 바로 옆 옵션 가격보다 높은 가격으로 reqPrice했다면 위험한 상태이다.
                    double elwPriceOfOption = ElwOptionUtil.ConvertOptionPriceToElwPrice(targetElw, doorOptionRMD.BidPrice1);
                    if (elwPriceOfOption <= order.ReqPrice)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else if (bTargetRMDBidPriceValid)
                {
                    // target이 있다면 target BidPrice - kBuffer < reqPrice라면 위험한 상태이다.
                    double elwPriceOfOption = ElwOptionUtil.ConvertOptionPriceToElwPrice(targetElw, Math.Max(0, targetOptionRMD.BidPrice1 - kBuffer));
                    if (elwPriceOfOption <= order.ReqPrice)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch (System.Exception ex)
            {
                logger.Error(ex.ToString());
                Util.KillWithNotice(ex.ToString());
            }
            return true;
        }