diff --git a/backend_api_python/app/services/live_trading/records.py b/backend_api_python/app/services/live_trading/records.py index cfc282e..3adb76d 100644 --- a/backend_api_python/app/services/live_trading/records.py +++ b/backend_api_python/app/services/live_trading/records.py @@ -39,7 +39,6 @@ def record_trade( profit: Optional[float] = None, user_id: int = None, ) -> None: - now = int(time.time()) value = float(amount or 0.0) * float(price or 0.0) if user_id is None: user_id = _get_user_id_from_strategy(strategy_id) @@ -50,7 +49,7 @@ def record_trade( INSERT INTO qd_strategy_trades (user_id, strategy_id, symbol, type, price, amount, value, commission, commission_ccy, profit, created_at) VALUES - (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()) """, ( int(user_id), @@ -63,7 +62,6 @@ def record_trade( float(commission or 0.0), str(commission_ccy or ""), profit, - now, ), ) db.commit() @@ -105,7 +103,6 @@ def upsert_position( lowest_price: float = 0.0, user_id: int = None, ) -> None: - now = int(time.time()) if user_id is None: user_id = _get_user_id_from_strategy(strategy_id) with get_db_connection() as db: @@ -115,16 +112,16 @@ def upsert_position( INSERT INTO qd_strategy_positions (user_id, strategy_id, symbol, side, size, entry_price, current_price, highest_price, lowest_price, updated_at) VALUES - (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + (%s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()) ON CONFLICT(strategy_id, symbol, side) DO UPDATE SET size = excluded.size, entry_price = excluded.entry_price, current_price = excluded.current_price, highest_price = CASE WHEN excluded.highest_price > 0 THEN excluded.highest_price ELSE qd_strategy_positions.highest_price END, lowest_price = CASE WHEN excluded.lowest_price > 0 THEN excluded.lowest_price ELSE qd_strategy_positions.lowest_price END, - updated_at = excluded.updated_at + updated_at = NOW() """, - (int(user_id), int(strategy_id), str(symbol), str(side), float(size or 0.0), float(entry_price or 0.0), float(current_price or 0.0), float(highest_price or 0.0), float(lowest_price or 0.0), now), + (int(user_id), int(strategy_id), str(symbol), str(side), float(size or 0.0), float(entry_price or 0.0), float(current_price or 0.0), float(highest_price or 0.0), float(lowest_price or 0.0)), ) db.commit() cur.close() diff --git a/backend_api_python/app/services/pending_order_worker.py b/backend_api_python/app/services/pending_order_worker.py index 9502d6c..5584d19 100644 --- a/backend_api_python/app/services/pending_order_worker.py +++ b/backend_api_python/app/services/pending_order_worker.py @@ -477,7 +477,6 @@ class PendingOrderWorker: def _mark_processing(self, order_id: int) -> bool: try: - now = int(time.time()) with get_db_connection() as db: cur = db.cursor() # Only claim if still pending to avoid double-processing. @@ -486,11 +485,11 @@ class PendingOrderWorker: UPDATE pending_orders SET status = 'processing', attempts = COALESCE(attempts, 0) + 1, - processed_at = %s, - updated_at = %s + processed_at = NOW(), + updated_at = NOW() WHERE id = %s AND status = 'pending' """, - (now, now, int(order_id)), + (int(order_id),), ) claimed = getattr(cur, "rowcount", None) db.commit() @@ -1922,36 +1921,34 @@ class PendingOrderWorker: avg_price: float = 0.0, executed_at: Optional[int] = None, ) -> None: - now = int(time.time()) with get_db_connection() as db: cur = db.cursor() + # Use NOW() for timestamp fields; executed_at is set to NOW() if provided, else NULL cur.execute( """ UPDATE pending_orders SET status = 'sent', last_error = %s, dispatch_note = %s, - sent_at = %s, - executed_at = %s, + sent_at = NOW(), + executed_at = CASE WHEN %s THEN NOW() ELSE NULL END, exchange_id = %s, exchange_order_id = %s, exchange_response_json = %s, filled = %s, avg_price = %s, - updated_at = %s + updated_at = NOW() WHERE id = %s """, ( "", str(note or ""), - now, - int(executed_at) if executed_at is not None else None, + executed_at is not None, # Boolean flag for CASE WHEN str(exchange_id or ""), str(exchange_order_id or ""), str(exchange_response_json or ""), float(filled or 0.0), float(avg_price or 0.0), - now, int(order_id), ), ) @@ -1959,7 +1956,6 @@ class PendingOrderWorker: cur.close() def _mark_failed(self, order_id: int, error: str) -> None: - now = int(time.time()) with get_db_connection() as db: cur = db.cursor() cur.execute( @@ -1967,16 +1963,15 @@ class PendingOrderWorker: UPDATE pending_orders SET status = 'failed', last_error = %s, - updated_at = %s + updated_at = NOW() WHERE id = %s """, - (str(error or "failed"), now, int(order_id)), + (str(error or "failed"), int(order_id)), ) db.commit() cur.close() def _mark_deferred(self, order_id: int, reason: str) -> None: - now = int(time.time()) with get_db_connection() as db: cur = db.cursor() cur.execute( @@ -1984,10 +1979,10 @@ class PendingOrderWorker: UPDATE pending_orders SET status = 'deferred', last_error = %s, - updated_at = %s + updated_at = NOW() WHERE id = %s """, - (str(reason or "deferred"), now, int(order_id)), + (str(reason or "deferred"), int(order_id)), ) db.commit() cur.close() diff --git a/backend_api_python/app/services/portfolio_monitor.py b/backend_api_python/app/services/portfolio_monitor.py index f657995..0b63334 100644 --- a/backend_api_python/app/services/portfolio_monitor.py +++ b/backend_api_python/app/services/portfolio_monitor.py @@ -748,17 +748,16 @@ def _send_monitor_notification( try: ch = str(channel).strip().lower() if ch == 'browser': - now = _now_ts() with get_db_connection() as db: cur = db.cursor() cur.execute( """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, NULL, ?, ?, ?, ?, ?, ?, NOW()) """, - (effective_user_id, 0, 'PORTFOLIO', 'ai_monitor', 'browser', error_title, error_msg, - json.dumps(result, ensure_ascii=False), now) + (effective_user_id, 'PORTFOLIO', 'ai_monitor', 'browser', error_title, error_msg, + json.dumps(result, ensure_ascii=False)) ) db.commit() cur.close() @@ -795,17 +794,16 @@ def _send_monitor_notification( if ch == 'browser': # Browser notification uses HTML report - now = _now_ts() with get_db_connection() as db: cur = db.cursor() cur.execute( """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, NULL, ?, ?, ?, ?, ?, ?, NOW()) """, - (effective_user_id, 0, 'PORTFOLIO', 'ai_monitor', 'browser', title, html_report, - json.dumps(result, ensure_ascii=False), now) + (effective_user_id, 'PORTFOLIO', 'ai_monitor', 'browser', title, html_report, + json.dumps(result, ensure_ascii=False)) ) db.commit() cur.close() @@ -1087,10 +1085,10 @@ def _check_position_alerts(): """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, NULL, ?, ?, ?, ?, ?, ?, NOW()) """, - (alert_user_id, 0, symbol, 'price_alert', 'browser', alert_title, alert_message, - json.dumps({'alert_id': alert_id, 'alert_type': alert_type}, ensure_ascii=False), now) + (alert_user_id, symbol, 'price_alert', 'browser', alert_title, alert_message, + json.dumps({'alert_id': alert_id, 'alert_type': alert_type}, ensure_ascii=False)) ) db.commit() cur.close() @@ -1178,10 +1176,10 @@ def notify_strategy_signal_for_positions(market: str, symbol: str, signal_type: """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, NULL, ?, ?, ?, ?, ?, ?, NOW()) """, - (pos_user_id, 0, symbol, 'strategy_linkage', 'browser', title, message, - json.dumps({'signal_type': signal_type}, ensure_ascii=False), now) + (pos_user_id, symbol, 'strategy_linkage', 'browser', title, message, + json.dumps({'signal_type': signal_type}, ensure_ascii=False)) ) db.commit() cur.close() diff --git a/backend_api_python/app/services/signal_notifier.py b/backend_api_python/app/services/signal_notifier.py index abbdb33..15a3144 100644 --- a/backend_api_python/app/services/signal_notifier.py +++ b/backend_api_python/app/services/signal_notifier.py @@ -468,7 +468,7 @@ class SignalNotifier: """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW()) """, ( int(user_id), @@ -479,7 +479,6 @@ class SignalNotifier: str(title or ""), str(message or ""), json.dumps(payload or {}, ensure_ascii=False), - int(now), ), ) db.commit() diff --git a/backend_api_python/app/services/trading_executor.py b/backend_api_python/app/services/trading_executor.py index c2de858..db9a042 100644 --- a/backend_api_python/app/services/trading_executor.py +++ b/backend_api_python/app/services/trading_executor.py @@ -2213,7 +2213,7 @@ class TradingExecutor: """ INSERT INTO qd_strategy_notifications (user_id, strategy_id, symbol, signal_type, channels, title, message, payload_json, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW()) """, ( int(user_id), @@ -2224,7 +2224,6 @@ class TradingExecutor: str(title or ""), str(message or ""), json.dumps(payload or {}, ensure_ascii=False), - int(now), ), ) db.commit() @@ -2450,7 +2449,7 @@ class TradingExecutor: VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s) + NOW(), NOW(), NULL, NULL) """, ( int(user_id), @@ -2469,10 +2468,6 @@ class TradingExecutor: 10, '', json.dumps(payload, ensure_ascii=False), - now, - now, - None, - None, ), ) pending_id = cur.lastrowid @@ -2510,10 +2505,10 @@ class TradingExecutor: INSERT INTO qd_strategy_trades ( user_id, strategy_id, symbol, type, price, amount, value, commission, profit, created_at ) VALUES ( - %s, %s, %s, %s, %s, %s, %s, %s, %s, %s + %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW() ) """ - cursor.execute(query, (user_id, strategy_id, symbol, type, price, amount, value, commission or 0, profit, int(time.time()))) + cursor.execute(query, (user_id, strategy_id, symbol, type, price, amount, value, commission or 0, profit)) db.commit() cursor.close() except Exception as e: @@ -2547,17 +2542,17 @@ class TradingExecutor: INSERT INTO qd_strategy_positions ( user_id, strategy_id, symbol, side, size, entry_price, current_price, highest_price, lowest_price, updated_at ) VALUES ( - %s, %s, %s, %s, %s, %s, %s, %s, %s, %s + %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW() ) ON CONFLICT(strategy_id, symbol, side) DO UPDATE SET size = excluded.size, entry_price = excluded.entry_price, current_price = excluded.current_price, highest_price = CASE WHEN excluded.highest_price > 0 THEN excluded.highest_price ELSE qd_strategy_positions.highest_price END, lowest_price = CASE WHEN excluded.lowest_price > 0 THEN excluded.lowest_price ELSE qd_strategy_positions.lowest_price END, - updated_at = excluded.updated_at + updated_at = NOW() """ cursor.execute(upsert_query, ( - user_id, strategy_id, symbol, side, size, entry_price, current_price, highest_price, lowest_price, int(time.time()) + user_id, strategy_id, symbol, side, size, entry_price, current_price, highest_price, lowest_price )) db.commit() cursor.close()