1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| def three_percent_signal_trading_with_30_percent_rule( initial_stock_value, initial_bond_value, target_stock_allocation=0.8, target_bond_allocation=0.2, signal_threshold=0.03, bear_market_threshold=0.30, quarterly_returns_stock=None, quarterly_returns_bond=None ): """ 模擬「3%訊號線交易」策略,加入「跌30%不出場」規則。 Args: initial_stock_value (float): 初始股票ETF價值。 initial_bond_value (float): 初始債券ETF價值。 target_stock_allocation (float): 目標股票配置比例 (0到1之間)。 target_bond_allocation (float): 目標債券配置比例 (0到1之間)。 signal_threshold (float): 3%訊號線,即觸發交易的波動閾值。 bear_market_threshold (float): 觸發熊市保護的下跌閾值,例如 0.30 代表跌30%。 quarterly_returns_stock (list): 每季股票ETF的報酬率列表。 quarterly_returns_bond (list): 每季債券ETF的報酬率列表。 Returns: tuple: 最終股票價值, 最終債券價值, 交易紀錄。 """ current_stock_value = initial_stock_value current_bond_value = initial_bond_value trade_log = []
historical_max_stock_value = initial_stock_value in_bear_market_protection = False
print(f"--- 初始資產配置 ---") print(f"初始股票價值: ${current_stock_value:,.2f}") print(f"初始債券價值: ${current_bond_value:,.2f}") print(f"總資產: ${current_stock_value + current_bond_value:,.2f}\n")
num_quarters = len(quarterly_returns_stock) if quarterly_returns_stock else 0
for q in range(num_quarters): print(f"--- 第 {q+1} 季 ---") if quarterly_returns_stock and q < len(quarterly_returns_stock): current_stock_value *= (1 + quarterly_returns_stock[q]) if quarterly_returns_bond and q < len(quarterly_returns_bond): current_bond_value *= (1 + quarterly_returns_bond[q])
total_value = current_stock_value + current_bond_value
if current_stock_value > historical_max_stock_value: historical_max_stock_value = current_stock_value in_bear_market_protection = False print(f"股票價值創新高: ${historical_max_stock_value:,.2f},退出熊市保護模式。")
if historical_max_stock_value > 0: current_stock_drawdown = (historical_max_stock_value - current_stock_value) / historical_max_stock_value if current_stock_drawdown >= bear_market_threshold and not in_bear_market_protection: in_bear_market_protection = True print(f"*** 觸發熊市保護!股票從歷史高點(${historical_max_stock_value:,.2f})下跌了 {current_stock_drawdown*100:.2f}%。本季及後續將暫停再平衡交易。 ***") elif in_bear_market_protection and current_stock_drawdown < bear_market_threshold: in_bear_market_protection = False print(f"股票從熊市中回升,跌幅({current_stock_drawdown*100:.2f}%)小於閾值,解除熊市保護。")
trade_amount = 0 trade_type = "無交易" log_message = ""
if in_bear_market_protection: log_message = "處於熊市保護模式,本季不進行再平衡交易。" else: target_stock_value = total_value * target_stock_allocation deviation = (current_stock_value - target_stock_value) / target_stock_value
if abs(deviation) >= signal_threshold: trade_amount = abs(current_stock_value - target_stock_value) if deviation > 0: current_stock_value -= trade_amount current_bond_value += trade_amount trade_type = "賣出股票" log_message = f"股票部位過高 ({deviation*100:.2f}%),賣出股票 ${trade_amount:,.2f},轉入債券。" else: current_stock_value += trade_amount current_bond_value -= trade_amount trade_type = "買入股票" log_message = f"股票部位過低 ({deviation*100:.2f}%),買入股票 ${trade_amount:,.2f},來自債券。" else: log_message = f"股票偏離度({deviation*100:.2f}%)在訊號線({signal_threshold*100:.2f}%)內,無需交易。"
trade_log.append({ "quarter": q + 1, "stock_value_after_return": current_stock_value, "bond_value_after_return": current_bond_value, "total_value": total_value, "historical_max_stock_value": historical_max_stock_value, "in_bear_market_protection": in_bear_market_protection, "trade_type": trade_type, "trade_amount": trade_amount, "message": log_message })
print(f"當前股票價值 (成長後): ${current_stock_value:,.2f}") print(f"當前債券價值 (成長後): ${current_bond_value:,.2f}") print(f"本季總資產: ${total_value:,.2f}") print(f"當前股票歷史高點: ${historical_max_stock_value:,.2f}") print(f"是否處於熊市保護: {in_bear_market_protection}") print(log_message) print(f"交易後股票價值: ${current_stock_value:,.2f}") print(f"交易後債券價值: ${current_bond_value:,.2f}\n")
print("--- 模擬結束 ---") print(f"最終股票價值: ${current_stock_value:,.2f}") print(f"最終債券價值: ${current_bond_value:,.2f}") print(f"最終總資產: ${current_stock_value + current_bond_value:,.2f}")
return current_stock_value, current_bond_value, trade_log
quarterly_stock_returns_volatile = [0.05, 0.02, -0.10, -0.15, -0.08, 0.03, 0.12, 0.05, -0.02, 0.07, 0.03] quarterly_bond_returns_stable = [0.01, 0.005, 0.008, 0.003, 0.01, 0.002, 0.005, 0.001, 0.004, 0.003, 0.002]
final_stock_30, final_bond_30, log_30 = three_percent_signal_trading_with_30_percent_rule( initial_stock_value=80000, initial_bond_value=20000, quarterly_returns_stock=quarterly_stock_returns_volatile, quarterly_returns_bond=quarterly_bond_returns_stable, bear_market_threshold=0.30 )
|