모의투자 로직 변경

This commit is contained in:
Macbook
2026-05-31 14:05:46 +09:00
parent ead97dad5d
commit d6eedf19bb
33 changed files with 1456 additions and 330 deletions
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.goldenchart.dto.BacktestSettingsDto;
import com.goldenchart.entity.GcAppSettings;
import com.goldenchart.repository.GcAppSettingsRepository;
import com.goldenchart.trading.TradingAccess;
import com.goldenchart.trading.TradingExecutionService;
import com.goldenchart.trading.TradingMode;
import com.goldenchart.trading.pipeline.OrderRequest;
@@ -50,8 +51,9 @@ public class LiveRiskMonitorService {
if (!Boolean.TRUE.equals(app.getLiveAutoTradeEnabled())) continue;
if (!liveTradingService.hasApiKeys(app)) continue;
if (!TradingMode.fromString(app.getTradingMode()).useLive()) continue;
String deviceId = app.getDeviceId();
if (deviceId == null || deviceId.isBlank()) continue;
Long userId = app.getUserId();
if (userId == null || userId <= 0) continue;
String cacheKey = TradingAccess.accountDeviceKey(userId);
try {
var creds = appSettingsService.resolveUpbitCredentials(app);
if (!creds.isComplete()) continue;
@@ -67,9 +69,9 @@ public class LiveRiskMonitorService {
coins.put(cur, new double[]{bal, avg});
}
}
accountCache.put(deviceId, coins);
accountCache.put(cacheKey, coins);
} catch (Exception e) {
log.debug("[LiveRisk] account sync {}: {}", deviceId, e.getMessage());
log.debug("[LiveRisk] account sync userId={}: {}", userId, e.getMessage());
}
}
}
@@ -79,40 +81,51 @@ public class LiveRiskMonitorService {
String currency = market.startsWith("KRW-") ? market.substring(4) : market;
for (var entry : accountCache.entrySet()) {
String deviceId = entry.getKey();
String cacheKey = entry.getKey();
double[] pos = entry.getValue().get(currency);
if (pos == null || pos[0] <= 0 || pos[1] <= 0) continue;
String key = deviceId + ":" + market;
String cooldownKey = cacheKey + ":" + market;
long now = System.currentTimeMillis();
Long last = exitCooldown.get(key);
Long last = exitCooldown.get(cooldownKey);
if (last != null && now - last < COOLDOWN_MS) continue;
GcAppSettings app = appSettingsRepo.findByDeviceId(deviceId).orElse(null);
Long userId = parseUserIdFromCacheKey(cacheKey);
if (userId == null) continue;
GcAppSettings app = appSettingsRepo.findByUserId(userId).orElse(null);
if (app == null) continue;
BacktestSettingsDto risk = backtestSettingsService.get(deviceId);
BacktestSettingsDto risk = backtestSettingsService.get(cacheKey);
double avg = pos[1];
double pnlPct = (tradePrice - avg) / avg * 100.0;
if (Boolean.TRUE.equals(risk.getStopLossEnabled())
&& risk.getStopLossPct() != null
&& pnlPct <= -risk.getStopLossPct().doubleValue()) {
exitCooldown.put(key, now);
exitCooldown.put(cooldownKey, now);
tradingExecutionService.executeRiskExit(
OrderRequest.stopLoss(deviceId, app.getUserId(), market, tradePrice,
OrderRequest.stopLoss(cacheKey, userId, market, tradePrice,
risk.getStopLossPct().doubleValue()));
return;
}
if (Boolean.TRUE.equals(risk.getTakeProfitEnabled())
&& risk.getTakeProfitPct() != null
&& pnlPct >= risk.getTakeProfitPct().doubleValue()) {
exitCooldown.put(key, now);
exitCooldown.put(cooldownKey, now);
tradingExecutionService.executeRiskExit(
OrderRequest.takeProfit(deviceId, app.getUserId(), market, tradePrice,
OrderRequest.takeProfit(cacheKey, userId, market, tradePrice,
risk.getTakeProfitPct().doubleValue()));
return;
}
}
}
private static Long parseUserIdFromCacheKey(String cacheKey) {
if (cacheKey == null || !cacheKey.startsWith("user:")) return null;
try {
return Long.parseLong(cacheKey.substring(5));
} catch (NumberFormatException e) {
return null;
}
}
}