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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user