Bootstrap

基于凯利公式的仓位管理

相对于全仓买入, 增加仓位管理(凯利公式), 在交易过程中动态更新胜率和赔率, 有效降低风险回撤和资金回测.

def simulate_kelly_trading(stock_data, signal, initial_balance=100000, commission_rate=0.0005, slippage_rate=0.01, tax_rate=0.001):

balance = initial_balance

position = 0

trade_history = []

portfolio_value_history = []

peak_value = initial_balance

max_risk_drawdown = 0

max_capital_drawdown = 0

win_count = 0

loss_count = 0

total_win = 0

total_loss = 0

stock_data['trade_date'] = pd.to_datetime(stock_data['trade_date'], format='%Y%m%d')

for index, row in stock_data.iterrows():

if signal[index] == 'buy' and position == 0:

if win_count + loss_count > 0:

win_rate = win_count / (win_count + loss_count)

avg_win = total_win / win_count if win_count > 0 else 0

avg_loss = total_loss / loss_count if loss_count > 0 else 0

kelly_fraction = calculate_kelly_position(win_rate, avg_win, avg_loss)

else:

kelly_fraction = 0.2

position = int((balance * kelly_fraction) / (row['close'] + slippage_rate))

position = int(position / 100) * 100

buy_cash = (row['close'] + slippage_rate) * position

commission = round(max(buy_cash * commission_rate, 5), 2)

balance = balance - buy_cash - commission

trade_history.append(('buy', stock_data['trade_date'][index], row['close']))

elif signal[index] =='sell' and position > 0:

last_balance = balance

sell_cash = (row['close'] - slippage_rate) * position

commission = round(max(sell_cash * commission_rate, 5), 2)

tax = round(sell_cash * tax_rate, 2)

balance = balance + sell_cash - commission - tax

trade_history.append(('sell', stock_data['trade_date'][index], row['close']))

position = 0

if balance > last_balance:

win_count += 1

total_win += balance - last_balance

else:

loss_count += 1

total_loss += last_balance - balance

portfolio_value = balance + position * row['close']

portfolio_value_history.append(portfolio_value)

if portfolio_value > peak_value:

peak_value = portfolio_value

risk_drawdown = (peak_value - portfolio_value) / peak_value

if risk_drawdown > max_risk_drawdown:

max_risk_drawdown = risk_drawdown

trade_history.append(('max_risk_drawdown', stock_data['trade_date'][index], max_risk_drawdown))

capital_drawdown = (initial_balance - portfolio_value) / initial_balance

if capital_drawdown > max_capital_drawdown:

max_capital_drawdown = capital_drawdown

trade_history.append(('max_capital_drawdown', stock_data['trade_date'][index], max_capital_drawdown))

if position > 0:

balance = position * stock_data.iloc[-1]['close']

trade_history.append(('sell', stock_data.iloc[-1]['trade_date'], stock_data.iloc[-1]['close']))

return balance, trade_history, max_risk_drawdown, max_capital_drawdown

Initl Balance: 100000

Final Balance: 104072.14

Max Risk Drawdown: 18.69%

Max Capital Drawdown: 0.61%

;