|
|
|
|
|
|
|
for i in range(1, len(data)): |
|
today = data.index[i] |
|
price = float(data['Close'].iloc[i]) |
|
rsi_today = float(data['RSI'].iloc[i]) |
|
|
|
|
|
macd_today = float(data['MACD'].iloc[i]) |
|
signal_today = float(data['MACD_signal'].iloc[i]) |
|
macd_yesterday = float(data['MACD'].iloc[i-1]) |
|
signal_yesterday = float(data['MACD_signal'].iloc[i-1]) |
|
|
|
buy_condition = (macd_yesterday < signal_yesterday) and (macd_today > signal_today) and (rsi_today < 50) |
|
|
|
if buy_condition and (last_buy_date is None or (today - last_buy_date).days >= min_days_between_buys): |
|
allocation = cash * buy_fraction |
|
if allocation > 0: |
|
shares_bought = allocation / price |
|
cash -= allocation |
|
last_buy_date = today |
|
open_positions.append({ |
|
"entry_date": today, |
|
"entry_price": price, |
|
"allocated": allocation, |
|
"shares": shares_bought, |
|
"highest": price, |
|
"trailing_stop": price * (1 - trailing_stop_pct) |
|
}) |
|
data.at[today, 'Buy'] = True |
|
|
|
|
|
positions_to_remove = [] |
|
for idx, pos in enumerate(open_positions): |
|
current_highest = pos["highest"] |
|
if price > current_highest: |
|
pos["highest"] = price |
|
pos["trailing_stop"] = pos["highest"] * (1 - trailing_stop_pct) |
|
|
|
|
|
if price >= (pos["entry_price"] * target_multiplier) and rsi_today > 50: |
|
shares_to_sell = pos["shares"] * sell_fraction |
|
cash += shares_to_sell * price |
|
pos["shares"] -= shares_to_sell |
|
pos["allocated"] -= shares_to_sell * pos["entry_price"] |
|
data.at[today, 'Sell'] = True |
|
if pos["shares"] < 0.001: |
|
completed_trades.append({ |
|
"entry_date": pos["entry_date"], |
|
"exit_date": today, |
|
"entry_price": pos["entry_price"], |
|
"exit_price": price, |
|
"allocated": pos["allocated"] |
|
}) |
|
positions_to_remove.append(idx) |
|
continue |
|
|
|
|
|
current_trailing_stop = pos["trailing_stop"] |
|
if price < current_trailing_stop: |
|
cash += pos["shares"] * price |
|
completed_trades.append({ |
|
"entry_date": pos["entry_date"], |
|
"exit_date": today, |
|
"entry_price": pos["entry_price"], |
|
"exit_price": price, |
|
"allocated": pos["allocated"] |
|
}) |
|
positions_to_remove.append(idx) |
|
|
|
for idx in reversed(positions_to_remove): |
|
del open_positions[idx] |
|
|
|
|
|
position_value = sum(pos["shares"] * price for pos in open_positions) |
|
equity_curve.append(cash + position_value) |
|
|
|
|