value averging model bulild, can use yahoo and csv fron other sources

This commit is contained in:
2026-01-28 08:48:53 +08:00
parent 9e7f474d5e
commit cf708d2466
12 changed files with 38342 additions and 27 deletions
+54 -6
View File
@@ -1,6 +1,6 @@
from flask import Flask, render_template, jsonify
from flask import Flask, render_template,request, jsonify
from datetime import datetime, timedelta
from engine import DataEngine
from engine import DataEngine, StrategyEngine
import concurrent.futures
from flask_caching import Cache
import csv, os, logging
@@ -9,10 +9,6 @@ from concurrent.futures import ThreadPoolExecutor
app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'SimpleCache'})
import os
import csv
@cache.memoize(timeout=3600)
def fetch_and_calculate(config):
engine = DataEngine(config['symbol'], config['url'], config['provider'])
@@ -63,5 +59,57 @@ def run_sync():
report = engine.global_sync()
return jsonify(report)
@app.route('/api/backtest', methods=['POST'])
def api_backtest():
data = request.get_json() or {}
# 1. Extract and Sanitize Symbol
symbol = data.get('symbol', '').strip().upper()
print(f"DEBUG: Processing {symbol}")
if not symbol:
return jsonify({"error": "Symbol is required"}), 400
try:
# 2. Extract Numerical and Logic Inputs (Matching updated JS keys)
initial = float(data.get('initial_inv', 0))
monthly = float(data.get('monthly_target', 0))
start_date = data.get('start_date', '2024-01-01')
# Robust Boolean Check for toggles
allow_sell = data.get('allow_sell') is True
allow_frac = data.get('allow_fractional') is True
# 3. Initialize Engines
# DataEngine __init__ now calls ensure_data() to download if missing
data_eng = DataEngine(symbol=symbol)
if not os.path.exists(data_eng.file_path):
return jsonify({"error": f"Data for {symbol} could not be retrieved."}), 404
strat_eng = StrategyEngine(data_eng)
# 4. Calculation
history = strat_eng.calculate_va_vs_dca(
initial_inv=initial,
monthly_target=monthly,
start_date=start_date,
allow_sell=allow_sell,
allow_fractional=allow_frac
)
return jsonify(history)
except Exception as e:
import traceback
print("CRITICAL ERROR in /api/backtest:")
print(traceback.format_exc())
return jsonify({"error": "Internal Server Error. Check terminal logs."}), 500
@app.route('/backtest') # This is the URL you will actually visit
def backtest_ui():
# This sends the HTML file to your browser
return render_template('val_avg_cal.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)