File size: 3,443 Bytes
d53dc44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import sys, re

with open('main.py', 'r', encoding='utf-8') as f:
    text = f.read()

# Replace the immediate execution block
old_exec_block = r'''        # 4\. ACTION / EXECUTION
        # \?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?
        direction = portfolio.get_open_directions\(\).get\(symbol\)
.*?
                alert\(f"Buy Order Submitted: {symbol} @ \"\)'''

new_exec_block = '''        # 4. ACTION / EXECUTION
        # Instead of executing immediately, we just collect the valid BUY signals for batch processing!
        direction = portfolio.get_open_directions().get(symbol)
        if direction:
            continue
            
        if current_price and sig.score >= config.SIGNAL_BUY_THRESHOLD:
            pending_buys.append({
                "symbol": symbol,
                "price": current_price,
                "score": sig.score,
                "pt": pt
            })'''

text = re.sub(old_exec_block, new_exec_block, text, flags=re.DOTALL)

# Add pending_buys = [] at start of run_trading_cycle
text = text.replace('def run_trading_cycle():', 'def run_trading_cycle():\n    pending_buys = []')

# Add execution at the end of run_trading_cycle
exec_footer = '''    # 5. PRIORITIZED BATCH EXECUTION
    if pending_buys:
        logger.info("Found %d pending buys. Sorting by price priority...", len(pending_buys))
        
        def price_priority(buy):
            p = buy['price']
            if p < 100: return 1
            if p < 200: return 2
            return 3 # Ignore >200
            
        # Filter out anything >= 200 and sort by priority, then by score
        valid_buys = [b for b in pending_buys if price_priority(b) < 3]
        valid_buys.sort(key=lambda b: (price_priority(b), -b['score']))
        
        for buy in valid_buys:
            sym = buy['symbol']
            price = buy['price']
            pt = buy['pt']
            
            # Check overnight risk
            if config.NO_OVERNIGHT_RISK and portfolio.has_overnight_risk():
                logger.info("%s: Skipped entry (Overnight risk limit)", sym)
                continue
                
            qty, risk_amount = calculate_position_size(price, pt.stop_loss, config.ALLOCATED_CAPITAL)
            if qty <= 0.0:
                continue
                
            notional = qty * price
            temp_id = f"res_{sym}"
            if portfolio.reserve_allocation(temp_id, notional):
                try:
                    logger.info("Executing PRIORITY BUY for %s at $%.2f", sym, price)
                    order = broker.submit_bracket_order(
                        symbol=sym,
                        side="buy",
                        qty=qty,
                        take_profit=pt.take_profit,
                        stop_loss=pt.stop_loss
                    )
                    portfolio.commit_allocation(temp_id, order.get("id", ""))
                    alert(f"?? PRIORITY BUY: {sym} @  (Score: {buy['score']:.2f})")
                except Exception as e:
                    logger.error("Failed to execute %s: %s", sym, e)
                    portfolio.release_allocation(temp_id)

    # Export signals to web API'''

text = text.replace('    # Export signals to web API', exec_footer)

with open('main.py', 'w', encoding='utf-8') as f:
    f.write(text)