...
This commit is contained in:
@@ -353,7 +353,7 @@ class TechnicalAnalyzer {
|
||||
|
||||
// 🌟 3. 3개 중 2개 이상 만족 시 반등 임박(Approaching)으로 판단
|
||||
val passedConditions = listOf(isPriceDropped, isPastMinTime, isWithinMaxTime).count { it }
|
||||
|
||||
//A. 진입 하락률 기준checkReboundApproaching 3개 중 2개 만족 시 통과 가격 하락 조건(isPriceDropped)을 필수 조건(AND)으로 고정
|
||||
return passedConditions >= 2
|
||||
}
|
||||
|
||||
@@ -670,7 +670,8 @@ $standardizedScores
|
||||
val remainingDropRate = reboundStats.avgDropRate - currentDropRate
|
||||
|
||||
// 바닥권 인정 마진 (ATR 기반)
|
||||
val bottomMargin = currentAtr * 0.7
|
||||
//B. 바닥권 판정 마진predictDropBottom currentAtr * 0.7 여유 마진 마진을 축소(currentAtr * 0.3)하여 예상 바닥에 더 근접해야 인정
|
||||
val bottomMargin = currentAtr * 0.5
|
||||
|
||||
// 저점 평균(smoothedBottom)도 마지노선 계산에 추가 가중치로 섞어줌으로써 저점에 더 밀착시킴
|
||||
val adjustedExtremeLow = (volatility.extremeLow + smoothedBottom) / 2.0
|
||||
|
||||
@@ -360,4 +360,9 @@ object KisSession {
|
||||
fun isAvailBuyTime(now: LocalTime) : Boolean {
|
||||
return now.isBefore(endBuyTime()) && now.isAfter(startBuyTime())
|
||||
}
|
||||
|
||||
fun isMarketOpenTime(now: LocalTime) : Boolean {
|
||||
return now.isBefore(LocalTime.of(15,30)) && now.isAfter(LocalTime.of(9,0))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -242,7 +242,7 @@ object AutoTradingManager {
|
||||
TradingLogStore.addNotice("SYSTEM", "LIMIT", "최대 보유 종목 도달로 신규 매수 일시 중단")
|
||||
addToReanalysis(RankingStock(mksc_shrn_iscd = stockCode,hts_kor_isnm = stockName))
|
||||
TradingLogStore.addWatchLog(decision,"WATCH","매수 실패 : 최대 보유 종목 도달로 신규 매수 일시 중단 => 재분석 대기열에 추가")
|
||||
} else if (KisSession.isAvailBuyTime(LocalTime.now())){
|
||||
} else if (KisSession.isAvailBuyTime(LocalTime.now()) || hasCode){
|
||||
println("basePrice : $basePrice, oneTickLowerPrice : $oneTickLowerPrice, finalPrice : $finalPrice hasStocks : ${stockCode.contains(stockCode)}" )
|
||||
var realOrderQty = orderQty
|
||||
KisTradeService.postOrder(stockCode, realOrderQty, finalPrice.toLong().toString(), isBuy = true)
|
||||
@@ -1028,7 +1028,7 @@ object AutoTradingManager {
|
||||
while (iterator.hasNext()) {
|
||||
totalCount--
|
||||
val stock = iterator.next()
|
||||
if (KisSession.isAvailBuyTime(now)) {
|
||||
if (KisSession.isMarketOpenTime(now)) {
|
||||
if (BLACKLISTEDSTOCKCODES.contains(stock.code)) {
|
||||
println("❌ 차단 처리된 주식 : ${stock.name}")
|
||||
} else {
|
||||
@@ -1181,8 +1181,8 @@ object AutoTradingManager {
|
||||
val tempAnalyzer = TechnicalAnalyzer().apply { this.daily = dailyData }
|
||||
|
||||
// 1. 변동성 기반 수익률 검증 (2% 이상 열려있는가?)
|
||||
println("(dailyData.size * 0.8).toInt() ${(dailyData.size * 0.8).toInt()}")
|
||||
val volatility = tempAnalyzer.calculateVolatilityForecast(dailyData, (dailyData.size * 0.8).toInt())
|
||||
println("(dailyData.size * 0.8).toInt() ${(dailyData.size * 0.3).toInt()}")
|
||||
val volatility = tempAnalyzer.calculateVolatilityForecast(dailyData, 20)
|
||||
val expectedProfitRate = ((volatility.realisticHigh - currentPrice) / currentPrice) * 100.0
|
||||
|
||||
// 2. 일봉 기준 반등 주기 통계 추출 (일주일 내 승부 가능한가?)
|
||||
@@ -1212,7 +1212,7 @@ object AutoTradingManager {
|
||||
|
||||
if (dropPrediction != null) {
|
||||
// 💡 [방어 로직 1] 아직 바닥까지 한참 남았다면 지하실 방지
|
||||
if (dropPrediction.remainingDropRate < -2.0 && !dropPrediction.isBottomZone) {
|
||||
if (dropPrediction.remainingDropRate < -1.0 && !dropPrediction.isBottomZone) {
|
||||
print("-> [${stock.name}] 지하실 주의 (현재 ${"%.1f".format(dropPrediction.currentDropRate)}% 하락, 추가 하락 위험) | ")
|
||||
return@withTimeout
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user