from flask import Flask, render_template, request, jsonify from backtester import Backtester import pandas as pd import io app = Flask(__name__) # Configure max upload size (e.g., 16MB) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # Configure Jinja2 delimiters to avoid conflict with Vue.js app.jinja_env.variable_start_string = '[[' app.jinja_env.variable_end_string = ']]' @app.errorhandler(413) def request_entity_too_large(error): return jsonify({'status': 'error', 'message': '文件太大,请上传小于 16MB 的文件'}), 413 @app.errorhandler(404) def page_not_found(error): if request.path.startswith('/api/'): return jsonify({'status': 'error', 'message': 'API 端点未找到'}), 404 return render_template('index.html'), 404 # Handle SPA routing if needed, or just 404 page @app.errorhandler(500) def internal_server_error(error): return jsonify({'status': 'error', 'message': '服务器内部错误'}), 500 @app.route('/') def index(): return render_template('index.html') @app.route('/api/backtest', methods=['POST']) def backtest(): try: # Check if it's a file upload (multipart/form-data) custom_data = None if request.content_type and 'multipart/form-data' in request.content_type: short_window = int(request.form.get('short_window', 20)) long_window = int(request.form.get('long_window', 50)) initial_capital = float(request.form.get('initial_capital', 10000)) if 'file' in request.files: file = request.files['file'] if file.filename != '': try: if file.filename.endswith('.csv'): custom_data = pd.read_csv(file) elif file.filename.endswith('.xlsx') or file.filename.endswith('.xls'): custom_data = pd.read_excel(file) else: return jsonify({'status': 'error', 'message': '不支持的文件格式,请上传 CSV 或 Excel 文件'}), 400 except Exception as e: return jsonify({'status': 'error', 'message': f'文件读取失败: {str(e)}'}), 400 else: # JSON request data = request.json short_window = int(data.get('short_window', 20)) long_window = int(data.get('long_window', 50)) initial_capital = float(data.get('initial_capital', 10000)) bt = Backtester() results = bt.run_strategy(short_window, long_window, initial_capital, custom_data=custom_data) return jsonify({'status': 'success', 'data': results}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=7860, debug=True)