@@ -1656,6 +1656,12 @@ def _analyze_opportunities_crypto(opportunities: list):
|
||||
crypto_data = _fetch_crypto_prices()
|
||||
if crypto_data:
|
||||
_set_cached("crypto_prices", crypto_data)
|
||||
|
||||
if not crypto_data:
|
||||
logger.warning("_analyze_opportunities_crypto: No crypto data available")
|
||||
return
|
||||
|
||||
logger.debug(f"_analyze_opportunities_crypto: Analyzing {len(crypto_data)} crypto coins")
|
||||
|
||||
for coin in (crypto_data or [])[:20]:
|
||||
change = _safe_float(coin.get("change_24h", 0))
|
||||
@@ -1669,12 +1675,13 @@ def _analyze_opportunities_crypto(opportunities: list):
|
||||
reason = ""
|
||||
impact = "neutral"
|
||||
|
||||
# Lower thresholds to show more opportunities
|
||||
if change > 15:
|
||||
signal = "overbought"
|
||||
strength = "strong"
|
||||
reason = f"24h涨幅{change:.1f}%,7日涨幅{change_7d:.1f}%,短期超买风险"
|
||||
impact = "bearish"
|
||||
elif change > 8:
|
||||
elif change > 5: # Lowered from 8 to 5
|
||||
signal = "bullish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"24h涨幅{change:.1f}%,上涨动能强劲"
|
||||
@@ -1684,7 +1691,7 @@ def _analyze_opportunities_crypto(opportunities: list):
|
||||
strength = "strong"
|
||||
reason = f"24h跌幅{abs(change):.1f}%,可能超卖反弹"
|
||||
impact = "bullish"
|
||||
elif change < -8:
|
||||
elif change < -5: # Lowered from -8 to -5
|
||||
signal = "bearish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"24h跌幅{abs(change):.1f}%,下跌趋势明显"
|
||||
@@ -1713,6 +1720,12 @@ def _analyze_opportunities_stocks(opportunities: list):
|
||||
stock_data = _fetch_stock_opportunity_prices()
|
||||
if stock_data:
|
||||
_set_cached("stock_opportunity_prices", stock_data, 3600)
|
||||
|
||||
if not stock_data:
|
||||
logger.warning("_analyze_opportunities_stocks: No stock data available")
|
||||
return
|
||||
|
||||
logger.debug(f"_analyze_opportunities_stocks: Analyzing {len(stock_data)} stocks")
|
||||
|
||||
for stock in (stock_data or []):
|
||||
change = _safe_float(stock.get("change", 0))
|
||||
@@ -1731,7 +1744,7 @@ def _analyze_opportunities_stocks(opportunities: list):
|
||||
strength = "strong"
|
||||
reason = f"日涨幅{change:.1f}%,短期涨幅较大,注意回调风险"
|
||||
impact = "bearish"
|
||||
elif change > 3:
|
||||
elif change > 2: # Lowered from 3 to 2
|
||||
signal = "bullish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"日涨幅{change:.1f}%,上涨动能强劲"
|
||||
@@ -1741,7 +1754,7 @@ def _analyze_opportunities_stocks(opportunities: list):
|
||||
strength = "strong"
|
||||
reason = f"日跌幅{abs(change):.1f}%,可能超卖反弹"
|
||||
impact = "bullish"
|
||||
elif change < -3:
|
||||
elif change < -2: # Lowered from -3 to -2
|
||||
signal = "bearish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"日跌幅{abs(change):.1f}%,下跌趋势明显"
|
||||
@@ -1769,6 +1782,12 @@ def _analyze_opportunities_forex(opportunities: list):
|
||||
forex_data = _fetch_forex_pairs()
|
||||
if forex_data:
|
||||
_set_cached("forex_pairs", forex_data, 3600)
|
||||
|
||||
if not forex_data:
|
||||
logger.warning("_analyze_opportunities_forex: No forex data available")
|
||||
return
|
||||
|
||||
logger.debug(f"_analyze_opportunities_forex: Analyzing {len(forex_data)} forex pairs")
|
||||
|
||||
for pair in (forex_data or []):
|
||||
change = _safe_float(pair.get("change", 0))
|
||||
@@ -1787,7 +1806,7 @@ def _analyze_opportunities_forex(opportunities: list):
|
||||
strength = "strong"
|
||||
reason = f"日涨幅{change:.2f}%,汇率波动剧烈,注意回调"
|
||||
impact = "bearish"
|
||||
elif change > 0.8:
|
||||
elif change > 0.5: # Lowered from 0.8 to 0.5
|
||||
signal = "bullish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"日涨幅{change:.2f}%,上涨动能较强"
|
||||
@@ -1797,7 +1816,7 @@ def _analyze_opportunities_forex(opportunities: list):
|
||||
strength = "strong"
|
||||
reason = f"日跌幅{abs(change):.2f}%,汇率波动剧烈,可能反弹"
|
||||
impact = "bullish"
|
||||
elif change < -0.8:
|
||||
elif change < -0.5: # Lowered from -0.8 to -0.5
|
||||
signal = "bearish_momentum"
|
||||
strength = "medium"
|
||||
reason = f"日跌幅{abs(change):.2f}%,下跌趋势明显"
|
||||
@@ -1836,17 +1855,34 @@ def trading_opportunities():
|
||||
opportunities = []
|
||||
|
||||
# 1) Crypto
|
||||
_analyze_opportunities_crypto(opportunities)
|
||||
try:
|
||||
_analyze_opportunities_crypto(opportunities)
|
||||
crypto_count = len([o for o in opportunities if o.get("market") == "Crypto"])
|
||||
logger.info(f"Trading opportunities: found {crypto_count} crypto opportunities")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to analyze crypto opportunities: {e}", exc_info=True)
|
||||
|
||||
# 2) US Stocks
|
||||
_analyze_opportunities_stocks(opportunities)
|
||||
try:
|
||||
_analyze_opportunities_stocks(opportunities)
|
||||
stock_count = len([o for o in opportunities if o.get("market") == "USStock"])
|
||||
logger.info(f"Trading opportunities: found {stock_count} US stock opportunities")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to analyze stock opportunities: {e}", exc_info=True)
|
||||
|
||||
# 3) Forex
|
||||
_analyze_opportunities_forex(opportunities)
|
||||
try:
|
||||
_analyze_opportunities_forex(opportunities)
|
||||
forex_count = len([o for o in opportunities if o.get("market") == "Forex"])
|
||||
logger.info(f"Trading opportunities: found {forex_count} forex opportunities")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to analyze forex opportunities: {e}", exc_info=True)
|
||||
|
||||
# Sort by absolute change descending
|
||||
opportunities.sort(key=lambda x: abs(x.get("change_24h", 0)), reverse=True)
|
||||
|
||||
logger.info(f"Trading opportunities: total {len(opportunities)} opportunities found (Crypto: {len([o for o in opportunities if o.get('market') == 'Crypto'])}, USStock: {len([o for o in opportunities if o.get('market') == 'USStock'])}, Forex: {len([o for o in opportunities if o.get('market') == 'Forex'])})")
|
||||
|
||||
_set_cached("trading_opportunities", opportunities, 3600)
|
||||
|
||||
return jsonify({"code": 1, "msg": "success", "data": opportunities})
|
||||
|
||||
@@ -830,6 +830,18 @@ def close_position():
|
||||
avg_fill = float(getattr(result, "avg_price", 0) or 0)
|
||||
raw = getattr(result, "raw", {}) or {}
|
||||
|
||||
# ---- calculate USDT amount for recording ----
|
||||
# Convert base asset quantity to USDT amount for consistent recording
|
||||
# amount (USDT) = base_qty * price
|
||||
usdt_amount = actual_close_size * avg_fill if avg_fill > 0 else 0
|
||||
# If price is not available, try to use entry price or mark price as fallback
|
||||
if usdt_amount <= 0:
|
||||
entry_price = float(position.get("entry_price") or 0)
|
||||
mark_price = float(position.get("mark_price") or 0)
|
||||
fallback_price = mark_price if mark_price > 0 else entry_price
|
||||
if fallback_price > 0:
|
||||
usdt_amount = actual_close_size * fallback_price
|
||||
|
||||
# ---- record trade ----
|
||||
trade_id = _record_quick_trade(
|
||||
user_id=user_id,
|
||||
@@ -838,7 +850,7 @@ def close_position():
|
||||
symbol=symbol,
|
||||
side="sell" if position_side == "long" else "buy", # Opposite of position side
|
||||
order_type="market",
|
||||
amount=actual_close_size, # Record position size
|
||||
amount=usdt_amount, # Record USDT amount, not base asset quantity
|
||||
price=avg_fill,
|
||||
leverage=float(position.get("leverage") or 1),
|
||||
market_type=market_type,
|
||||
|
||||
Reference in New Issue
Block a user