From 086fe05c4d6f89d5eb90085e3fb7293f25860af6 Mon Sep 17 00:00:00 2001 From: guopengfa Date: Fri, 16 Jan 2026 21:35:47 +0800 Subject: [PATCH 1/8] =?UTF-8?q?set=20trading=20code=20history=20data=20to?= =?UTF-8?q?=20config(=E7=AD=96=E7=95=A5=E6=89=A7=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=85=8D=E7=BD=AE=E6=95=B0=E9=87=8F=E7=9A=84?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=95=B0=E6=8D=AE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend_api_python/app/services/trading_executor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index a663c397d..8728933f4 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -708,7 +708,7 @@ def _run_strategy_loop(self, strategy_id: int): # 2. 检查是否需要更新K线(每个K线周期更新一次,从API拉取) # ============================================ if current_time - last_kline_update_time >= kline_update_interval: - klines = self._fetch_latest_kline(symbol, timeframe, limit=500) + klines = self._fetch_latest_kline(symbol, timeframe, limit=history_limit) if klines and len(klines) >= 2: df = self._klines_to_dataframe(klines) if len(df) > 0: From affbfd98da376b59ff7825f75a5ca663becebc09 Mon Sep 17 00:00:00 2001 From: guopengfa Date: Fri, 16 Jan 2026 21:50:44 +0800 Subject: [PATCH 2/8] =?UTF-8?q?add=20log=20show=20strategy=20history=20kli?= =?UTF-8?q?ne=20number=20(=E5=A2=9E=E5=8A=A0log=E5=B1=95=E7=A4=BA=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E4=B8=AD=E8=8E=B7=E5=8F=96=E7=9A=84=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9C=89=E5=A4=9A=E5=B0=91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend_api_python/app/services/trading_executor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index 8728933f4..af6b0eaf6 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -596,6 +596,7 @@ def _run_strategy_loop(self, strategy_id: int): if not klines or len(klines) < 2: logger.error(f"Strategy {strategy_id} failed to fetch K-lines") return + logger.info(rf'Strategy {strategy_id} kline number: {len(klines)}') # 转换为DataFrame df = self._klines_to_dataframe(klines) From ce11f7ad67820e6c53a39845b20f60c1ef6b84b7 Mon Sep 17 00:00:00 2001 From: guopengfa Date: Fri, 16 Jan 2026 22:35:44 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix=20bug:=20trade=20time=20is=20valid.=20(?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG=EF=BC=9A=E6=8C=81=E4=BB=93=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend_api_python/app/routes/strategy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend_api_python/app/routes/strategy.py b/backend_api_python/app/routes/strategy.py index cb614e3fe..083ee2b3f 100644 --- a/backend_api_python/app/routes/strategy.py +++ b/backend_api_python/app/routes/strategy.py @@ -471,7 +471,7 @@ def get_equity_curve(): equity += float(r.get('profit') or 0) except Exception: pass - ts = int(r.get('created_at') or time.time()) + ts = int(r.get('created_at').timestamp() or time.time()) curve.append({'time': ts, 'equity': equity}) return jsonify({'code': 1, 'msg': 'success', 'data': curve}) From 889e5acae5401c124260ca93768bd73bed68155c Mon Sep 17 00:00:00 2001 From: guopengfa Date: Sat, 17 Jan 2026 00:31:44 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix=20bug:=20trade=20time=20is=20valid.=20(?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG=EF=BC=9A=E6=8C=81=E4=BB=93=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 433 ++++++++++++++++++ .idea/vcs.xml | 1 + backend_api_python/app/data_sources/base.py | 8 +- backend_api_python/app/data_sources/crypto.py | 13 +- .../app/services/trading_executor.py | 5 +- .../scripts/simulate_trading_executor.py | 2 +- 6 files changed, 449 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 8b1378917..a3b01980d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,434 @@ +/quantdinger_vue/.browserslistrc +/quantdinger_vue/.dockerignore +/quantdinger_vue/.editorconfig +/quantdinger_vue/.env +/quantdinger_vue/.env.development +/quantdinger_vue/.env.preview +/quantdinger_vue/tests/unit/.eslintrc.js +/quantdinger_vue/.eslintrc.js +/quantdinger_vue/.eslintrc.json +/quantdinger_vue/.gitattributes +/quantdinger_vue/.husky/.gitignore +/quantdinger_vue/.gitignore +/quantdinger_vue/.lintstagedrc.json +/quantdinger_vue/.prettierrc +/quantdinger_vue/.stylelintrc.js +/quantdinger_vue/.travis.yml +/quantdinger_vue/src/views/exception/403.vue +/quantdinger_vue/src/views/exception/404.vue +/quantdinger_vue/src/views/404.vue +/quantdinger_vue/src/views/exception/500.vue +/quantdinger_vue/src/core/directives/action.js +/quantdinger_vue/src/api/ai-trading.js +/quantdinger_vue/src/views/trading-assistant/components/AIDecisionRecords.vue +/quantdinger_vue/src/config/aiModels.js +/quantdinger_vue/src/store/modules/app.js +/quantdinger_vue/src/App.vue +/quantdinger_vue/src/store/app-mixin.js +/quantdinger_vue/src/locales/lang/ar-SA.js +/quantdinger_vue/src/mock/services/article.js +/quantdinger_vue/src/components/ArticleListContent/ArticleListContent.vue +/quantdinger_vue/src/store/modules/async-router.js +/quantdinger_vue/src/api/auth.js +/quantdinger_vue/src/mock/services/auth.js +/quantdinger_vue/public/avatar2.jpg +/quantdinger_vue/src/components/GlobalHeader/AvatarDropdown.vue +/quantdinger_vue/src/utils/axios.js +/quantdinger_vue/babel.config.js +/quantdinger_vue/src/assets/background.svg +/quantdinger_vue/src/views/indicator-analysis/components/BacktestHistoryDrawer.vue +/quantdinger_vue/src/views/indicator-analysis/components/BacktestModal.vue +/quantdinger_vue/src/views/indicator-analysis/components/BacktestRunViewer.vue +/quantdinger_vue/src/components/Charts/Bar.vue +/quantdinger_vue/src/layouts/BasicLayout.less +/quantdinger_vue/src/layouts/BasicLayout.vue +/quantdinger_vue/src/layouts/BlankLayout.vue +/quantdinger_vue/src/core/bootstrap.js +/quantdinger_vue/src/assets/icons/bx-analyse.svg +/quantdinger_vue/deploy/caddy.conf +/quantdinger_vue/src/components/Other/CarbonAds.vue +/quantdinger_vue/src/components/Charts/chart.less +/quantdinger_vue/src/components/Charts/ChartCard.vue +/quantdinger_vue/src/utils/codeDecrypt.js +/quantdinger_vue/commitlint.config.js +/quantdinger_vue/src/api/credentials.js +/quantdinger_vue/src/api/dashboard.js +/quantdinger_vue/src/locales/lang/de-DE.js +/quantdinger_vue/src/config/defaultSettings.js +/quantdinger_vue/src/store/device-mixin.js +/quantdinger_vue/src/components/Dialog.js +/quantdinger_vue/Dockerfile +/quantdinger_vue/src/utils/domUtil.js +/quantdinger_vue/src/components/Ellipsis/Ellipsis.vue +/quantdinger_vue/src/locales/lang/en-US.js +/quantdinger_vue/src/components/MultiTab/events.js +/quantdinger_vue/scripts/fetch_pyodide.ps1 +/quantdinger_vue/src/utils/filter.js +/quantdinger_vue/src/components/FooterToolbar/FooterToolBar.vue +/quantdinger_vue/src/locales/lang/fr-FR.js +/quantdinger_vue/src/router/generator-routers.js +/quantdinger_vue/src/store/getters.js +/quantdinger_vue/src/global.less +/quantdinger_vue/src/components/Search/GlobalSearch.jsx +/quantdinger_vue/src/store/i18n-mixin.js +/quantdinger_vue/src/components/IconSelector/icons.js +/quantdinger_vue/src/core/icons.js +/quantdinger_vue/src/components/IconSelector/IconSelector.vue +/quantdinger_vue/public/index.html +/quantdinger_vue/src/components/ArticleListContent/index.js +/quantdinger_vue/src/components/AvatarList/index.js +/quantdinger_vue/src/components/Ellipsis/index.js +/quantdinger_vue/src/components/FooterToolbar/index.js +/quantdinger_vue/src/components/IconSelector/index.js +/quantdinger_vue/src/components/MultiTab/index.js +/quantdinger_vue/src/components/NoticeIcon/index.js +/quantdinger_vue/src/components/NumberInfo/index.js +/quantdinger_vue/src/components/SettingDrawer/index.js +/quantdinger_vue/src/components/StandardFormRow/index.js +/quantdinger_vue/src/components/Table/index.js +/quantdinger_vue/src/components/Trend/index.js +/quantdinger_vue/src/components/index.js +/quantdinger_vue/src/layouts/index.js +/quantdinger_vue/src/locales/index.js +/quantdinger_vue/src/mock/index.js +/quantdinger_vue/src/router/index.js +/quantdinger_vue/src/store/index.js +/quantdinger_vue/src/components/PageLoading/index.jsx +/quantdinger_vue/src/components/SelectLang/index.jsx +/quantdinger_vue/src/components/TagSelect/index.jsx +/quantdinger_vue/src/components/TextArea/index.jsx +/quantdinger_vue/src/components/AvatarList/index.less +/quantdinger_vue/src/components/FooterToolbar/index.less +/quantdinger_vue/src/components/MultiTab/index.less +/quantdinger_vue/src/components/NumberInfo/index.less +/quantdinger_vue/src/components/Search/index.less +/quantdinger_vue/src/components/SelectLang/index.less +/quantdinger_vue/src/components/Trend/index.less +/quantdinger_vue/src/components/index.less +/quantdinger_vue/src/components/AvatarList/index.md +/quantdinger_vue/src/components/Ellipsis/index.md +/quantdinger_vue/src/components/FooterToolbar/index.md +/quantdinger_vue/src/components/NumberInfo/index.md +/quantdinger_vue/src/components/Trend/index.md +/quantdinger_vue/src/components/GlobalFooter/index.vue +/quantdinger_vue/src/components/Turnstile/index.vue +/quantdinger_vue/src/views/ai-analysis/components/index.vue +/quantdinger_vue/src/views/ai-analysis/index.vue +/quantdinger_vue/src/views/dashboard/index.vue +/quantdinger_vue/src/views/indicator-analysis/index.vue +/quantdinger_vue/src/views/indicator-community/index.vue +/quantdinger_vue/src/views/portfolio/index.vue +/quantdinger_vue/src/views/profile/index.vue +/quantdinger_vue/src/views/settings/index.vue +/quantdinger_vue/src/views/trading-assistant/index.vue +/quantdinger_vue/src/views/user-manage/index.vue +/quantdinger_vue/src/views/indicator-analysis/components/IndicatorEditor.vue +/quantdinger_vue/src/components/AvatarList/Item.jsx +/quantdinger_vue/src/locales/lang/ja-JP.js +/quantdinger_vue/jest.config.js +/quantdinger_vue/jsconfig.json +/quantdinger_vue/src/views/indicator-analysis/components/KlineChart.vue +/quantdinger_vue/src/locales/lang/ko-KR.js +/quantdinger_vue/src/core/lazy_use.js +/quantdinger_vue/src/components/Charts/Liquid.vue +/quantdinger_vue/src/components/AvatarList/List.jsx +/quantdinger_vue/src/api/login.js +/quantdinger_vue/src/views/user/Login.vue +/quantdinger_vue/public/logo.png +/quantdinger_vue/src/assets/logo.png +/quantdinger_vue/src/assets/logo.svg +/quantdinger_vue/src/main.js +/quantdinger_vue/src/api/manage.js +/quantdinger_vue/src/mock/services/manage.js +/quantdinger_vue/src/api/market.js +/quantdinger_vue/src/components/Charts/MiniArea.vue +/quantdinger_vue/src/components/Charts/MiniBar.vue +/quantdinger_vue/src/components/Charts/MiniProgress.vue +/quantdinger_vue/src/components/Charts/MiniSmoothArea.vue +/quantdinger_vue/src/components/MultiTab/MultiTab.vue +/quantdinger_vue/src/store/mutation-types.js +/quantdinger_vue/deploy/nginx.conf +/quantdinger_vue/deploy/nginx-docker.conf +/quantdinger_vue/src/components/NoticeIcon/NoticeIcon.vue +/quantdinger_vue/src/components/NProgress/nprogress.less +/quantdinger_vue/src/components/NumberInfo/NumberInfo.vue +/quantdinger_vue/src/mock/services/other.js +/quantdinger_vue/package.json +/quantdinger_vue/src/layouts/PageView.vue +/quantdinger_vue/src/core/permission/permission.js +/quantdinger_vue/src/permission.js +/quantdinger_vue/config/plugin.config.js +/quantdinger_vue/pnpm-lock.yaml +/quantdinger_vue/src/api/portfolio.js +/quantdinger_vue/src/views/trading-assistant/components/PositionRecords.vue +/quantdinger_vue/postcss.config.js +/quantdinger_vue/src/components/Editor/QuillEditor.vue +/quantdinger_vue/src/components/Charts/Radar.vue +/quantdinger_vue/src/components/Charts/RankList.vue +/quantdinger_vue/src/components/IconSelector/README.md +/quantdinger_vue/src/components/Table/README.md +/quantdinger_vue/src/router/README.md +/quantdinger_vue/README.md +/quantdinger_vue/src/views/user/RegisterResult.vue +/quantdinger_vue/src/utils/request.js +/quantdinger_vue/src/components/GlobalHeader/RightContent.vue +/quantdinger_vue/src/utils/routeConvert.js +/quantdinger_vue/src/config/router.config.js +/quantdinger_vue/src/layouts/RouteView.vue +/quantdinger_vue/src/utils/screenLog.js +/quantdinger_vue/src/components/SettingDrawer/settingConfig.js +/quantdinger_vue/src/components/SettingDrawer/SettingDrawer.vue +/quantdinger_vue/src/components/SettingDrawer/SettingItem.vue +/quantdinger_vue/src/api/settings.js +/quantdinger_vue/public/slogo.png +/quantdinger_vue/src/assets/slogo.png +/quantdinger_vue/src/components/Charts/smooth.area.less +/quantdinger_vue/src/components/StandardFormRow/StandardFormRow.vue +/quantdinger_vue/src/store/modules/static-router.js +/quantdinger_vue/src/api/strategy.js +/quantdinger_vue/src/components/TextArea/style.less +/quantdinger_vue/src/mock/services/tagCloud.js +/quantdinger_vue/src/components/Charts/TagCloud.vue +/quantdinger_vue/src/components/TagSelect/TagSelectOption.jsx +/quantdinger_vue/src/locales/lang/th-TH.js +/quantdinger_vue/src/components/SettingDrawer/themeColor.js +/quantdinger_vue/config/themePluginConfig.js +/quantdinger_vue/src/views/trading-assistant/components/TradingRecords.vue +/quantdinger_vue/src/components/Charts/TransferBar.vue +/quantdinger_vue/src/components/Tree/Tree.jsx +/quantdinger_vue/src/components/Charts/Trend.vue +/quantdinger_vue/src/components/Trend/Trend.vue +/quantdinger_vue/src/components/tools/TwoStepCaptcha.vue +/quantdinger_vue/src/core/use.js +/quantdinger_vue/src/api/user.js +/quantdinger_vue/src/mock/services/user.js +/quantdinger_vue/src/store/modules/user.js +/quantdinger_vue/src/layouts/UserLayout.vue +/quantdinger_vue/src/components/_util/util.js +/quantdinger_vue/src/mock/util.js +/quantdinger_vue/src/utils/util.js +/quantdinger_vue/src/utils/utils.less +/quantdinger_vue/src/locales/lang/vi-VN.js +/quantdinger_vue/vue.config.js +/quantdinger_vue/src/components/Editor/WangEditor.vue +/quantdinger_vue/yarn.lock +/quantdinger_vue/src/locales/lang/zh-CN.js +/quantdinger_vue/src/locales/lang/zh-TW.js +/quantdinger_vue/.browserslistrc +/quantdinger_vue/.dockerignore +/quantdinger_vue/.editorconfig +/quantdinger_vue/.env +/quantdinger_vue/.env.development +/quantdinger_vue/.env.preview +/quantdinger_vue/tests/unit/.eslintrc.js +/quantdinger_vue/.eslintrc.js +/quantdinger_vue/.eslintrc.json +/quantdinger_vue/.gitattributes +/quantdinger_vue/.husky/.gitignore +/quantdinger_vue/.gitignore +/quantdinger_vue/.lintstagedrc.json +/quantdinger_vue/.prettierrc +/quantdinger_vue/.stylelintrc.js +/quantdinger_vue/.travis.yml +/quantdinger_vue/src/views/exception/403.vue +/quantdinger_vue/src/views/exception/404.vue +/quantdinger_vue/src/views/404.vue +/quantdinger_vue/src/views/exception/500.vue +/quantdinger_vue/src/core/directives/action.js +/quantdinger_vue/src/api/ai-trading.js +/quantdinger_vue/src/views/trading-assistant/components/AIDecisionRecords.vue +/quantdinger_vue/src/config/aiModels.js +/quantdinger_vue/src/store/modules/app.js +/quantdinger_vue/src/App.vue +/quantdinger_vue/src/store/app-mixin.js +/quantdinger_vue/src/locales/lang/ar-SA.js +/quantdinger_vue/src/mock/services/article.js +/quantdinger_vue/src/components/ArticleListContent/ArticleListContent.vue +/quantdinger_vue/src/store/modules/async-router.js +/quantdinger_vue/src/api/auth.js +/quantdinger_vue/src/mock/services/auth.js +/quantdinger_vue/public/avatar2.jpg +/quantdinger_vue/src/components/GlobalHeader/AvatarDropdown.vue +/quantdinger_vue/src/utils/axios.js +/quantdinger_vue/babel.config.js +/quantdinger_vue/src/assets/background.svg +/quantdinger_vue/src/views/indicator-analysis/components/BacktestHistoryDrawer.vue +/quantdinger_vue/src/views/indicator-analysis/components/BacktestModal.vue +/quantdinger_vue/src/views/indicator-analysis/components/BacktestRunViewer.vue +/quantdinger_vue/src/components/Charts/Bar.vue +/quantdinger_vue/src/layouts/BasicLayout.less +/quantdinger_vue/src/layouts/BasicLayout.vue +/quantdinger_vue/src/layouts/BlankLayout.vue +/quantdinger_vue/src/core/bootstrap.js +/quantdinger_vue/src/assets/icons/bx-analyse.svg +/quantdinger_vue/deploy/caddy.conf +/quantdinger_vue/src/components/Other/CarbonAds.vue +/quantdinger_vue/src/components/Charts/chart.less +/quantdinger_vue/src/components/Charts/ChartCard.vue +/quantdinger_vue/src/utils/codeDecrypt.js +/quantdinger_vue/commitlint.config.js +/quantdinger_vue/src/api/credentials.js +/quantdinger_vue/src/api/dashboard.js +/quantdinger_vue/src/locales/lang/de-DE.js +/quantdinger_vue/src/config/defaultSettings.js +/quantdinger_vue/src/store/device-mixin.js +/quantdinger_vue/src/components/Dialog.js +/quantdinger_vue/Dockerfile +/quantdinger_vue/src/utils/domUtil.js +/quantdinger_vue/src/components/Ellipsis/Ellipsis.vue +/quantdinger_vue/src/locales/lang/en-US.js +/quantdinger_vue/src/components/MultiTab/events.js +/quantdinger_vue/scripts/fetch_pyodide.ps1 +/quantdinger_vue/src/utils/filter.js +/quantdinger_vue/src/components/FooterToolbar/FooterToolBar.vue +/quantdinger_vue/src/locales/lang/fr-FR.js +/quantdinger_vue/src/router/generator-routers.js +/quantdinger_vue/src/store/getters.js +/quantdinger_vue/src/global.less +/quantdinger_vue/src/components/Search/GlobalSearch.jsx +/quantdinger_vue/src/store/i18n-mixin.js +/quantdinger_vue/src/components/IconSelector/icons.js +/quantdinger_vue/src/core/icons.js +/quantdinger_vue/src/components/IconSelector/IconSelector.vue +/quantdinger_vue/public/index.html +/quantdinger_vue/src/components/ArticleListContent/index.js +/quantdinger_vue/src/components/AvatarList/index.js +/quantdinger_vue/src/components/Ellipsis/index.js +/quantdinger_vue/src/components/FooterToolbar/index.js +/quantdinger_vue/src/components/IconSelector/index.js +/quantdinger_vue/src/components/MultiTab/index.js +/quantdinger_vue/src/components/NoticeIcon/index.js +/quantdinger_vue/src/components/NumberInfo/index.js +/quantdinger_vue/src/components/SettingDrawer/index.js +/quantdinger_vue/src/components/StandardFormRow/index.js +/quantdinger_vue/src/components/Table/index.js +/quantdinger_vue/src/components/Trend/index.js +/quantdinger_vue/src/components/index.js +/quantdinger_vue/src/layouts/index.js +/quantdinger_vue/src/locales/index.js +/quantdinger_vue/src/mock/index.js +/quantdinger_vue/src/router/index.js +/quantdinger_vue/src/store/index.js +/quantdinger_vue/src/components/PageLoading/index.jsx +/quantdinger_vue/src/components/SelectLang/index.jsx +/quantdinger_vue/src/components/TagSelect/index.jsx +/quantdinger_vue/src/components/TextArea/index.jsx +/quantdinger_vue/src/components/AvatarList/index.less +/quantdinger_vue/src/components/FooterToolbar/index.less +/quantdinger_vue/src/components/MultiTab/index.less +/quantdinger_vue/src/components/NumberInfo/index.less +/quantdinger_vue/src/components/Search/index.less +/quantdinger_vue/src/components/SelectLang/index.less +/quantdinger_vue/src/components/Trend/index.less +/quantdinger_vue/src/components/index.less +/quantdinger_vue/src/components/AvatarList/index.md +/quantdinger_vue/src/components/Ellipsis/index.md +/quantdinger_vue/src/components/FooterToolbar/index.md +/quantdinger_vue/src/components/NumberInfo/index.md +/quantdinger_vue/src/components/Trend/index.md +/quantdinger_vue/src/components/GlobalFooter/index.vue +/quantdinger_vue/src/components/Turnstile/index.vue +/quantdinger_vue/src/views/ai-analysis/components/index.vue +/quantdinger_vue/src/views/ai-analysis/index.vue +/quantdinger_vue/src/views/dashboard/index.vue +/quantdinger_vue/src/views/indicator-analysis/index.vue +/quantdinger_vue/src/views/indicator-community/index.vue +/quantdinger_vue/src/views/portfolio/index.vue +/quantdinger_vue/src/views/profile/index.vue +/quantdinger_vue/src/views/settings/index.vue +/quantdinger_vue/src/views/trading-assistant/index.vue +/quantdinger_vue/src/views/user-manage/index.vue +/quantdinger_vue/src/views/indicator-analysis/components/IndicatorEditor.vue +/quantdinger_vue/src/components/AvatarList/Item.jsx +/quantdinger_vue/src/locales/lang/ja-JP.js +/quantdinger_vue/jest.config.js +/quantdinger_vue/jsconfig.json +/quantdinger_vue/src/views/indicator-analysis/components/KlineChart.vue +/quantdinger_vue/src/locales/lang/ko-KR.js +/quantdinger_vue/src/core/lazy_use.js +/quantdinger_vue/src/components/Charts/Liquid.vue +/quantdinger_vue/src/components/AvatarList/List.jsx +/quantdinger_vue/src/api/login.js +/quantdinger_vue/src/views/user/Login.vue +/quantdinger_vue/public/logo.png +/quantdinger_vue/src/assets/logo.png +/quantdinger_vue/src/assets/logo.svg +/quantdinger_vue/src/main.js +/quantdinger_vue/src/api/manage.js +/quantdinger_vue/src/mock/services/manage.js +/quantdinger_vue/src/api/market.js +/quantdinger_vue/src/components/Charts/MiniArea.vue +/quantdinger_vue/src/components/Charts/MiniBar.vue +/quantdinger_vue/src/components/Charts/MiniProgress.vue +/quantdinger_vue/src/components/Charts/MiniSmoothArea.vue +/quantdinger_vue/src/components/MultiTab/MultiTab.vue +/quantdinger_vue/src/store/mutation-types.js +/quantdinger_vue/deploy/nginx.conf +/quantdinger_vue/deploy/nginx-docker.conf +/quantdinger_vue/src/components/NoticeIcon/NoticeIcon.vue +/quantdinger_vue/src/components/NProgress/nprogress.less +/quantdinger_vue/src/components/NumberInfo/NumberInfo.vue +/quantdinger_vue/src/mock/services/other.js +/quantdinger_vue/package.json +/quantdinger_vue/src/layouts/PageView.vue +/quantdinger_vue/src/core/permission/permission.js +/quantdinger_vue/src/permission.js +/quantdinger_vue/config/plugin.config.js +/quantdinger_vue/pnpm-lock.yaml +/quantdinger_vue/src/api/portfolio.js +/quantdinger_vue/src/views/trading-assistant/components/PositionRecords.vue +/quantdinger_vue/postcss.config.js +/quantdinger_vue/src/components/Editor/QuillEditor.vue +/quantdinger_vue/src/components/Charts/Radar.vue +/quantdinger_vue/src/components/Charts/RankList.vue +/quantdinger_vue/src/components/IconSelector/README.md +/quantdinger_vue/src/components/Table/README.md +/quantdinger_vue/src/router/README.md +/quantdinger_vue/README.md +/quantdinger_vue/src/views/user/RegisterResult.vue +/quantdinger_vue/src/utils/request.js +/quantdinger_vue/src/components/GlobalHeader/RightContent.vue +/quantdinger_vue/src/utils/routeConvert.js +/quantdinger_vue/src/config/router.config.js +/quantdinger_vue/src/layouts/RouteView.vue +/quantdinger_vue/src/utils/screenLog.js +/quantdinger_vue/src/components/SettingDrawer/settingConfig.js +/quantdinger_vue/src/components/SettingDrawer/SettingDrawer.vue +/quantdinger_vue/src/components/SettingDrawer/SettingItem.vue +/quantdinger_vue/src/api/settings.js +/quantdinger_vue/public/slogo.png +/quantdinger_vue/src/assets/slogo.png +/quantdinger_vue/src/components/Charts/smooth.area.less +/quantdinger_vue/src/components/StandardFormRow/StandardFormRow.vue +/quantdinger_vue/src/store/modules/static-router.js +/quantdinger_vue/src/api/strategy.js +/quantdinger_vue/src/components/TextArea/style.less +/quantdinger_vue/src/mock/services/tagCloud.js +/quantdinger_vue/src/components/Charts/TagCloud.vue +/quantdinger_vue/src/components/TagSelect/TagSelectOption.jsx +/quantdinger_vue/src/locales/lang/th-TH.js +/quantdinger_vue/src/components/SettingDrawer/themeColor.js +/quantdinger_vue/config/themePluginConfig.js +/quantdinger_vue/src/views/trading-assistant/components/TradingRecords.vue +/quantdinger_vue/src/components/Charts/TransferBar.vue +/quantdinger_vue/src/components/Tree/Tree.jsx +/quantdinger_vue/src/components/Charts/Trend.vue +/quantdinger_vue/src/components/Trend/Trend.vue +/quantdinger_vue/src/components/tools/TwoStepCaptcha.vue +/quantdinger_vue/src/core/use.js +/quantdinger_vue/src/api/user.js +/quantdinger_vue/src/mock/services/user.js +/quantdinger_vue/src/store/modules/user.js +/quantdinger_vue/src/layouts/UserLayout.vue +/quantdinger_vue/src/components/_util/util.js +/quantdinger_vue/src/mock/util.js +/quantdinger_vue/src/utils/util.js +/quantdinger_vue/src/utils/utils.less +/quantdinger_vue/src/locales/lang/vi-VN.js +/quantdinger_vue/vue.config.js +/quantdinger_vue/src/components/Editor/WangEditor.vue +/quantdinger_vue/yarn.lock +/quantdinger_vue/src/locales/lang/zh-CN.js +/quantdinger_vue/src/locales/lang/zh-TW.js +/quantdinger_vue/.browserslistrc diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1ddfb..5925268ad 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/backend_api_python/app/data_sources/base.py b/backend_api_python/app/data_sources/base.py index 5eff84f81..9b54d242f 100644 --- a/backend_api_python/app/data_sources/base.py +++ b/backend_api_python/app/data_sources/base.py @@ -140,10 +140,10 @@ def log_result( if klines: latest_time = datetime.fromtimestamp(klines[-1]['time']) time_diff = (datetime.now() - latest_time).total_seconds() - # logger.info( - # f"{self.name}: {symbol} 获取 {len(klines)} 条数据, " - # f"最新时间: {latest_time}, 延迟: {time_diff:.0f}秒" - # ) + logger.info( + f"{self.name}: {symbol} 获取 {len(klines)} 条数据, " + f"最新时间: {latest_time}, 延迟: {time_diff:.0f}秒" + ) # 检查数据是否过旧 max_diff = TIMEFRAME_SECONDS.get(timeframe, 3600) * 2 diff --git a/backend_api_python/app/data_sources/crypto.py b/backend_api_python/app/data_sources/crypto.py index 7b55a8da5..871752ef1 100644 --- a/backend_api_python/app/data_sources/crypto.py +++ b/backend_api_python/app/data_sources/crypto.py @@ -84,7 +84,7 @@ def get_kline( else: symbol_pair = symbol - # logger.info(f"获取加密货币K线: {symbol_pair}, 周期: {ccxt_timeframe}, 条数: {limit}") + logger.info(f"获取加密货币K线: {symbol_pair}, 周期: {ccxt_timeframe}, 条数: {limit}") ohlcv = self._fetch_ohlcv(symbol_pair, ccxt_timeframe, limit, before_time, timeframe) @@ -136,7 +136,7 @@ def _fetch_ohlcv( since = int(start_time.timestamp() * 1000) end_ms = before_time * 1000 - # logger.info(f"历史数据请求: since={since//1000}, end={before_time}, 时间跨度={total_seconds/86400:.1f}天") + logger.info(f"历史数据请求: since={since//1000}, end={before_time}, 时间跨度={total_seconds/86400:.1f}天") # 分页获取数据,直到覆盖完整时间范围 all_ohlcv = [] @@ -160,20 +160,21 @@ def _fetch_ohlcv( last_timestamp = batch[-1][0] # 如果最后一条数据时间超过了结束时间,或者返回数据少于请求量,说明已经获取完毕 - if last_timestamp >= end_ms or len(batch) < batch_limit: + # if last_timestamp >= end_ms or len(batch) < batch_limit: + if last_timestamp >= end_ms: break # 下次从最后一条的下一个时间点开始 timeframe_ms = TIMEFRAME_SECONDS.get(timeframe, 86400) * 1000 current_since = last_timestamp + timeframe_ms - # logger.info(f"分页获取中: 已获取 {len(all_ohlcv)} 条, 继续从 {datetime.fromtimestamp(current_since/1000)}") + logger.info(f"分页获取中: 已获取 {len(all_ohlcv)} 条, 继续从 {datetime.fromtimestamp(current_since/1000)}") ohlcv = all_ohlcv else: ohlcv = self.exchange.fetch_ohlcv(symbol_pair, ccxt_timeframe, limit=limit) - # logger.info(f"CCXT 返回 {len(ohlcv) if ohlcv else 0} 条数据") + logger.info(f"CCXT 返回 {len(ohlcv) if ohlcv else 0} 条数据") return ohlcv except Exception as e: @@ -200,7 +201,7 @@ def _fetch_ohlcv_fallback( since = int((datetime.now() - timedelta(seconds=total_seconds)).timestamp() * 1000) ohlcv = self.exchange.fetch_ohlcv(symbol_pair, ccxt_timeframe, since=since, limit=limit) - # logger.info(f"CCXT 备用方法返回 {len(ohlcv) if ohlcv else 0} 条数据") + logger.info(f"CCXT 备用方法返回 {len(ohlcv) if ohlcv else 0} 条数据") return ohlcv except Exception as e: logger.error(f"CCXT fallback method also failed: {str(e)}") diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index af6b0eaf6..71ffe2497 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -596,7 +596,7 @@ def _run_strategy_loop(self, strategy_id: int): if not klines or len(klines) < 2: logger.error(f"Strategy {strategy_id} failed to fetch K-lines") return - logger.info(rf'Strategy {strategy_id} kline number: {len(klines)}') + logger.info(rf'Strategy {strategy_id} history kline number: {len(klines)}') # 转换为DataFrame df = self._klines_to_dataframe(klines) @@ -1093,7 +1093,8 @@ def _fetch_latest_kline(self, symbol: str, timeframe: str, limit: int = 500) -> market='Crypto', symbol=symbol, timeframe=timeframe, - limit=limit + limit=limit, + before_time=int(time.time()), ) except Exception as e: logger.error(f"Failed to fetch K-lines: {str(e)}") diff --git a/backend_api_python/scripts/simulate_trading_executor.py b/backend_api_python/scripts/simulate_trading_executor.py index 211fa81c1..af07c5305 100644 --- a/backend_api_python/scripts/simulate_trading_executor.py +++ b/backend_api_python/scripts/simulate_trading_executor.py @@ -274,7 +274,7 @@ def _insert_strategy( json.dumps(indicator_config, ensure_ascii=False), json.dumps(trading_config, ensure_ascii=False), json.dumps({}, ensure_ascii=False), - 300, + 3000, now, now, ), From 36ddf09f844e6db14cb0336be38ed970dddde5f7 Mon Sep 17 00:00:00 2001 From: guopengfa Date: Sat, 17 Jan 2026 00:38:40 +0800 Subject: [PATCH 5/8] delete before. --- backend_api_python/app/services/trading_executor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index 71ffe2497..9f8745f27 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -1093,8 +1093,7 @@ def _fetch_latest_kline(self, symbol: str, timeframe: str, limit: int = 500) -> market='Crypto', symbol=symbol, timeframe=timeframe, - limit=limit, - before_time=int(time.time()), + limit=limit ) except Exception as e: logger.error(f"Failed to fetch K-lines: {str(e)}") From 235395491bea16223b5552f6adfc28a3b80e56de Mon Sep 17 00:00:00 2001 From: guopengfa Date: Sat, 17 Jan 2026 00:56:12 +0800 Subject: [PATCH 6/8] recovery decide_interval --- backend_api_python/scripts/simulate_trading_executor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend_api_python/scripts/simulate_trading_executor.py b/backend_api_python/scripts/simulate_trading_executor.py index af07c5305..211fa81c1 100644 --- a/backend_api_python/scripts/simulate_trading_executor.py +++ b/backend_api_python/scripts/simulate_trading_executor.py @@ -274,7 +274,7 @@ def _insert_strategy( json.dumps(indicator_config, ensure_ascii=False), json.dumps(trading_config, ensure_ascii=False), json.dumps({}, ensure_ascii=False), - 3000, + 300, now, now, ), From b4a03a8e3396cc81a0e016c37a99c54274856ecc Mon Sep 17 00:00:00 2001 From: guopengfa Date: Sat, 17 Jan 2026 01:11:58 +0800 Subject: [PATCH 7/8] recovery decide_interval --- backend_api_python/app/services/trading_executor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index 9f8745f27..644ffd977 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -1093,7 +1093,8 @@ def _fetch_latest_kline(self, symbol: str, timeframe: str, limit: int = 500) -> market='Crypto', symbol=symbol, timeframe=timeframe, - limit=limit + limit=limit, + before_time=int(time.time()) ) except Exception as e: logger.error(f"Failed to fetch K-lines: {str(e)}") From b49e642066a7388243dd6a646e2831b5ea173ba4 Mon Sep 17 00:00:00 2001 From: guopengfa Date: Sat, 17 Jan 2026 01:26:25 +0800 Subject: [PATCH 8/8] hide logs --- backend_api_python/app/data_sources/crypto.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend_api_python/app/data_sources/crypto.py b/backend_api_python/app/data_sources/crypto.py index 871752ef1..039bbfa9d 100644 --- a/backend_api_python/app/data_sources/crypto.py +++ b/backend_api_python/app/data_sources/crypto.py @@ -84,7 +84,7 @@ def get_kline( else: symbol_pair = symbol - logger.info(f"获取加密货币K线: {symbol_pair}, 周期: {ccxt_timeframe}, 条数: {limit}") + # logger.info(f"获取加密货币K线: {symbol_pair}, 周期: {ccxt_timeframe}, 条数: {limit}") ohlcv = self._fetch_ohlcv(symbol_pair, ccxt_timeframe, limit, before_time, timeframe) @@ -136,7 +136,7 @@ def _fetch_ohlcv( since = int(start_time.timestamp() * 1000) end_ms = before_time * 1000 - logger.info(f"历史数据请求: since={since//1000}, end={before_time}, 时间跨度={total_seconds/86400:.1f}天") + # logger.info(f"历史数据请求: since={since//1000}, end={before_time}, 时间跨度={total_seconds/86400:.1f}天") # 分页获取数据,直到覆盖完整时间范围 all_ohlcv = [] @@ -168,13 +168,13 @@ def _fetch_ohlcv( timeframe_ms = TIMEFRAME_SECONDS.get(timeframe, 86400) * 1000 current_since = last_timestamp + timeframe_ms - logger.info(f"分页获取中: 已获取 {len(all_ohlcv)} 条, 继续从 {datetime.fromtimestamp(current_since/1000)}") + # logger.info(f"分页获取中: 已获取 {len(all_ohlcv)} 条, 继续从 {datetime.fromtimestamp(current_since/1000)}") ohlcv = all_ohlcv else: ohlcv = self.exchange.fetch_ohlcv(symbol_pair, ccxt_timeframe, limit=limit) - logger.info(f"CCXT 返回 {len(ohlcv) if ohlcv else 0} 条数据") + # logger.info(f"CCXT 返回 {len(ohlcv) if ohlcv else 0} 条数据") return ohlcv except Exception as e: @@ -201,7 +201,7 @@ def _fetch_ohlcv_fallback( since = int((datetime.now() - timedelta(seconds=total_seconds)).timestamp() * 1000) ohlcv = self.exchange.fetch_ohlcv(symbol_pair, ccxt_timeframe, since=since, limit=limit) - logger.info(f"CCXT 备用方法返回 {len(ohlcv) if ohlcv else 0} 条数据") + # logger.info(f"CCXT 备用方法返回 {len(ohlcv) if ohlcv else 0} 条数据") return ohlcv except Exception as e: logger.error(f"CCXT fallback method also failed: {str(e)}")