private void kiwoomApi_OnReceiveRealCondition(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealConditionEvent e) { // 실시간 조건검색 요청으로 종목 편입 확인 (type - I : 종목편입, D : 종목이탈) if (e.strType.Equals("I")) { //Console.WriteLine("조건검색 실시간 편입 [" + e.sTrCode + "]"); DetectionStock conditionStock = conditionStocks.SingleOrDefault(item => item.StockNo.Equals(e.sTrCode)); if (conditionStock != null) { //conditionStock.Status = "재편입"; //conditionStock.NewTransferPrice = null; conditionStock.Status = "편입"; conditionStock.TransferPrice = null; conditionStock.upTransferCnt(); conditionStock.DetectionTime = DateTime.Now.ToString("HHmmss"); } else { conditionStocks.Add(new DetectionStock(e.sTrCode, kiwoomApi.GetMasterCodeName(e.sTrCode), maxStock >= holdings.Count)); requestRealtimeQuote(SCREEN_NO_CONDITION, e.sTrCode, conditionStocks.Count > 0 ? REALTIME_ADD : REALTIME_NEW); } // 실시간으로 여러 종목을 가져올 경우는 없는가? 확인이 필요할듯.. } else if (e.strType.Equals("D")) { //Console.WriteLine("조건검색 실시간 이탈 [" + e.sTrCode + "]"); DetectionStock conditionStock = conditionStocks.SingleOrDefault(item => item.StockNo.Equals(e.sTrCode)); if (conditionStock != null) { conditionStock.Status = "이탈"; conditionStock.TransferPrice = null; //removeRealtimeQuote(SCREEN_NO_CONDITION, e.sTrCode); } } }
private void kiwoomApi_OnReceiveRealData(object sender, AxKHOpenAPILib._DKHOpenAPIEvents_OnReceiveRealDataEvent e) { if (!isRunning) { return; } if (DateTime.Now.Hour > 13) { buttonStop.PerformClick(); } //Console.WriteLine("[DEBUG] OnReceiveRealData - e.sRealKey : " + e.sRealKey + ", e.sRealType : " + e.sRealType + ", e.sRealData : " + e.sRealData); // 보유 종목에 있을 경우 값 업데이트 string market = kiwoomApi.GetCommRealData(e.sRealKey, 290).Trim(); if (market.Equals("2")) { if (orders.Count > 0) { foreach (OrderStock order in orders) { if (order.AfterOrder > ORDER_TIMEOUT && !order.Canceled) { log(LogMode.TRADE, "주문번호 " + order.OrderNo + "의 주문이 오래되어 해당 주문을 취소합니다. (" + order.AfterOrder + "초)"); order.Canceled = true; cancelOrder(order.OrderType.Equals("매수") ? ORDER_TYPE_BUY_CANCEL : ORDER_TYPE_SELL_CANCEL, order.StockNo, order.OrderNo); } } } HoldStock holding = holdings.SingleOrDefault(item => item.StockNo.Contains(e.sRealKey)); if (holding != null) { long currentPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 10).Trim(), @"[^0-9]", "")); holding.CurrentPrice = String.Format("{0:#,###0}", currentPrice); long dayHighPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 17).Trim(), @"[^0-9]", "")); holding.DayHighPrice = String.Format("{0:#,###0}", dayHighPrice); long dayLowPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 18).Trim(), @"[^0-9]", "")); holding.DayLowPrice = String.Format("{0:#,###0}", dayLowPrice); if (holding.isProfit) { log(LogMode.TRADE, holding.StockName + "(" + holding.StockNo + ") 종목이 익절가(" + holding.TargetLine + ")에 도달하여 익절 합니다. (매수가 : " + holding.BuyPrice + ", 매수 횟수 : " + holding.BuyCnt + ", 수익 : " + float.Parse(holding.ProfitRate) + "%)"); holding.Ordered = "주문"; if (!order(ORDER_TYPE_SELL, holding.StockNo, int.Parse(holding.Qty, System.Globalization.NumberStyles.AllowThousands), int.Parse(currentPrice.ToString()), ORDER_HOGA_MARKET)) { holding.Ordered = "대기"; } } else if (holding.Ordered.Equals("대기") && long.Parse(holding.SecondBuyPrice, System.Globalization.NumberStyles.AllowThousands) > currentPrice && holding.BuyCnt == 1) { // 2차 매수가에 도달하면 손절 log(LogMode.TRADE, holding.StockName + "(" + holding.StockNo + ") 종목이 손절가(" + holding.SecondBuyPrice + ")에 도달하여 손절 합니다. (매수가 : " + holding.BuyPrice + ", 손익 : " + float.Parse(holding.ProfitRate) + "%)"); holding.Ordered = "주문"; if (!order(ORDER_TYPE_SELL, holding.StockNo, int.Parse(holding.Qty, System.Globalization.NumberStyles.AllowThousands), int.Parse(currentPrice.ToString()), ORDER_HOGA_MARKET)) { holding.Ordered = "대기"; } /*} else if (holding.Ordered.Equals("대기") && long.Parse(holding.SecondBuyPrice, System.Globalization.NumberStyles.AllowThousands) > currentPrice && holding.BuyCnt == 1) * { * // 2차 매수가 주문 * holding.Ordered = "주문"; * holding.BuyCnt = holding.BuyCnt + 1; * log(LogMode.TRADE, holding.StockName + "(" + holding.StockNo + ") 종목이 2차 매수가에 도달하여 주문 합니다. (" + holding.CurrentPrice + "원)"); * if(!order(ORDER_TYPE_BUY, holding.StockNo, (oneTimeAmount / int.Parse(currentPrice.ToString())), int.Parse(currentPrice.ToString()), ORDER_HOGA_LIIMIT)) * { * holding.BuyCnt = holding.BuyCnt - 1; * } * } else if (holding.Ordered.Equals("대기") && long.Parse(holding.ThirdBuyPrice, System.Globalization.NumberStyles.AllowThousands) > currentPrice && holding.BuyCnt == 2) * { * // 3차 매수가 주문. 기본 2배 물량 * holding.Ordered = "주문"; * holding.BuyCnt = holding.BuyCnt + 1; * log(LogMode.TRADE, holding.StockName + "(" + holding.StockNo + ") 종목이 3차 매수가에 도달하여 주문 합니다. (" + holding.CurrentPrice + "원)"); * if(!order(ORDER_TYPE_BUY, holding.StockNo, (oneTimeAmount / int.Parse(currentPrice.ToString())) * 2, int.Parse(currentPrice.ToString()), ORDER_HOGA_LIIMIT)) * { * holding.Ordered = "대기"; * holding.BuyCnt = holding.BuyCnt - 1; * }*/ } } DetectionStock conditionStock = conditionStocks.SingleOrDefault(item => item.StockNo.Contains(e.sRealKey)); if (conditionStock != null) { long currentPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 10).Trim(), @"[^0-9]", "")); conditionStock.CurrentPrice = String.Format("{0:#,###0}", currentPrice); //conditionStock.NewTransferPrice = String.Format("{0:#,###0}", currentPrice); long dayHighPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 17).Trim(), @"[^0-9]", "")); conditionStock.DayHighPrice = String.Format("{0:#,###0}", dayHighPrice); long dayLowPrice = long.Parse(Regex.Replace(kiwoomApi.GetCommRealData(e.sRealKey, 18).Trim(), @"[^0-9]", "")); conditionStock.DayLowPrice = String.Format("{0:#,###0}", dayLowPrice); if (string.IsNullOrEmpty(conditionStock.TransferPrice) || long.Parse(conditionStock.TransferPrice, System.Globalization.NumberStyles.AllowThousands) < 1) { conditionStock.TransferPrice = conditionStock.CurrentPrice; } float fluctuationRate = float.Parse(kiwoomApi.GetCommRealData(e.sRealKey, 12).Trim()); conditionStock.FluctuationRate = String.Format("{0:f2}", fluctuationRate); // 1차 매수가에 도달하면 매수 -> 1차 매수 도달 시 매수 대기했다가 돌파하면 매수하는 방식은? if (currentPrice < oneTimeAmount && !conditionStock.Status.Equals("이탈") && conditionStock.Ordered.Equals("대기") && long.Parse(conditionStock.TargetPrice, System.Globalization.NumberStyles.AllowThousands) > 0 && long.Parse(conditionStock.TargetPrice, System.Globalization.NumberStyles.AllowThousands) > currentPrice && long.Parse(conditionStock.TargetPrice, System.Globalization.NumberStyles.AllowThousands) < long.Parse(conditionStock.TransferPrice, System.Globalization.NumberStyles.AllowThousands)) { /*if (long.Parse(conditionStock.TransferPrice, System.Globalization.NumberStyles.AllowThousands) > long.Parse(conditionStock.NewTransferPrice, System.Globalization.NumberStyles.AllowThousands)) * { * return; * }*/ log(LogMode.TRADE, conditionStock.StockName + "(" + conditionStock.StockNo + ")의 1차 매수가에 도달하여 매수 합니다. (1차 매수가 : " + conditionStock.TargetPrice + ", 진입횟수 : " + conditionStock.TransferCnt + ")"); conditionStock.Ordered = "주문"; //if (!order(ORDER_TYPE_BUY, conditionStock.StockNo, (oneTimeAmount / int.Parse(currentPrice.ToString())), int.Parse(currentPrice.ToString()), ORDER_HOGA_LIIMIT)) // 시장가로 매수 if (!order(ORDER_TYPE_BUY, conditionStock.StockNo, (oneTimeAmount / int.Parse(currentPrice.ToString())), 0, ORDER_HOGA_MARKET)) { conditionStock.Ordered = "대기"; } } } } }