import randomimport matplotlib.pyplot as pltfrom collections import Counterimport matplotlib.font_manager as fm# ---------- 设置中文字体 ----------def set_chinese_font(): chinese_fonts = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Zen Hei', 'Noto Sans CJK SC', 'Arial Unicode MS', 'KaiTi'] for font in chinese_fonts: if any(f.name == font for f in fm.fontManager.ttflist): plt.rcParams['font.sans-serif'] = [font] break else: print("警告:未找到中文字体,图表中的中文将显示为乱码。") plt.rcParams['axes.unicode_minus'] = Falseset_chinese_font()# ---------------------------------def parse_input(): """获取并验证用户输入:胜率(支持小数或百分数)和交易次数""" while True: p_str = input("请输入胜率(例如 0.6 或 60%):").strip() if p_str.endswith('%'): try: p = float(p_str[:-1]) / 100.0 except ValueError: print("胜率格式错误,请重新输入") continue else: try: p = float(p_str) except ValueError: print("胜率格式错误,请重新输入") continue if 0 <= p <= 1: break else: print("胜率应在0到1之间,请重新输入") while True: try: n = int(input("请输入交易次数(正整数):").strip()) if n > 0: break else: print("交易次数必须为正整数") except ValueError: print("请输入有效的整数") return p, ndef generate_trades(p, n): """生成n次交易结果,1表示盈利,0表示亏损""" return [1 if random.random() < p else 0 for _ in range(n)]def analyze_trades(trades): """ 分析交易序列,返回: max_loss, max_win, median_loss, median_win, loss_streaks, win_streaks """ loss_streaks = [] win_streaks = [] if not trades: return 0, 0, 0.0, 0.0, loss_streaks, win_streaks cur_type = trades[0] cur_len = 1 for i in range(1, len(trades)): if trades[i] == cur_type: cur_len += 1 else: if cur_type == 0: loss_streaks.append(cur_len) else: win_streaks.append(cur_len) cur_type = trades[i] cur_len = 1 if cur_type == 0: loss_streaks.append(cur_len) else: win_streaks.append(cur_len) max_loss = max(loss_streaks) if loss_streaks else 0 max_win = max(win_streaks) if win_streaks else 0 def median(lst): if not lst: return 0.0 s = sorted(lst) n = len(s) if n % 2 == 1: return float(s[n // 2]) else: return (s[n // 2 - 1] + s[n // 2]) / 2.0 median_loss = median(loss_streaks) median_win = median(win_streaks) return max_loss, max_win, median_loss, median_win, loss_streaks, win_streaksdef plot_results(trades, loss_streaks, win_streaks): """绘制交易序列图及连续盈亏长度的分布图(带柱上数值标签)""" n = len(trades) colors = ['green' if x == 1 else 'red' for x in trades] fig = plt.figure(figsize=(14, 8)) # 第一行:交易序列图 ax1 = plt.subplot(2, 2, (1, 2)) ax1.bar(range(1, n+1), [1] * n, width=1.0, color=colors, edgecolor='none', alpha=0.7) ax1.set_xlim(0, n+1) ax1.set_ylim(0, 1.2) ax1.set_ylabel("交易结果") ax1.set_yticks([0, 1]) ax1.set_yticklabels(['亏损', '盈利']) ax1.set_xlabel("交易序号") ax1.set_title("交易盈亏序列(红色=亏损,绿色=盈利)") ax1.grid(axis='x', linestyle='--', alpha=0.5) # 第二行左:亏损长度分布 ax2 = plt.subplot(2, 2, 3) if loss_streaks: loss_counter = Counter(loss_streaks) lengths = sorted(loss_counter.keys()) freqs = [loss_counter[l] for l in lengths] ax2.bar(lengths, freqs, color='red', alpha=0.7, edgecolor='black') for l, f in zip(lengths, freqs): ax2.text(l, f + 0.1, str(f), ha='center', va='bottom', fontsize=9) ax2.set_xlabel("连续亏损次数") ax2.set_ylabel("频数") ax2.set_title("连续亏损长度分布") max_loss = max(lengths) max_loss_freq = loss_counter[max_loss] ax2.text(max_loss, max_loss_freq, f"max={max_loss}", ha='center', va='bottom') else: ax2.text(0.5, 0.5, "无亏损段", transform=ax2.transAxes, ha='center', va='center') ax2.set_title("连续亏损长度分布") # 第二行右:盈利长度分布 ax3 = plt.subplot(2, 2, 4) if win_streaks: win_counter = Counter(win_streaks) lengths = sorted(win_counter.keys()) freqs = [win_counter[l] for l in lengths] ax3.bar(lengths, freqs, color='green', alpha=0.7, edgecolor='black') for l, f in zip(lengths, freqs): ax3.text(l, f + 0.1, str(f), ha='center', va='bottom', fontsize=9) ax3.set_xlabel("连续盈利次数") ax3.set_ylabel("频数") ax3.set_title("连续盈利长度分布") max_win = max(lengths) max_win_freq = win_counter[max_win] ax3.text(max_win, max_win_freq, f"max={max_win}", ha='center', va='bottom') else: ax3.text(0.5, 0.5, "无盈利段", transform=ax3.transAxes, ha='center', va='center') ax3.set_title("连续盈利长度分布") plt.tight_layout() plt.show()def main(): p, n = parse_input() trades = generate_trades(p, n) max_loss, max_win, median_loss, median_win, loss_streaks, win_streaks = analyze_trades(trades) print("\n====== 分析结果 ======") print(f"交易序列长度: {n}") print(f"胜率: {p:.2%}") print(f"最大连续亏损次数: {max_loss}") print(f"最大连续盈利次数: {max_win}") print(f"中位数连续亏损次数: {median_loss:.2f}") print(f"中位数连续盈利次数: {median_win:.2f}") print("=====================\n") plot_results(trades, loss_streaks, win_streaks)if __name__ == "__main__": main()