#!/usr/bin/env python3
"""
Improved Bot - Stop loss + trailing stops + tighter entries
"""
import os, json, time
from datetime import datetime, timezone

os.environ['KALSHI_API_KEY_ID'] = '81fe00fc-27b2-48ca-85f8-9c37ec1dc82f'
os.environ['KALSHI_PRIVATE_KEY_PATH'] = '/home/wkmabra/.openclaw/workspace/kalshi_private_key'

from pykalshi import KalshiClient, MarketStatus

SERIES = 'KXETH15M'
STATE_FILE = 'eth_state.json'
HIST_FILE = 'eth_history.json'

SIZE = 0.015  # 1.5%
MIN_PROFIT = 0.01  # 1%
STOP_LOSS = 0.12  # 12% stop loss
TAKE_PROFIT = 0.90  # 90c take profit
MOMENTUM_THRESHOLD = 0.05  # 5% momentum required
ENTRY_FLOOR = 0.72  # minimum entry price
ABS_STOP = 0.06  # absolute stop in dollars
TRAIL_TRIGGER = 0.04  # move stop to breakeven after +4c
TRAIL_GAP = 0.02  # trail 2c behind
DAILY_LOSS_LIMIT = -20.0  # stop entering for the day if hit
SKIP_CLOSE_MINUTES = {30, 45}

prices = {}

def main():
    try:
        with open(HIST_FILE) as f:
            history = json.load(f)
    except:
        history = []
    
    pnl = sum(t.get('pnl', 0) for t in history)
    balance = 1500 + pnl
    
    position = None
    last_ticker = None
    
    print(f"Starting - Balance: ${balance}")
    
    client = KalshiClient()
    
    while True:
        try:
            # daily loss guard
            today = datetime.now(timezone.utc).date().isoformat()
            daily_pnl = sum(t.get('pnl', 0) for t in history if t.get('time', '')[:10] == today)
            daily_limit_hit = daily_pnl <= DAILY_LOSS_LIMIT
            markets = client.get_markets(series_ticker=SERIES, status=MarketStatus.OPEN, limit=3)
            if not markets:
                time.sleep(5)
                continue
            
            m = markets[0]
            mid = m.yes_ask / 100 if m.yes_ask else 0
            now = datetime.now(timezone.utc)
            close = datetime.fromisoformat(m.close_time.replace('Z', '+00:00'))
            close_min = close.minute
            left = int((close - now).total_seconds())
            
            # Track price
            if m.ticker not in prices:
                prices[m.ticker] = []
            prices[m.ticker].append({'time': now, 'price': mid})
            if len(prices[m.ticker]) > 5:
                prices[m.ticker] = prices[m.ticker][-5:]
            
            # Calculate momentum
            momentum = 0
            if len(prices[m.ticker]) >= 2:
                first = prices[m.ticker][0]['price']
                if first > 0:
                    momentum = (mid - first) / first
            
            # New market - reset
            if last_ticker and m.ticker != last_ticker:
                last_ticker = None
            
            # Exit logic
            if position and position['ticker'] == m.ticker:
                pct = (mid - position['entry']) / position['entry']

                # Trailing stop setup/update
                if mid >= position['entry'] + TRAIL_TRIGGER:
                    trail = position.get('trail')
                    new_trail = mid - TRAIL_GAP
                    if trail is None or new_trail > trail:
                        position['trail'] = new_trail

                # Trailing stop hit
                if position.get('trail') and mid <= position['trail']:
                    pnl = (mid - position['entry']) * position['contracts']
                    balance += position['cost'] + pnl
                    position['exit'] = mid
                    position['pnl'] = pnl
                    history.append(position)
                    with open(HIST_FILE, 'w') as f:
                        json.dump(history, f, default=str)
                    print(f"TRAIL STOP: ${pnl:.0f} | Balance: ${balance:.0f}")
                    position = None
                    last_ticker = m.ticker

                # Hard stop: absolute drop
                elif mid <= position['entry'] - ABS_STOP:
                    pnl = (mid - position['entry']) * position['contracts']
                    balance += position['cost'] + pnl
                    position['exit'] = mid
                    position['pnl'] = pnl
                    history.append(position)
                    with open(HIST_FILE, 'w') as f:
                        json.dump(history, f, default=str)
                    print(f"HARD STOP: ${pnl:.0f} | Balance: ${balance:.0f}")
                    position = None
                    last_ticker = m.ticker

                # Stop loss: -20%
                elif pct <= -STOP_LOSS:
                    pnl = (mid - position['entry']) * position['contracts']
                    balance += position['cost'] + pnl
                    position['exit'] = mid
                    position['pnl'] = pnl
                    history.append(position)
                    with open(HIST_FILE, 'w') as f:
                        json.dump(history, f, default=str)
                    print(f"STOP LOSS: ${pnl:.0f} | Balance: ${balance:.0f}")
                    position = None
                    last_ticker = m.ticker
                
                # Take profit: 80c+
                elif mid >= TAKE_PROFIT:
                    pnl = (mid - position['entry']) * position['contracts']
                    balance += position['cost'] + pnl
                    position['exit'] = mid
                    position['pnl'] = pnl
                    history.append(position)
                    with open(HIST_FILE, 'w') as f:
                        json.dump(history, f, default=str)
                    print(f"TAKE PROFIT: ${pnl:.0f} | Balance: ${balance:.0f}")
                    position = None
                    last_ticker = m.ticker
                
                # Time-based exit: 2min left if profit
                elif left <= 120 and pct > MIN_PROFIT:
                    pnl = (mid - position['entry']) * position['contracts']
                    balance += position['cost'] + pnl
                    position['exit'] = mid
                    position['pnl'] = pnl
                    history.append(position)
                    with open(HIST_FILE, 'w') as f:
                        json.dump(history, f, default=str)
                    print(f"EXIT TIME: {'WIN' if pnl > 0 else 'LOSS'} ${pnl:.0f} | Balance: ${balance:.0f}")
                    position = None
                    last_ticker = m.ticker
            
            # Entry: stricter rules
            if (not position and m.ticker != last_ticker and 
                180 < left <= 480 and  # 3-8 min before close
                mid >= ENTRY_FLOOR and  # entry floor
                close_min not in SKIP_CLOSE_MINUTES and
                momentum > MOMENTUM_THRESHOLD and  # 5%+ momentum
                not daily_limit_hit):  # daily loss guard
                
                contracts = int(balance * SIZE / mid)
                if contracts >= 1:
                    cost = contracts * mid
                    balance -= cost
                    position = {
                        'ticker': m.ticker,
                        'entry': mid,
                        'contracts': contracts,
                        'cost': cost,
                        'time': datetime.now().isoformat()
                    }
                    last_ticker = m.ticker
                    print(f"ENTER {m.ticker} @ {mid*100:.0f}c ${cost:.0f} | {left}s | Momentum: {momentum*100:.0f}%")
            
            with open(STATE_FILE, 'w') as f:
                json.dump({'balance': balance, 'trades': [position] if position else []}, f, default=str)
            
            time.sleep(2)
        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)

if __name__ == '__main__':
    main()
