diff --git a/PyModel/batch_predict_betting_v8.py b/PyModel/batch_predict_betting_v8.py index 2ca139c..8ff249c 100644 --- a/PyModel/batch_predict_betting_v8.py +++ b/PyModel/batch_predict_betting_v8.py @@ -63,6 +63,15 @@ def get_history_records(data_dirs): return all_records +def generate_time_series(start, end): + current = start + series = [] + while current <= end: + series.append(current) + current += timedelta(minutes=5) + return series + + def main(next_period_time, df): entry = { "id": next_period_time.strftime('%Y%m%d%H%M'), @@ -77,22 +86,37 @@ def main(next_period_time, df): if next_period_time.strftime('%H:%M:%S') in EMPTY_TIME_WINDOWS: return entry + result = [] predictor = LotteryPredictorV14Profit() - next_period_time = pd.to_datetime(next_period_time) - recent_x = df[df['time'] < next_period_time].tail(10000) - predictor.check_init_daily_pnl_tracker(next_period_time) - predictions = predictor.predict(next_period_time, recent_x) + start_time, _ = predictor.check_init_daily_pnl_tracker(next_period_time) + time_series = generate_time_series(start_time, next_period_time) - for pos, nums_bet in predictions.items(): - if not nums_bet: - continue - entry['result'][pos] = nums_bet + for dt in time_series: + entry = { + "id": dt.strftime('%Y%m%d%H%M'), + "time": dt.strftime('%Y-%m-%d %H:%M:%S'), + "result": {i: {n: None for n in range(1, 11)} for i in range(10)}, + "result_detail": {i: {"单": None, "双": None, "大": None, "小": None} for i in range(10)}, + "winner": {}, + "GD1": {"冠亚大": None, "冠亚小": None}, + "GD2": {"冠亚单": None, "冠亚双": None}, + "GLH_result": {} + } + current_time = pd.to_datetime(dt) + recent_x = df[df['time'] < current_time].tail(10000) + predictions = predictor.predict(current_time, recent_x) - last_result = df[df['time'] == next_period_time] - if last_result.size != 0: - predictor.update_result(last_result, entry) - return entry + for pos, nums_bet in predictions.items(): + if not nums_bet: + continue + entry['result'][pos] = nums_bet + + last_result = df[df['time'] == current_time] + if last_result.size != 0: + predictor.update_result(last_result, entry) + result.append(entry) + return result[-1] if __name__ == "__main__": @@ -101,7 +125,7 @@ if __name__ == "__main__": all_records = get_history_records(data_dirs) parser = argparse.ArgumentParser(description="下一期时间 next_period_time, 例: 2026-01-02 06:00:00") # 必选位置参数(直接传入值,无需前缀) - parser.add_argument("--next_period_time", type=str, help="下一期时间, 例: 2026-01-02 06:00:00", default="2026-01-02 06:00:00") + parser.add_argument("--next_period_time", type=str, help="下一期时间, 例: 2026-01-02 06:00:00", default="2026-01-02 07:05:00") args = parser.parse_args() fmt = "%Y-%m-%d %H:%M:%S" next_period_time = datetime.strptime(args.next_period_time, fmt) diff --git a/PyModel/conf.ini b/PyModel/conf.ini index e4e14ca..e8fae19 100644 --- a/PyModel/conf.ini +++ b/PyModel/conf.ini @@ -1,8 +1,6 @@ [init] ODDS = 9.599 -BASE_BET_UNIT = 100 -BET_THIS_ROUND = 100 -INITIAL_CAPITAL = 20000 +BASE_BET_UNIT = 20 DAILY_STOP_LOSS_RATE = 0.30 [dynamic] diff --git a/PyModel/predict_model_v14_profit_maximizer.py b/PyModel/predict_model_v14_profit_maximizer.py index 2452326..e110d2e 100644 --- a/PyModel/predict_model_v14_profit_maximizer.py +++ b/PyModel/predict_model_v14_profit_maximizer.py @@ -19,7 +19,7 @@ class LotteryPredictorV14Profit: ODDS = float(conf["init"]["ODDS"]) REBATE_RATE = float(conf["dynamic"]["REBATE_RATE"]) BASE_BET_UNIT = int(conf["init"]["BASE_BET_UNIT"]) - _bet_this_round = int(conf["init"]["BET_THIS_ROUND"]) + _bet_this_round = BASE_BET_UNIT SAFE_BET_LEVEL_1 = 0.05 SAFE_BET_LEVEL_2 = 0.10 SAFE_BET_LEVEL_3 = 0.15 @@ -28,7 +28,7 @@ class LotteryPredictorV14Profit: RADICAL_BET_LEVEL_0 = 0.05 RADICAL_BET_LEVEL_1 = 0.1 RADICAL_BET_LEVEL_2 = 0.2 - INITIAL_CAPITAL = int(conf["init"]["INITIAL_CAPITAL"]) + INITIAL_CAPITAL = BASE_BET_UNIT * 200 DAILY_STOP_LOSS_RATE = float(conf["init"]["DAILY_STOP_LOSS_RATE"]) # 绝佳熔断点:6000元熔断 POSITION_LOOKBACK_PERIODS = int(conf["dynamic"]["POSITION_LOOKBACK_PERIODS"]) OMISSIONS_LEVEL_1 = int(conf["dynamic"]["OMISSIONS_LEVEL_1"]) @@ -126,10 +126,17 @@ class LotteryPredictorV14Profit: start_time, end_time = date_range if start_time <= current_date <= end_time: _date_range = (start_time, end_time) + break if not _date_range: - current_date_start_time = pd.to_datetime(current_date.date()) + timedelta(hours=7, minutes=5) - current_date_end_time = current_date_start_time + timedelta(hours=22, minutes=55) + + if current_date.hour <= 6: + current_date_start_time = pd.to_datetime(current_date.date()) + timedelta(days=-1, hours=7, minutes=5) + current_date_end_time = current_date_start_time + timedelta(hours=22, minutes=55) + else: + current_date_start_time = pd.to_datetime(current_date.date()) + timedelta(hours=7, minutes=5) + current_date_end_time = current_date_start_time + timedelta(hours=22, minutes=55) + _date_range = (current_date_start_time, current_date_end_time) self.daily_pnl_tracker[_date_range] = {'pnl': 0, 'bets': 0, 'miss_count': 0} diff --git a/bocai.db b/bocai.db index 8521b7e..f7e9cf2 100644 Binary files a/bocai.db and b/bocai.db differ diff --git a/run-project.bat b/run-project.bat index 5c25593..a1ee8fd 100644 --- a/run-project.bat +++ b/run-project.bat @@ -2,14 +2,14 @@ rem 启动后端Spring Boot应用 echo 正在启动后端应用... -start "后端服务" cmd /k "cd /d e:\git_resp\bocai && java -jar target/bocai-0.0.1-SNAPSHOT.jar" +start "后端服务" cmd /k "cd /d C:\Users\admin\Desktop\boc && java -jar target/bocai-0.0.1-SNAPSHOT.jar" rem 等待后端启动 ping 127.0.0.1 -n 5 > nul rem 启动前端Vue应用 echo 正在启动前端应用... -start "前端服务" cmd /k "cd /d e:\git_resp\bocai\frontend && npm run dev" +start "前端服务" cmd /k "cd /d C:\Users\admin\Desktop\boc\frontend && npm run dev" echo 前后端应用已启动! echo 后端服务:http://localhost:8080 diff --git a/run-project.sh b/run-project.sh deleted file mode 100644 index b2e6c93..0000000 --- a/run-project.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# 启动后端Spring Boot应用 -echo "正在启动后端应用..." -cd "$(dirname "$0")" && java -jar target/bocai-0.0.1-SNAPSHOT.jar & - -# 等待后端启动 -sleep 5 - -# 启动前端Vue应用 -echo "正在启动前端应用..." -cd frontend && npm run dev & - -echo "前后端应用已启动!" -echo "后端服务:http://localhost:8080" -echo "前端服务:通常为 http://localhost:5173 (具体端口请查看前端启动日志)" -echo "按 Ctrl+C 停止所有服务..." - -# 等待用户中断 -trap "kill 0" EXIT -wait \ No newline at end of file diff --git a/src/main/java/com/tem/bocai/BocaiApplication.java b/src/main/java/com/tem/bocai/BocaiApplication.java index 758869d..17a6a31 100644 --- a/src/main/java/com/tem/bocai/BocaiApplication.java +++ b/src/main/java/com/tem/bocai/BocaiApplication.java @@ -17,7 +17,7 @@ public class BocaiApplication { // // 依次执行三个任务 // -// // 1. 执行CrawlerSchedule方法 + // 1. 执行CrawlerSchedule方法 System.out.println("\n=== 开始执行CrawlerSchedule任务 ==="); CrawlerSchedule crawlerSchedule = context.getBean(CrawlerSchedule.class); crawlerSchedule.executeLotteryDraw(); diff --git a/src/main/java/com/tem/bocai/config/TessConfig.java b/src/main/java/com/tem/bocai/config/TessConfig.java index f544dd1..d685f2c 100644 --- a/src/main/java/com/tem/bocai/config/TessConfig.java +++ b/src/main/java/com/tem/bocai/config/TessConfig.java @@ -12,7 +12,7 @@ public class TessConfig { Tesseract instance = new Tesseract(); instance.setLanguage("oci"); // 设置语言包,这里使用英语 - instance.setDatapath("src/main/resources/tessdata"); // 设置语言包路径 + instance.setDatapath("tessdata"); // 设置语言包路径 return instance; } } diff --git a/src/main/java/com/tem/bocai/schedules/BetSchedule.java b/src/main/java/com/tem/bocai/schedules/BetSchedule.java index 8bf8a10..e768edf 100644 --- a/src/main/java/com/tem/bocai/schedules/BetSchedule.java +++ b/src/main/java/com/tem/bocai/schedules/BetSchedule.java @@ -2,6 +2,7 @@ package com.tem.bocai.schedules; import com.tem.bocai.util.TokenCacheService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -142,7 +143,7 @@ public class BetSchedule { // 调用投注接口 System.out.println(" - 提交投注..."); - String betResult = callBetApi(betData, loginInfo); + String betResult = callBetApi(betData, null); System.out.println(" - 投注结果: " + betResult); // 记录投注结果 @@ -167,7 +168,7 @@ public class BetSchedule { /** * 调用投注接口 */ - private String callBetApi(String betData, LoginInfoResult loginInfo) throws IOException, InterruptedException { + private String callBetApi(String betData, String token) throws IOException, InterruptedException { // 假设投注接口地址为http://localhost:8080/api/bet String apiUrl = "https://4701268539-esh.qdk63ayw8g.com/member/bet"; @@ -176,7 +177,7 @@ public class BetSchedule { HttpRequest.Builder requestBuilder = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .header("Content-Type", "application/json") - .header("cookie", "token=" + tokenCacheService.getToken()); + .header("cookie", "token=" + (StringUtils.isBlank(token)?tokenCacheService.getToken():token)); HttpRequest request = requestBuilder .POST(HttpRequest.BodyPublishers.ofString(betData)) @@ -187,10 +188,14 @@ public class BetSchedule { // 解析响应 if (response.statusCode() == 200) { - log.info("投注成功"); return null; - } else { + }else if (response.statusCode() == 302){ + String tokenSqlite = tokenCacheService.getTokenSqlite(); + callBetApi(betData, tokenSqlite); + return null; + } + else { return "error: " + response.statusCode(); } }