diff --git a/ft-app/app/collector.py b/ft-app/app/collector.py index 0c0e4db..85d285e 100644 --- a/ft-app/app/collector.py +++ b/ft-app/app/collector.py @@ -1,7 +1,10 @@ """Data collector — fetch OHLCV from akshare and upsert into daily_bars.""" +import socket import threading import time from datetime import date + +socket.setdefaulttimeout(15) from app.database import SessionLocal from app.models import DailyBar, Contract from app.engine.lock_strategy import compute_amp_5d @@ -111,7 +114,9 @@ def sync_positions_bg(contract_code: str) -> bool: r[0] for r in db.query(DailyBar.date) .filter(DailyBar.contract == code) - .order_by(DailyBar.date).all() + .order_by(DailyBar.date.desc()) + .limit(20) + .all() ] missing = [d for d in bar_dates if d not in existing_dates] total_missing = len(missing) @@ -341,10 +346,10 @@ def _sync_positions_for_contract(db, contract_code: str) -> int: r[0] for r in db.query(DailyBar.date) .filter(DailyBar.contract == code) - .order_by(DailyBar.date) + .order_by(DailyBar.date.desc()) + .limit(20) .all() ] - inserted = 0 for d in bar_dates: if d in existing_dates: diff --git a/ft-app/app/templates/admin.html b/ft-app/app/templates/admin.html index 7d22bc3..5efc5e0 100644 --- a/ft-app/app/templates/admin.html +++ b/ft-app/app/templates/admin.html @@ -245,16 +245,24 @@ function pollProgress() { clearInterval(syncTimer); syncTimer = null; document.getElementById('sync-progress-bar').style.width = '100%'; - var resultText = data.result > 0 ? ' · +' + data.result : ''; - document.getElementById('sync-progress-label').textContent = data.label + ' ✓' + resultText; + if (data.result > 0) { + document.getElementById('sync-progress-label').textContent = data.label + ' ✓ · +' + data.result; + } else if (data.total > 0) { + document.getElementById('sync-progress-label').textContent = data.label + ' ⚠ 无新数据,历史日期无可用持仓'; + } else { + document.getElementById('sync-progress-label').textContent = data.label + ' ✓ 已是最新'; + } document.getElementById('sync-progress-pct').textContent = ''; - // Remember which product headers are expanded before reload - var expanded = []; - document.querySelectorAll('.product-body').forEach(function(b, i) { - if (b.style.display === 'block') expanded.push(i); - }); - try { sessionStorage.setItem('ft-expanded', JSON.stringify(expanded)); } catch(e) {} - setTimeout(function() { location.reload(); }, 1200); + document.getElementById('sync-progress').insertAdjacentHTML('beforeend', + ''); + if (data.result > 0) { + var expanded = []; + document.querySelectorAll('.product-body').forEach(function(b, i) { + if (b.style.display === 'block') expanded.push(i); + }); + try { sessionStorage.setItem('ft-expanded', JSON.stringify(expanded)); } catch(e) {} + setTimeout(function() { location.reload(); }, 1200); + } }, delay); } }); @@ -317,5 +325,18 @@ function toggleProduct(header) { } catch(e) {} })(); +// Auto-show progress bar if a sync is already running +(function() { + fetch('/admin/sync-status') + .then(function(r) { return r.json(); }) + .then(function(data) { + if (data.running) { + showProgress(); + syncTimer = setInterval(pollProgress, 500); + pollProgress(); + } + }); +})(); + {% endblock %} diff --git a/ft-app/app/templates/contract.html b/ft-app/app/templates/contract.html index 9f1147a..ee03cb5 100644 --- a/ft-app/app/templates/contract.html +++ b/ft-app/app/templates/contract.html @@ -13,21 +13,18 @@ 共 {{ total_rows }} 条 +{% if page == 1 and next_date %} +
+ 📅 次日预测 + {{ next_date }} {{ next_weekday }} + 预计振幅 + {{ next_amp }} +
+{% endif %} +
- {% if page == 1 and next_date %} - - - - - - - - - - - {% endif %} {% for row in rows %} @@ -150,10 +147,12 @@ function showDrawer(cell, product, calcRows, isNext) { document.getElementById('overlay').classList.add('show'); document.getElementById('drawer').classList.add('show'); - var row = cell.parentElement.parentElement; - if (activeRow) activeRow.classList.remove('active'); - row.classList.add('active'); - activeRow = row; + if (!isNext) { + var row = cell.parentElement.parentElement; + if (activeRow) activeRow.classList.remove('active'); + row.classList.add('active'); + activeRow = row; + } } {% endblock %} diff --git a/ft-app/docker-compose.yml b/ft-app/docker-compose.yml index c86e186..236aa8a 100644 --- a/ft-app/docker-compose.yml +++ b/ft-app/docker-compose.yml @@ -1,6 +1,8 @@ services: app: build: . + image: ft-app + container_name: app ports: - "8000:8000" volumes:
日期星期开盘收盘最高最低波幅5日均振幅
{{ next_date }}{{ next_weekday }}{{ next_amp }}
{{ row.date }}