File size: 3,123 Bytes
cbdd805
f023109
 
 
 
cbdd805
 
f023109
f0c68c9
cbdd805
 
 
 
f023109
 
 
f0c68c9
f023109
 
 
 
 
f0c68c9
f023109
 
 
 
cbdd805
f023109
f0c68c9
f023109
 
f0c68c9
f023109
 
cbdd805
 
f023109
 
 
f0c68c9
cbdd805
f023109
f0c68c9
f023109
f0c68c9
f023109
 
 
 
 
 
 
 
 
 
 
 
f0c68c9
cbdd805
 
f0c68c9
f023109
 
 
 
 
 
 
 
 
f0c68c9
f023109
 
f0c68c9
 
 
f023109
cbdd805
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
# ... (previous code remains the same)

# Backtesting simulation loop
for i in range(1, len(data)):
    today = data.index[i]
    price = float(data['Close'].iloc[i])  # Cast to float
    rsi_today = float(data['RSI'].iloc[i])  # Cast to float
    
    # Check for buy signal
    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,  # Ensure scalar
                "trailing_stop": price * (1 - trailing_stop_pct)
            })
            data.at[today, 'Buy'] = True

    # Update positions and check sell conditions
    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)
        
        # Partial sell condition
        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
        
        # Trailing stop exit
        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]
    
    # Update equity curve
    position_value = sum(pos["shares"] * price for pos in open_positions)
    equity_curve.append(cash + position_value)

# ... (remaining code remains the same)