diff --git a/src/main/kotlin/service/AutoTradingManager.kt b/src/main/kotlin/service/AutoTradingManager.kt index 155d6d6..584db1e 100644 --- a/src/main/kotlin/service/AutoTradingManager.kt +++ b/src/main/kotlin/service/AutoTradingManager.kt @@ -128,7 +128,8 @@ object AutoTradingManager { decision = decision, orderQty = calculatedQty.toString(), profitRate1 = KisSession.config.getValues(ConfigIndex.PROFIT_INDEX) * KisSession.config.getValues(grade.profitGuide), - investmentGrade = grade + investmentGrade = grade, + hasCode = hasCodes == true ) } else if (decision.decision.equals("RETRY") || decision.confidence >= 60.0) { // 아까운 종목만 재분석 addToReanalysis(RankingStock(decision.stockCode, decision.stockName)) @@ -207,7 +208,7 @@ object AutoTradingManager { } } - fun excuteTrade(decision: TradingDecision, orderQty: String, profitRate1: Double?, investmentGrade: InvestmentGrade = InvestmentGrade.LEVEL_2_HIGH_RISK) { + fun excuteTrade(decision: TradingDecision, orderQty: String, profitRate1: Double?, investmentGrade: InvestmentGrade = InvestmentGrade.LEVEL_2_HIGH_RISK, hasCode: Boolean) { scope.launch { var basePrice = decision.currentPrice val tickSize = MarketUtil.getTickSize(basePrice) @@ -218,9 +219,8 @@ object AutoTradingManager { val maxStocks = KisSession.config.getValues(ConfigIndex.MAX_HOLDING_COUNT).toInt() if (!canAddNewPosition(maxStocks)) { - TradingLogStore.addNotice("SYSTEM", "LIMIT", "최대 보유 종목 도달로 신규 매수 일시 중단") - AutoTradingManager.addToReanalysis(RankingStock(mksc_shrn_iscd = stockCode,hts_kor_isnm = stockName)) + addToReanalysis(RankingStock(mksc_shrn_iscd = stockCode,hts_kor_isnm = stockName)) TradingLogStore.addWatchLog(decision,"WATCH","매수 실패 : 최대 보유 종목 도달로 신규 매수 일시 중단 => 재분석 대기열에 추가") } else if (KisSession.isAvailBuyTime(LocalTime.now())){ println("basePrice : $basePrice, oneTickLowerPrice : $oneTickLowerPrice, finalPrice : $finalPrice hasStocks : ${stockCode.contains(stockCode)}" ) @@ -238,6 +238,13 @@ object AutoTradingManager { var tax = KisSession.config.getValues(ConfigIndex.TAX_INDEX) val effectiveProfitRate = (profitRate1 ?: KisSession.config.getValues(ConfigIndex.PROFIT_INDEX)) + tax + var oldTarget = currentBalance?.getHoldings()?.filter { it.code.equals(decision.stockCode) }?.first() + if (hasCode && oldTarget != null) { + var avgPrive = oldTarget.avgPrice.toDouble() + var qty = oldTarget.quantity.toDouble() + basePrice = ((avgPrive * qty) + decision.currentPrice).div(qty!!.toInt() + 1) + println("물타기 ${avgPrive}, ${qty} ${basePrice}") + } val calculatedTarget = MarketUtil.roundToTickSize(basePrice * (1 + effectiveProfitRate / 100.0)) @@ -822,7 +829,7 @@ object AutoTradingManager { } } var loadedTops = mutableListOf>() - var defaultStockCount = 100 + var defaultStockCount = 30 fun poll100Stocks(): List> { loadedTops.shuffle() val count = minOf(loadedTops.size, defaultStockCount) @@ -915,7 +922,7 @@ object AutoTradingManager { val myCash = currentBalance?.deposit?.replace(",", "")?.toLongOrNull() ?: KisSession.config.getValues(ConfigIndex.MAX_PRICE_INDEX).toLong() val myHoldings = currentBalance?.getHoldings()?.filter { !it.isTodayEntry }?.map { it.code }?.toSet() ?: emptySet() val pendingStocks = DatabaseFactory.findAllMonitoringTrades().map { it.code } - + var now = LocalTime.now(ZoneId.of("Asia/Seoul")) if (remainingCandidates.isEmpty()) { if (loadedTops.size < defaultStockCount) { loadedTops.addAll(StockUniverseLoader.loadUniverse()) @@ -944,10 +951,10 @@ object AutoTradingManager { if (reanalysisList.isNotEmpty()) { candidates.addAll(reanalysisList) } + candidates.clear()///물타기 reanalysisList.clear() if (KisSession.tradeConfig.lowerAveragePrice) { currentBalance?.getHoldings()?.map { -// println("물타기 기준 체크${ it.profitRate.toDouble()},${(KisSession.tradeConfig.lowerAverageMaxRate * -1)}, ${(KisSession.tradeConfig.lowerAverageMinRate * -1)}") if( it.quantity.toInt() > KisSession.tradeConfig.lowerAverageTargetCount && it.profitRate.toDouble() < (KisSession.tradeConfig.lowerAverageMaxRate * -1) && @@ -955,6 +962,14 @@ object AutoTradingManager { { candidates.add(RankingStock(mksc_shrn_iscd = it.code, hts_kor_isnm = it.name)) println("물타기 대상 추가 ${it.name}[${it.code}]") + var oldTarget = it + if ( oldTarget != null) { + var avgPrive = oldTarget.avgPrice.toDouble() + + var qty = oldTarget.quantity.toDouble() + var basePrice = ((avgPrive * qty) + it.currentPrice.toDouble()).div(qty!!.toInt() + 1) + println("물타기 ${avgPrive}, ${qty} ${basePrice}") + } } } }