import time import threading import json import os from datetime import datetime from market import ( market_info_loop, get_latest_price, get_all_latest_prices, get_latest_price_with_timestamp, get_binance_price_for_market, get_price_comparison, get_market_arbitrage_opportunities ) from order import create_market_order, create_trigger_order, update_trigger_order, cancel_trigger_order, list_trigger_orders from position import list_open_positions from flextrade.constants.markets import BASE_MARKET_ETH_USD, BASE_MARKET_SOL_USD, BASE_MARKET_BTC_USD from flextrade.enum import Action # Validate Action enum is properly imported print(f"โœ… Action enum imported: BUY={Action.BUY} (boolean), SELL={Action.SELL} (boolean)") # Configuration ENABLE_AUTO_HEDGE = True # Set to True to enable automatic hedging ENABLE_TRIGGER_ORDERS = True # Set to True to enable trigger order functionality ORDER_TRACKING_FILE = "opened_trigger_orders.json" # File to store all opened trigger orders # Single coin configuration MONITORED_COIN = "SOL" # Change this to monitor different coins: SOL, ETH, BTC, etc. MONITORED_MARKET_NAME = "SOLUSD" # Market name for price lookup MONITORED_MARKET_CONSTANT = BASE_MARKET_SOL_USD # Market constant for orders SUB_ACCOUNT_ID = 1 # Example sub-account ID for testing HEDGE_PRICE_THRESHOLD = 167.75 # Price threshold for auto-hedging HEDGE_SIZE = 500.0 # Size of the hedge order HEDGE_PRICE_SL = 1.0 # Stop-loss threshold for hedging # Global storage for active orders active_orders = { "trigger_orders": [], # List of {order_id, market, account_id, action, size, trigger_price} "market_orders": [] # List of market order transactions } # Track executed hedges to prevent duplicates executed_hedges = { "hedge_executed": False, "last_hedge_price": 0, "initial_position_check_done": False } def save_last_trigger_order_id(order_id, account_id, market, action, size, trigger_price): """ Save a new trigger order to the opened orders JSON file Args: order_id (int): Order ID account_id (int): Account ID market (str): Market constant action (Action): Buy/Sell action size (float): Order size trigger_price (float): Trigger price """ try: # Load existing orders existing_orders = load_opened_trigger_orders_data() if existing_orders is None: existing_orders = {"opened_orders": []} # Create new order data new_order = { "order_id": order_id, "account_id": account_id, "market": str(market), "action": safe_action_to_string(action), "size": size, "trigger_price": trigger_price, "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "coin": MONITORED_COIN } # Check if order already exists (prevent duplicates) existing_order_ids = [order.get("order_id") for order in existing_orders.get("opened_orders", [])] if order_id not in existing_order_ids: existing_orders["opened_orders"].append(new_order) # Save updated orders list with open(ORDER_TRACKING_FILE, 'w') as f: json.dump(existing_orders, f, indent=2) print(f"๐Ÿ’พ Added trigger order ID {order_id} to {ORDER_TRACKING_FILE}") print(f" Total opened orders: {len(existing_orders['opened_orders'])}") else: print(f"โ„น๏ธ Order ID {order_id} already exists in {ORDER_TRACKING_FILE}") except Exception as e: print(f"โŒ Error saving trigger order ID: {e}") def load_opened_trigger_orders_data(): """ Load all opened trigger orders from JSON file Returns: dict: Orders data or None if file doesn't exist or error """ try: if not os.path.exists(ORDER_TRACKING_FILE): print(f"โ„น๏ธ No existing order tracking file found: {ORDER_TRACKING_FILE}") return None with open(ORDER_TRACKING_FILE, 'r') as f: orders_data = json.load(f) return orders_data except Exception as e: print(f"โŒ Error loading trigger orders: {e}") return None def load_last_trigger_order_id(): """ Load and display all opened trigger orders from JSON file Returns: dict: Orders data or None if file doesn't exist or error """ try: orders_data = load_opened_trigger_orders_data() if not orders_data: return None opened_orders = orders_data.get("opened_orders", []) print(f"๐Ÿ“‚ Loaded opened trigger orders from {ORDER_TRACKING_FILE}:") print(f" Total active orders: {len(opened_orders)}") if opened_orders: print(" Order details:") for i, order in enumerate(opened_orders, 1): print(f" {i}. โœ… Order ID: {order.get('order_id', 'N/A')}") print(f" Account: {order.get('account_id', 'N/A')} | Market: {order.get('market', 'N/A')}") print(f" Action: {order.get('action', 'N/A')} | Size: {order.get('size', 'N/A')}") print(f" Trigger Price: ${order.get('trigger_price', 0):.2f}") print(f" Created: {order.get('created_at', 'N/A')} | Coin: {order.get('coin', 'N/A')}") if i < len(opened_orders): # Don't add extra line after last order print() return orders_data except Exception as e: print(f"โŒ Error loading trigger orders: {e}") return None def clear_last_trigger_order_file(): """ Clear the opened trigger orders tracking file """ try: if os.path.exists(ORDER_TRACKING_FILE): os.remove(ORDER_TRACKING_FILE) print(f"๐Ÿ—‘๏ธ Cleared order tracking file: {ORDER_TRACKING_FILE}") else: print(f"โ„น๏ธ Order tracking file doesn't exist: {ORDER_TRACKING_FILE}") except Exception as e: print(f"โŒ Error clearing order tracking file: {e}") def mark_order_as_cancelled(order_id): """ Remove a cancelled order from the tracking file Args: order_id (int): Order ID to remove """ try: orders_data = load_opened_trigger_orders_data() if not orders_data: print(f"โ„น๏ธ No orders data found to update") return False opened_orders = orders_data.get("opened_orders", []) original_count = len(opened_orders) # Remove the order with the matching order_id updated_orders = [order for order in opened_orders if order.get("order_id") != order_id] if len(updated_orders) < original_count: # Order was found and removed orders_data["opened_orders"] = updated_orders # Save updated orders list with open(ORDER_TRACKING_FILE, 'w') as f: json.dump(orders_data, f, indent=2) print(f"โœ… Removed cancelled order ID {order_id} from {ORDER_TRACKING_FILE}") print(f" Remaining orders: {len(updated_orders)}") return True else: print(f"โš ๏ธ Order ID {order_id} not found in tracking file") return False except Exception as e: print(f"โŒ Error removing cancelled order: {e}") return False def get_active_orders_from_file(): """ Get list of active orders from the tracking file Returns: list: List of active orders """ try: orders_data = load_opened_trigger_orders_data() if not orders_data: return [] # All orders in the file are active since cancelled ones are removed opened_orders = orders_data.get("opened_orders", []) return opened_orders except Exception as e: print(f"โŒ Error getting active orders: {e}") return [] def check_existing_positions_for_hedges(): """ Check existing open positions and mark appropriate hedges as executed to prevent duplicate hedge orders for the monitored coin. Also closes all existing trigger orders and creates new stop-loss orders for hedged positions. """ try: print(f"๐Ÿ” Checking existing positions for {MONITORED_COIN} hedge requirements...") # First, close all existing trigger orders (if method is available) print("๐Ÿงน Attempting to close existing trigger orders...") # Load active trigger orders from file active_orders_in_file = get_active_orders_from_file() if active_orders_in_file: print(f"๐Ÿ—‘๏ธ Found {len(active_orders_in_file)} active trigger orders to cancel...") else: print("โ„น๏ธ No active trigger orders found in file.") for account_id in [SUB_ACCOUNT_ID]: # Cancel each active trigger order found in the file for order in active_orders_in_file: order_id = order.get("order_id") print(f"๐Ÿ—‘๏ธ Attempting to cancel trigger order ID: {order_id}") try: cancel_result = handle_cancel_trigger_order(account_id, MONITORED_MARKET_CONSTANT, order_id) if cancel_result: print(f"โœ… Successfully cancelled order {order_id}") # Remove from file after successful cancellation mark_order_as_cancelled(order_id) else: print(f"โŒ Failed to cancel order {order_id}") except Exception as e: print(f"โš ๏ธ Error cancelling trigger order {order_id}: {e}") time.sleep(8) # Delay between cancellations print("โณ Brief wait before position check...") time.sleep(3) # Now check positions for hedge requirements hedge_positions_found = [] for account_id in [SUB_ACCOUNT_ID]: positions = list_open_positions(account_id, delay=2) if positions: print(f"๐Ÿ“Š Found {len(positions)} open position(s) in account {account_id}") for position in positions: market = position.get("market", "") size = position.get("position_size", 0) entry_price = position.get("avg_entry_price", 0) orderIndex = position.get("orderIndex", 0) direction = "LONG" if size > 0 else "SHORT" print(f" - {market} ({direction}): Size={size:.4f}, Entry=${entry_price:.2f}, orderIndex={orderIndex}") # Check hedge requirements for monitored coin if MONITORED_MARKET_NAME in market and size > 0 and entry_price > HEDGE_PRICE_THRESHOLD: print(f"โœ… {MONITORED_COIN} hedge requirement met: Position size {size:.4f} at ${entry_price:.2f} (above ${HEDGE_PRICE_THRESHOLD})") executed_hedges["hedge_executed"] = True executed_hedges["last_hedge_price"] = entry_price # Store hedge position info for stop-loss creation hedge_positions_found.append({ 'account_id': account_id, 'size': size, 'entry_price': entry_price }) # Add delay between account checks to avoid rate limiting time.sleep(3) # Create stop-loss trigger orders for hedged positions if hedge_positions_found: print(f"\n๐Ÿ›ก๏ธ Creating stop-loss orders for {len(hedge_positions_found)} hedged position(s)...") for hedge_pos in hedge_positions_found: account_id = hedge_pos['account_id'] size = hedge_pos['size'] entry_price = hedge_pos['entry_price'] # Calculate stop-loss price: entry_price - HEDGE_PRICE_SL stop_loss_price = entry_price - HEDGE_PRICE_SL print(f"๐Ÿ“‰ Creating stop-loss order for position:") print(f" Account: {account_id}, Size: {size:.4f}") print(f" Entry Price: ${entry_price:.2f}") print(f" Stop-Loss Price: ${stop_loss_price:.2f} (Entry - ${HEDGE_PRICE_SL})") print(f" orderIndex: {hedge_pos.get('orderIndex', 'N/A')}") # Retry logic for creating stop-loss trigger order max_retries = 3 retry_delay = 5 trigger_result = None for attempt in range(max_retries): try: print(f"๐Ÿ”„ Attempt {attempt + 1}/{max_retries} to create stop-loss order...") # Create stop-loss trigger order (SELL when price goes below stop-loss price) trigger_result = handle_trigger_order( account_id=account_id, market=MONITORED_MARKET_CONSTANT, action=Action.SELL, size=size, trigger_price=stop_loss_price, trigger_above=False # Trigger when price goes BELOW stop-loss price ) if trigger_result: print(f"โœ… Stop-loss trigger order created successfully!") break else: print(f"โŒ Failed to create stop-loss trigger order (attempt {attempt + 1})") except Exception as e: print(f"โŒ Exception during stop-loss creation (attempt {attempt + 1}): {e}") # Wait before retry if not the last attempt if attempt < max_retries - 1: wait_time = retry_delay * (attempt + 1) print(f"โณ Waiting {wait_time} seconds before retry...") time.sleep(wait_time) if not trigger_result: print(f"โŒ Failed to create stop-loss trigger order after {max_retries} attempts") # Add longer delay between different positions time.sleep(5) executed_hedges["initial_position_check_done"] = True print("โœ… Initial position check completed") # Show current hedge status print(f"\n๐Ÿ“‹ {MONITORED_COIN} Hedge Status Summary:") print(f" {MONITORED_COIN} Hedge: {'โœ… Executed' if executed_hedges['hedge_executed'] else 'โŒ Not executed'}") if executed_hedges["hedge_executed"]: print(f" Last Hedge Price: ${executed_hedges['last_hedge_price']:.2f}") print(f" Stop-Loss Orders: {'โœ… Created' if hedge_positions_found else 'โŒ None needed'}") print() except Exception as e: print(f"โŒ Error checking existing positions: {e}") executed_hedges["initial_position_check_done"] = True # Mark as done even on error to prevent infinite retries def start_market_data_thread(debug=True, include_binance=True): """Start market data collection in a separate thread""" market_thread = threading.Thread(target=lambda: market_info_loop(debug, include_binance), daemon=True) market_thread.start() return market_thread def store_trigger_order(result, market, account_id, action, size, trigger_price): """Store trigger order information for later management""" if result and 'order' in result and 'orderIndex' in result['order']: order_id = result['order']['orderIndex'] order_info = { 'order_id': order_id, 'market': market, 'account_id': account_id, 'action': action, 'size': size, 'trigger_price': trigger_price, 'tx_hash': result['tx'].hex(), 'created_at': datetime.now().strftime("%Y-%m-%d %H:%M:%S") } active_orders["trigger_orders"].append(order_info) print(f"๐Ÿ“ Stored trigger order info: ID {order_id}") # Save to file for persistence save_last_trigger_order_id(order_id, account_id, market, action, size, trigger_price) return order_info return None def get_active_trigger_orders(): """Get list of all active trigger orders""" return active_orders["trigger_orders"].copy() def remove_trigger_order(order_id): """Remove a trigger order from active list and remove from file""" active_orders["trigger_orders"] = [ order for order in active_orders["trigger_orders"] if order['order_id'] != order_id ] print(f"๐Ÿ“ Removed trigger order ID {order_id} from active list") # Also remove from the persistent file mark_order_as_cancelled(order_id) def safe_action_to_string(action): """Convert action to string safely, handling both enum and boolean cases""" if hasattr(action, 'name'): return action.name elif action is True or action == 1: return "BUY" elif action is False or action == 0: return "SELL" else: return str(action) def handle_market_order(account_id, market, action, size): """ Handle market order creation with error handling Args: account_id (int): Account ID to trade with market (str): Market constant (e.g., BASE_MARKET_ETH_USD) action (Action): Action.BUY or Action.SELL size (float): Order size """ try: print(f"\n--- Creating Market Order ---") # Convert action to string safely action_name = safe_action_to_string(action) print(f"Account: {account_id}, Market: {market}, Action: {action_name}, Size: {size}") result = create_market_order(account_id, market, action, size) if result: print(f"โœ… Market order successful!") print(f"Transaction: {result['tx'].hex()}") else: print("โŒ Market order failed!") print("--- Order Complete ---\n") return result except Exception as e: print(f"โŒ Error handling market order: {e}") return None def handle_trigger_order(account_id, market, action, size, trigger_price, trigger_above=True): """ Handle trigger order creation with error handling Args: account_id (int): Account ID to trade with market (str): Market constant (e.g., BASE_MARKET_ETH_USD) action (Action): Action.BUY or Action.SELL size (float): Order size trigger_price (float): Price at which the order should trigger trigger_above (bool): True to trigger when price goes above, False for below """ try: print(f"\n--- Creating Trigger Order ---") # Convert action to string safely action_name = safe_action_to_string(action) trigger_direction = "above" if trigger_above else "below" print(f"Account: {account_id}, Market: {market}, Action: {action_name}, Size: {size}") print(f"Trigger: {trigger_direction} ${trigger_price:.2f}") result = create_trigger_order(account_id, market, action, size, trigger_price, trigger_above) if result: print(f"โœ… Trigger order successful!") print(f"Transaction: {result['tx'].hex()}") print(f"Order ID: {result['order']['orderIndex']}") # Store the order for later management store_trigger_order(result, market, account_id, action, size, trigger_price) else: print("โŒ Trigger order failed!") print("--- Order Complete ---\n") return result except Exception as e: print(f"โŒ Error handling trigger order: {e}") return None def handle_update_trigger_order(account_id, order_id, action, size, trigger_price, trigger_above=True): """ Handle trigger order update with error handling Args: account_id (int): Account ID order_id (int): Order ID to update action (Action): Action.BUY or Action.SELL size (float): New order size trigger_price (float): New trigger price trigger_above (bool): True to trigger when price goes above, False for below """ try: print(f"\n--- Updating Trigger Order ---") trigger_direction = "above" if trigger_above else "below" action_name = safe_action_to_string(action) print(f"Order ID: {order_id}, Action: {action_name}, Size: {size}") print(f"New trigger: {trigger_direction} ${trigger_price:.2f}") result = update_trigger_order(account_id, order_id, action, size, trigger_price, trigger_above) if result: print(f"โœ… Trigger order updated successfully!") print(f"Transaction: {result['tx'].hex()}") else: print("โŒ Trigger order update failed!") print("--- Update Complete ---\n") return result except Exception as e: print(f"โŒ Error updating trigger order: {e}") return None def handle_cancel_trigger_order(account_id, market, order_id): """ Handle trigger order cancellation with error handling Args: account_id (int): Account ID market (str): Market constant order_id (int): Order ID to cancel """ try: print(f"\n--- Cancelling Trigger Order ---") print(f"Order ID: {order_id}, Market: {market}") result = cancel_trigger_order(account_id, market, order_id) if result: print(f"โœ… Trigger order cancelled successfully!") print(f"Transaction: {result['tx'].hex()}") # Remove from active orders list remove_trigger_order(order_id) else: print("โŒ Trigger order cancellation failed!") print("--- Cancellation Complete ---\n") return result except Exception as e: print(f"โŒ Error cancelling trigger order: {e}") return None def smart_market_order(market_name, market_constant, action, size, price_threshold=None): """ Create a market order with optional price threshold checking Args: market_name (str): Market name for price lookup (e.g., "ETHUSD") market_constant (str): Market constant for order (e.g., BASE_MARKET_ETH_USD) action (Action): Action.BUY or Action.SELL size (float): Order size price_threshold (float): Optional price threshold for conditional orders Returns: dict: Order result or None if conditions not met """ current_price_data = get_latest_price_with_timestamp(market_name) if not current_price_data: print(f"โŒ No price data available for {market_name}") return None current_price = current_price_data['price'] print(f"๐Ÿ“Š Current {market_name} price: ${current_price:.2f}") # Check price threshold if provided if price_threshold: if action == Action.BUY and current_price > price_threshold: print(f"โธ๏ธ Price ${current_price:.2f} above buy threshold ${price_threshold:.2f} - order not placed") return None elif action == Action.SELL and current_price < price_threshold: print(f"โธ๏ธ Price ${current_price:.2f} below sell threshold ${price_threshold:.2f} - order not placed") return None print(f"โœ… Price conditions met, placing order...") return handle_market_order(SUB_ACCOUNT_ID, market_constant, action, size) def smart_trigger_order(market_name, market_constant, action, size, trigger_price, trigger_above=True, offset_percentage=None): """ Create a trigger order with smart pricing based on current market conditions Args: market_name (str): Market name for price lookup (e.g., "ETHUSD") market_constant (str): Market constant for order (e.g., BASE_MARKET_ETH_USD) action (Action): Action.BUY or Action.SELL size (float): Order size trigger_price (float): Price at which the order should trigger trigger_above (bool): True to trigger when price goes above, False for below offset_percentage (float): Optional percentage offset from current price for automatic trigger calculation Returns: dict: Order result or None if conditions not met """ current_price_data = get_latest_price_with_timestamp(market_name) if not current_price_data: print(f"โŒ No price data available for {market_name}") return None current_price = current_price_data['price'] print(f"๐Ÿ“Š Current {market_name} price: ${current_price:.2f}") # Calculate trigger price based on offset if provided if offset_percentage: if trigger_above: calculated_trigger = current_price * (1 + offset_percentage / 100) else: calculated_trigger = current_price * (1 - offset_percentage / 100) print(f"๐Ÿงฎ Calculated trigger price: ${calculated_trigger:.2f} ({offset_percentage:+.1f}% from current)") trigger_price = calculated_trigger # Validate trigger price makes sense trigger_direction = "above" if trigger_above else "below" if trigger_above and trigger_price <= current_price: print(f"โš ๏ธ Warning: Trigger price ${trigger_price:.2f} is not above current price ${current_price:.2f}") elif not trigger_above and trigger_price >= current_price: print(f"โš ๏ธ Warning: Trigger price ${trigger_price:.2f} is not below current price ${current_price:.2f}") print(f"โœ… Creating trigger order: {trigger_direction} ${trigger_price:.2f}") return handle_trigger_order(SUB_ACCOUNT_ID, market_constant, action, size, trigger_price, trigger_above) def main(): print(f"Starting app - monitoring {MONITORED_COIN} with market data collection...") print(f"Monitored Coin: {MONITORED_COIN}") print(f"Market: {MONITORED_MARKET_NAME}") print(f"Hedge Price Threshold: ${HEDGE_PRICE_THRESHOLD}") print(f"Auto-hedge enabled: {ENABLE_AUTO_HEDGE}") print("-" * 50) # Load last trigger order information on startup print("๐Ÿ” Checking for existing opened trigger orders...") orders_data = load_last_trigger_order_id() if orders_data: total_count = len(orders_data.get("opened_orders", [])) print(f"โœ… Found {total_count} active trigger orders for {MONITORED_COIN} coin") else: print("โ„น๏ธ No existing opened trigger orders found") print() # Start market data collection in background thread with Binance comparison start_market_data_thread(debug=False, include_binance=True) # Give some time for initial market data to be collected time.sleep(10) try: while True: current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"[{current_time}] update!") # Show some sample prices with timestamps (FlexTrade and Binance) monitored_data = get_latest_price_with_timestamp(MONITORED_MARKET_NAME) # Check if we have received first successful price update and haven't checked positions yet if (not executed_hedges["initial_position_check_done"] and monitored_data): print(f"\n๐ŸŽฏ First successful price update received for {MONITORED_COIN} - checking existing positions...") check_existing_positions_for_hedges() # Get Binance prices for comparison monitored_binance = get_latest_price_with_timestamp(f"{MONITORED_MARKET_NAME}_BINANCE") if monitored_data or monitored_binance: ft_price = f"${monitored_data['price']:.2f}" if monitored_data else "N/A" bn_price = f"${monitored_binance['price']:.2f}" if monitored_binance else "N/A" ft_time = monitored_data['timestamp_str'] if monitored_data else "N/A" bn_time = monitored_binance['timestamp_str'] if monitored_binance else "N/A" print(f"{MONITORED_COIN}/USD: FlexTrade={ft_price} ({ft_time}) | Binance={bn_price} ({bn_time})") # Show price difference if both available if monitored_data and monitored_binance: price_diff = monitored_data['price'] - monitored_binance['price'] diff_pct = (price_diff / monitored_binance['price']) * 100 if monitored_binance['price'] > 0 else 0 diff_emoji = "๐Ÿ“ˆ" if price_diff > 0 else "๐Ÿ“‰" if price_diff < 0 else "โžก๏ธ" print(f"{MONITORED_COIN} Difference: {diff_emoji} {price_diff:+.4f} ({diff_pct:+.2f}%)") # Show total number of markets with prices all_prices = get_all_latest_prices() flextrade_markets = len([k for k in all_prices.keys() if not k.endswith('_BINANCE') and k != '_comparison']) binance_markets = len([k for k in all_prices.keys() if k.endswith('_BINANCE')]) print(f"Total markets tracked: FlexTrade={flextrade_markets}, Binance={binance_markets}") # Show arbitrage opportunities if available try: arbitrage_ops = get_market_arbitrage_opportunities(min_percentage_diff=0.5) if arbitrage_ops: print(f"\n๐ŸŽฏ Found {len(arbitrage_ops)} arbitrage opportunities (>0.5% difference):") for i, op in enumerate(arbitrage_ops[:3]): # Show top 3 action_emoji = "๐Ÿ“ˆ" if "buy_flextrade" in op['action'] else "๐Ÿ“‰" print(f" {i+1}. {action_emoji} {op['market']}: {op['potential_profit_pct']:.2f}% potential profit") print(f" FlexTrade: ${op['flextrade_price']:.4f} | Binance: ${op['binance_price']:.4f}") print(f" Strategy: {op['action'].replace('_', ' ').title()}") else: print("๐ŸŽฏ No significant arbitrage opportunities found (threshold: 0.5%)") # Show smaller differences for informational purposes small_ops = get_market_arbitrage_opportunities(min_percentage_diff=0.1) if small_ops: best_small = small_ops[0] # Show best small opportunity diff_emoji = "๐Ÿ“ˆ" if best_small['difference_pct'] > 0 else "๐Ÿ“‰" print(f" Best small difference: {diff_emoji} {best_small['market']} ({best_small['potential_profit_pct']:.2f}%)") except Exception as e: print(f"โš ๏ธ Error checking arbitrage opportunities: {e}") print() # Extra line for readability # Auto-hedging logic if ENABLE_AUTO_HEDGE: # Hedging logic with duplicate prevention for monitored coin if (monitored_data and monitored_data['price'] > HEDGE_PRICE_THRESHOLD and not executed_hedges["hedge_executed"]): # Only execute once print(f"๐Ÿค– Auto-hedge triggered: {MONITORED_COIN} price above ${HEDGE_PRICE_THRESHOLD}") # Execute market order to buy the monitored coin market_result = smart_market_order(MONITORED_MARKET_NAME, MONITORED_MARKET_CONSTANT, Action.BUY, 100.0) if market_result: print(f"๐Ÿค– Auto-hedge triggered: {MONITORED_COIN} stop-loss trigger") time.sleep(10) # Create stop-loss trigger order trigger_result = smart_trigger_order(MONITORED_MARKET_NAME, MONITORED_MARKET_CONSTANT, Action.SELL, 100.0, 0, trigger_above=False, offset_percentage=5) if trigger_result: # Mark hedge as executed executed_hedges["hedge_executed"] = True executed_hedges["last_hedge_price"] = monitored_data['price'] print(f"โœ… {MONITORED_COIN} hedge completed at price ${monitored_data['price']:.2f}") # Reset hedge flag if price drops significantly below hedge price if (monitored_data and monitored_data['price'] < (HEDGE_PRICE_THRESHOLD * 0.95) and executed_hedges["hedge_executed"]): print(f"๐Ÿ”„ Resetting {MONITORED_COIN} hedge flag - price dropped to ${monitored_data['price']:.2f}") executed_hedges["hedge_executed"] = False # Sleep for 60 seconds (1 minute) time.sleep(60) except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": main()