Refactor and translate comments and docstrings in utility modules to English for better clarity and maintainability. Update Gunicorn and application startup messages for consistency in language. Enhance documentation with English translations for better accessibility.

This commit is contained in:
dienakdz
2026-04-06 16:47:36 +07:00
parent 3ca291a346
commit 11e2e5aaa6
64 changed files with 2323 additions and 2336 deletions
@@ -1,17 +1,17 @@
"""
Indicator Parameters Parser and Helper Functions
支持两个核心功能:
1. 指标参数外部传递 - 解析指标代码中的 @param 声明
2. 指标调用其他指标 - 提供 call_indicator() 函数
Supports two core functions:
1. External transfer of indicator parameters - parse the @param statement in the indicator code
2. Indicators call other indicators - provide call_indicator() function
参数声明格式:
# @param param_name type default_value 描述
# @param ma_fast int 5 短期均线周期
# @param ma_slow int 20 长期均线周期
# @param threshold float 0.5 阈值
Parameter declaration format:
# @param param_name type default_value description
# @param ma_fast int 5 short-term moving average period
# @param ma_slow int 20 long-term moving average period
# @param threshold float 0.5 threshold
支持的类型:int, float, bool, str
Supported types: int, float, bool, str
"""
import re
@@ -24,9 +24,9 @@ logger = get_logger(__name__)
class IndicatorParamsParser:
"""解析指标代码中的参数声明"""
"""Parsing parameter declarations in indicator code"""
# 参数声明正则:# @param name type default description
# Parameter declaration rules: # @param name type default description
PARAM_PATTERN = re.compile(
r'#\s*@param\s+(\w+)\s+(int|float|bool|str|string)\s+(\S+)\s*(.*)',
re.IGNORECASE
@@ -35,7 +35,7 @@ class IndicatorParamsParser:
@classmethod
def parse_params(cls, indicator_code: str) -> List[Dict[str, Any]]:
"""
解析指标代码中的参数声明
Parsing parameter declarations in indicator code
Returns:
List of param definitions:
@@ -44,7 +44,7 @@ class IndicatorParamsParser:
"name": "ma_fast",
"type": "int",
"default": 5,
"description": "短期均线周期"
"description": "Short-term moving average cycle"
},
...
]
@@ -62,10 +62,10 @@ class IndicatorParamsParser:
default_str = match.group(3)
description = match.group(4).strip() if match.group(4) else ''
# 转换默认值类型
# Convert default value type
default = cls._convert_value(default_str, param_type)
# 规范化类型名
# Canonical type name
if param_type == 'string':
param_type = 'str'
@@ -80,7 +80,7 @@ class IndicatorParamsParser:
@classmethod
def _convert_value(cls, value_str: str, param_type: str) -> Any:
"""转换字符串值为对应类型"""
"""Convert string value to corresponding type"""
try:
param_type = param_type.lower()
if param_type == 'int':
@@ -97,14 +97,14 @@ class IndicatorParamsParser:
@classmethod
def merge_params(cls, declared_params: List[Dict], user_params: Dict[str, Any]) -> Dict[str, Any]:
"""
合并声明的参数和用户提供的参数
Merge declared parameters with user-supplied parameters
Args:
declared_params: 从代码中解析的参数声明
user_params: 用户提供的参数值
declared_params: parameter declarations parsed from code
user_params: user-provided parameter values
Returns:
合并后的参数字典(使用用户值或默认值)
Merged parameter dictionary (using user values or default values)
"""
result = {}
for param in declared_params:
@@ -113,10 +113,10 @@ class IndicatorParamsParser:
default = param['default']
if name in user_params:
# 用户提供了值,转换为正确类型
# User supplied value, converted to correct type
result[name] = cls._convert_value(str(user_params[name]), param_type)
else:
# 使用默认值
# Use default value
result[name] = default
return result
@@ -124,58 +124,58 @@ class IndicatorParamsParser:
class IndicatorCaller:
"""
指标调用器 - 允许一个指标调用另一个指标
Indicator caller - allows one indicator to call another indicator
使用方式(在指标代码中):
# 按ID调用
Usage (in indicator code):
# Call by ID
rsi_df = call_indicator(5, df)
# 按名称调用(自己的指标)
# Call by name (own indicator)
macd_df = call_indicator('My MACD', df)
"""
# 最大调用深度,防止循环依赖
# Maximum call depth to prevent circular dependencies
MAX_CALL_DEPTH = 5
def __init__(self, user_id: int, current_indicator_id: int = None):
self.user_id = user_id
self.current_indicator_id = current_indicator_id
self._call_stack = [] # 调用栈,用于检测循环依赖
self._call_stack = [] # Call stack for detecting circular dependencies
def call_indicator(
self,
indicator_ref: Any, # int (ID) str (名称)
indicator_ref: Any, # int (ID) or str (name)
df: 'pd.DataFrame',
params: Dict[str, Any] = None,
_depth: int = 0
) -> Optional['pd.DataFrame']:
"""
调用另一个指标并返回结果
Call another indicator and return the result
Args:
indicator_ref: 指标ID或名称
df: 输入的K线数据
params: 传递给被调用指标的参数
_depth: 内部使用,跟踪调用深度
indicator_ref: indicator ID or name
df: input K-line data
params: parameters passed to the called indicator
_depth: used internally to track call depth
Returns:
执行后的DataFrame,包含被调用指标计算的列
DataFrame after execution, containing columns calculated by the called indicator
"""
import pandas as pd
import numpy as np
# 检查调用深度
# Check call depth
if _depth >= self.MAX_CALL_DEPTH:
logger.error(f"Indicator call depth exceeded {self.MAX_CALL_DEPTH}")
return df.copy()
# 获取指标代码
# Get indicator code
indicator_code, indicator_id = self._get_indicator_code(indicator_ref)
if not indicator_code:
logger.warning(f"Indicator not found: {indicator_ref}")
return df.copy()
# 检查循环依赖
# Check for circular dependencies
if indicator_id in self._call_stack:
logger.error(f"Circular dependency detected: {self._call_stack} -> {indicator_id}")
return df.copy()
@@ -183,11 +183,11 @@ class IndicatorCaller:
self._call_stack.append(indicator_id)
try:
# 解析并合并参数
# Parse and merge parameters
declared_params = IndicatorParamsParser.parse_params(indicator_code)
merged_params = IndicatorParamsParser.merge_params(declared_params, params or {})
# 准备执行环境
# Prepare execution environment
df_copy = df.copy()
local_vars = {
'df': df_copy,
@@ -200,11 +200,11 @@ class IndicatorCaller:
'np': np,
'pd': pd,
'params': merged_params,
# 递归调用支持
# Recursive call support
'call_indicator': lambda ref, d, p=None: self.call_indicator(ref, d, p, _depth + 1)
}
# 安全执行
# Safe execution
import builtins
def safe_import(name, *args, **kwargs):
allowed_modules = ['numpy', 'pandas', 'math', 'json', 'time']
@@ -236,19 +236,19 @@ class IndicatorCaller:
self._call_stack.pop()
def _get_indicator_code(self, indicator_ref: Any) -> Tuple[Optional[str], Optional[int]]:
"""获取指标代码"""
"""Get indicator code"""
try:
with get_db_connection() as db:
cursor = db.cursor()
if isinstance(indicator_ref, int):
# 按ID查询
# Query by ID
cursor.execute("""
SELECT id, code FROM qd_indicator_codes
WHERE id = %s AND (user_id = %s OR publish_to_community = 1)
""", (indicator_ref, self.user_id))
else:
# 按名称查询(优先自己的指标)
# Query by name (priority to own indicators)
cursor.execute("""
SELECT id, code FROM qd_indicator_codes
WHERE name = %s AND user_id = %s