234 lines
8.7 KiB
Python
234 lines
8.7 KiB
Python
"""
|
|
缠论分析系统主程序入口
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import sys
|
|
import os
|
|
from datetime import datetime
|
|
|
|
# 添加项目根目录到Python路径
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from data.data_fetcher import DataFetcher
|
|
from data.data_processor import DataProcessor
|
|
from core.chan_analyzer import ChanAnalyzer
|
|
from web.app import run_app
|
|
|
|
# 配置日志
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.StreamHandler(sys.stdout),
|
|
logging.FileHandler('chan_analysis.log', encoding='utf-8')
|
|
]
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def run_command_line_analysis(args):
|
|
"""运行命令行分析"""
|
|
try:
|
|
logger.info("开始命令行缠论分析...")
|
|
|
|
# 初始化组件
|
|
data_fetcher = DataFetcher(args.exchange)
|
|
data_processor = DataProcessor()
|
|
|
|
# 获取数据
|
|
logger.info(f"获取 {args.symbol} {args.timeframe} 数据...")
|
|
klines = data_fetcher.fetch_klines(
|
|
symbol=args.symbol,
|
|
timeframe=args.timeframe,
|
|
limit=args.limit
|
|
)
|
|
|
|
if klines.empty:
|
|
logger.error("未获取到数据")
|
|
return
|
|
|
|
# 数据处理
|
|
logger.info("清理和验证数据...")
|
|
if not data_processor.validate_klines(klines):
|
|
logger.warning("数据验证失败,继续处理...")
|
|
|
|
klines = data_processor.clean_klines(klines)
|
|
|
|
# 缠论分析
|
|
logger.info("开始缠论分析...")
|
|
analyzer = ChanAnalyzer(klines)
|
|
analysis_summary = analyzer.run_full_analysis(args.fractal_strength)
|
|
|
|
# 输出分析结果
|
|
print("\n" + "="*50)
|
|
print("缠论分析结果摘要")
|
|
print("="*50)
|
|
|
|
# 数据信息
|
|
data_info = analysis_summary['data_info']
|
|
print(f"\n数据信息:")
|
|
print(f" 原始K线数量: {data_info['original_klines']}")
|
|
print(f" 处理后K线数量: {data_info['processed_klines']}")
|
|
print(f" 数据时间范围: {data_info['date_range']['start']} 至 {data_info['date_range']['end']}")
|
|
|
|
# 分型信息
|
|
fractal_info = analysis_summary['fractal_info']
|
|
print(f"\n分型信息:")
|
|
print(f" 总分型数量: {fractal_info['total']}")
|
|
print(f" 顶分型: {fractal_info['top']}")
|
|
print(f" 底分型: {fractal_info['bottom']}")
|
|
|
|
# 笔信息
|
|
stroke_info = analysis_summary['stroke_info']
|
|
print(f"\n笔信息:")
|
|
print(f" 总笔数量: {stroke_info['total']}")
|
|
print(f" 上升笔: {stroke_info['up']}")
|
|
print(f" 下降笔: {stroke_info['down']}")
|
|
|
|
# 线段信息
|
|
segment_info = analysis_summary['segment_info']
|
|
print(f"\n线段信息:")
|
|
print(f" 总线段数量: {segment_info['total']}")
|
|
print(f" 上升线段: {segment_info['up']}")
|
|
print(f" 下降线段: {segment_info['down']}")
|
|
|
|
# 中枢信息
|
|
cb_info = analysis_summary['central_bank_info']
|
|
print(f"\n中枢信息:")
|
|
print(f" 总中枢数量: {cb_info['total']}")
|
|
if cb_info['levels']:
|
|
print(" 级别分布:")
|
|
for level, count in cb_info['levels'].items():
|
|
print(f" {level}: {count}个")
|
|
|
|
# 买卖点信息
|
|
signal_info = analysis_summary['trading_signal_info']
|
|
print(f"\n买卖点信息:")
|
|
print(f" 总信号数量: {signal_info['total']}")
|
|
print(f" 买点: {signal_info['buy_points']}")
|
|
print(f" 卖点: {signal_info['sell_points']}")
|
|
if signal_info['by_class']:
|
|
print(" 类别分布:")
|
|
for class_name, count in signal_info['by_class'].items():
|
|
print(f" {class_name}: {count}个")
|
|
|
|
# 获取最新信号
|
|
latest_signals = analyzer.get_latest_signals(24) # 最近24小时
|
|
if latest_signals:
|
|
print(f"\n最近24小时信号 ({len(latest_signals)}个):")
|
|
for signal in latest_signals:
|
|
signal_type = "买点" if signal.signal_type == 'buy' else "卖点"
|
|
class_type = {"first": "一类", "second": "二类", "third": "三类"}.get(signal.point_class, "未知")
|
|
print(f" {signal.timestamp.strftime('%m-%d %H:%M')} - {class_type}{signal_type} - 价格:{signal.price:.2f} - 强度:{signal.strength:.3f}")
|
|
|
|
# 当前市场结构
|
|
market_structure = analyzer.get_current_market_structure()
|
|
if market_structure:
|
|
print(f"\n当前市场结构:")
|
|
print(f" 当前价格: {market_structure.get('current_price', 'N/A')}")
|
|
trend_map = {'upward': '上升', 'downward': '下降', 'sideways': '震荡', 'unclear': '不明'}
|
|
print(f" 趋势方向: {trend_map.get(market_structure.get('trend'), '未知')}")
|
|
phase_map = {'consolidation': '盘整', 'trending': '趋势', 'unknown': '未知'}
|
|
print(f" 市场阶段: {phase_map.get(market_structure.get('market_phase'), '未知')}")
|
|
|
|
# 保存结果
|
|
if args.export:
|
|
export_results(analyzer, args)
|
|
|
|
logger.info("命令行分析完成")
|
|
|
|
except Exception as e:
|
|
logger.error(f"命令行分析失败: {e}")
|
|
raise
|
|
|
|
|
|
def export_results(analyzer: ChanAnalyzer, args):
|
|
"""导出分析结果"""
|
|
try:
|
|
results = analyzer.export_results()
|
|
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
export_dir = f"exports/chan_analysis_{args.symbol.replace('/', '_')}_{timestamp}"
|
|
os.makedirs(export_dir, exist_ok=True)
|
|
|
|
# 保存各种分析结果
|
|
for name, df in results.items():
|
|
if not df.empty:
|
|
filename = f"{export_dir}/{name}.csv"
|
|
df.to_csv(filename, encoding='utf-8-sig')
|
|
logger.info(f"导出 {name} 到 {filename}")
|
|
|
|
# 保存分析摘要
|
|
with open(f"{export_dir}/summary.txt", 'w', encoding='utf-8') as f:
|
|
f.write(f"缠论分析结果摘要\n")
|
|
f.write(f"交易对: {args.symbol}\n")
|
|
f.write(f"时间周期: {args.timeframe}\n")
|
|
f.write(f"分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
f.write(f"数据数量: {args.limit}\n")
|
|
f.write(f"分型强度: {args.fractal_strength}\n")
|
|
|
|
logger.info(f"分析结果已导出到 {export_dir}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"导出结果失败: {e}")
|
|
|
|
|
|
def main():
|
|
"""主程序入口"""
|
|
parser = argparse.ArgumentParser(description='缠论分析系统')
|
|
|
|
# 运行模式
|
|
parser.add_argument('--mode', choices=['web', 'cli'], default='web',
|
|
help='运行模式:web(Web界面) 或 cli(命令行)')
|
|
|
|
# 数据参数
|
|
parser.add_argument('--symbol', default='BTC/USDT',
|
|
help='交易对 (默认: BTC/USDT)')
|
|
parser.add_argument('--timeframe', default='1h',
|
|
help='时间周期 (默认: 1h)')
|
|
parser.add_argument('--limit', type=int, default=500,
|
|
help='获取的K线数量 (默认: 500)')
|
|
parser.add_argument('--exchange', default='binance',
|
|
help='交易所 (默认: binance)')
|
|
|
|
# 分析参数
|
|
parser.add_argument('--fractal-strength', type=int, default=1,
|
|
help='分型强度要求 (默认: 1)')
|
|
|
|
# 输出参数
|
|
parser.add_argument('--export', action='store_true',
|
|
help='是否导出分析结果')
|
|
|
|
# Web参数
|
|
parser.add_argument('--port', type=int, default=8050,
|
|
help='Web服务端口 (默认: 8050)')
|
|
parser.add_argument('--debug', action='store_true',
|
|
help='是否启用调试模式')
|
|
|
|
args = parser.parse_args()
|
|
|
|
logger.info("缠论分析系统启动")
|
|
logger.info(f"运行模式: {args.mode}")
|
|
|
|
try:
|
|
if args.mode == 'web':
|
|
logger.info(f"启动Web服务,端口: {args.port}")
|
|
print(f"\n缠论分析系统Web界面")
|
|
print(f"访问地址: http://localhost:{args.port}")
|
|
print("按 Ctrl+C 停止服务\n")
|
|
run_app(debug=args.debug, port=args.port)
|
|
else:
|
|
run_command_line_analysis(args)
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("用户中断,程序退出")
|
|
except Exception as e:
|
|
logger.error(f"程序执行失败: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |