Coding

小果量化因子库

Try it

小果(微信:xg_quant)量化因子库是一个集成了数百个技术指标、Alpha因子和交易信号的Python量化因子计算系统。 支持股票、ETF、可转债等多品种的历史因子批量计算,提供单只股票因子分析和全市场因子数据生成。 触发关键词:小果因子、量化因子、因子计算、xg_factor、技术指标、Alpha因子、因子选股、因子库。

What it does

小果量化因子库是一个集成了数百个技术指标、Alpha因子和交易信号的Python量化因子计算系统。 支持股票、ETF、可转债等多品种的历史因子批量计算,提供单只股票因子分析和全市场因子数据生成。 触发关键词:小果因子、量化因子、因子计算、xg_factor、技术指标、Alpha因子、因子选股、因子库。

The skill document

小果量化因子库 Skill

1. 概述

小果量化因子库是一套完整的 Python 量化因子计算系统,基于 xg_factor 核心类实现,提供了从传统技术指标到高级 Alpha 因子的全面覆盖。该系统支持单只股票的因子分析和全市场股票的批量因子计算,是量化投研和策略开发的得力工具。

作者:小果(微信:xg_quant)

2. 主要作用

  1. 因子计算引擎:提供 300+ 个量化因子计算函数,涵盖技术指标、交易信号、风险收益指标、WorldQuant Alpha 因子等。
  2. 批量数据处理:支持多进程/多线程并行计算全市场股票的因子数据,大幅提升计算效率。
  3. 策略信号生成:内置多种交易信号函数(如金叉死叉、波段买卖点),可直接用于构建量化策略。
  4. 数据标准化输出:统一的因子计算结果以 Pandas DataFrame 或 Parquet 格式输出,便于后续分析和回测。

3. 核心功能模块

3.1 基础技术指标(超卖超买类)

函数名说明
CCI()商品路径指标
RSI1() / RSI2() / RSI3()相对强弱指标(6/12/24日)
KDJ_K() / KDJ_D() / KDJ_J()KDJ随机指标
WR1() / WR2()威廉指标
MFI()资金流量指标
BIAS1() / BIAS2() / BIAS3()乖离率(6/12/24日)
PSY() / PSYMA()心理线指标
SKDJ_K() / SKDJ_D()慢速随机指标
LWR1() / LWR2()LWR指标
MARSI1() / MARSI2()相对强弱平均线
BIAS_QL_BIAS() / BIAS_QL_BIASMA()传统版乖离率
BIAS36_BIAS36() / BIAS36_BIAS612() / BIAS36_MABIAS()三六乖离
ACCER()幅度涨速
MTM_MTM() / MTM_MTMMA()动量线指标
UDL_UDL() / UDL_MAUDL()引力线

3.2 趋势类指标

函数名说明
MACD_DIF() / MACD_DEA() / MACD_MACD()平滑异同平均线
MACD_金叉() / MACD_死叉()MACD金叉/死叉信号
DMI_PDI() / DMI_MDI() / DMI_ADX() / DMI_ADXR()趋向指标
BOLL_BOLL() / BOLL_UB() / BOLL_LB()布林线(中/上/下轨)
SAR()抛物线转向指标
TRIX_TRIX() / TRIX_MATRIX()三重指数平均线
UOS_UOS() / UOS_MAUOS()终极指标
ASI_ASI() / ASI_ASIT()振动升降指标
CHO_CHO() / CHO_MACHO()佳庆指标
DMA_XT_DIF() / DMA_XT_DIFMA()平均差
DPO_DPO() / DPO_MADPO()区间震荡线
EMV_EMV() / EMV_MAEMV()简易波动指标
VMACD_DIF() / VMACD_DEA() / VMACD_MACD()量平滑异同平均线
SMACD_DEA() / SMACD_MACD()单线平滑异同平均线
QACD_DIF() / QACD_MACD() / QACD_DDIF()快速异同平均线
VTP_VPT() / VTP_MAVP()量价曲线
WVAD_WVAD() / WVAD_MAWVAD()威廉变异离散量
JS_JS() / JS_MAJS1() / JS_MAJS2() / JS_MAJS3()加数线
CYE_CYEL() / CYE_CYES()市场趋势
GDX_轨道() / GDX_压力线() / GDX_支撑线()轨道线
JLHB_B() / JLHB_VAR2() / JLHB_绝路航标()绝路航标

3.3 能量类指标

函数名说明
OBV_OBV() / OBV_MAOBV()累积能量线
VR_VR() / VR_MAVR()成交量变异率
BRAR_BR() / BRAR_AR()情绪指标
CR_CR() / CR_MA1() / CR_MA2() / CR_MA3() / CR_MA4()带状能量线
MASS_MASS() / MASS_MAMASS()梅斯线
WAD_WAD() / WAD_MAWAD()威廉多空力度线
PCNT_PCNT() / PCNT_MAPCNT()幅度比
CYR_CYR() / CYR_MACYR()市场强弱
AMO_AMOW() / AMO_AMO1() / AMO_AMO2()成交金额
VOL_XT_MAVOL1() / VOL_XT_MAVOL2()成交量均线
VRSI1() / VRSI2() / VRSI3()相对强弱量
HSL_HSL() / HSL_MAHSL()换手线

3.4 均线系统

函数名说明
SMA(period)N日简单移动平均线(5/10/20/30/60/120日)
MA_XT_MA1() / MA_XT_MA2() / MA_XT_MA3() / MA_XT_MA4()均线(5/10/20/60日)
EXPMA_EXP1() / EXPMA_EXP2()指数平均线(12/50日)
BBI()多空均线
ACD_ACD() / ACD_MAACD()升降线
HMA_HMA1() ~ HMA_HMA5()高价平均线(6/12/30/70/90日)
LMA_LMA1() ~ LMA_LMA5()低价平均线(6/12/30/70/90日)
VMA_VMA1() ~ VMA_VMA5()变异平均线
AMV_AMV1() / AMV_AMV2() / AMV_AMV3() / AMV_AMV4()成本均线(5/13/34/60日)
BBIBOLL_BBIBOLL() / BBIBOLL_UPR() / BBIBOLL_DWN()多空布林线
ALLIGAT_上唇() / ALLIGAT_牙齿() / ALLIGAT_下颚()鳄鱼线
GMMA_MA3() ~ GMMA_MA60()顾比均线(12条均线)
CROSS_UP(n1,n2)N1上穿N2金叉判断
CROSS_DOWN(n1,n2)N1下穿N2死叉判断
PRICE_MA_LINE_ANAL(n)价格在N均线上方判断
MA_LINE_ANAL(n1,n2)N1均线在N2均线上方判断

3.5 路径类指标

函数名说明
PBX_PBX1() ~ PBX_PBX6()瀑布线(6条)
ENE_UPPER() / ENE_LOWER() / ENE_ENE()轨道线
MIKE_STOR() / MIKE_MIDR() / MIKE_WEKR() / MIKE_WEKS() / MIKE_MIDS() / MIKE_STOS()麦克支撑压力
XS_SUP() / XS_SDN() / XS_LUP() / XS_LDN()薛斯通道
TQN_周期高点() / TQN_周期低点() / TQN_平空开多() / TQN_平多开空()唐奇安通道

3.6 WorldQuant Alpha 因子(101-191)

函数名说明
alpha001() ~ alpha191()完整的 WorldQuant Formula 101 系列因子
涵盖类型动量、反转、波动率、相关性、排名、衰减、成交量、价格等

3.7 交易信号类

函数名说明
six_pulse_excalibur_hist()六脉神剑(多指标综合买卖信号)
small_fruit_band_trading_1()小波段交易买卖点识别
small_fruit_band_trading_2()大波段交易买卖点识别
band_supe_buy_sell()波段超级买卖信号
KDJ_KD金叉() / KDJ_KD死叉()KDJ金叉/死叉信号
RSI_金叉() / RSI_死叉()RSI金叉/死叉信号
WR_金叉()WR金叉信号
PSY_金叉() / PSY_死叉()PSY金叉/死叉信号
BARSLASTCOUNT_UP()连续上涨天数
BARSLASTCOUNT_DOWN()连续下跌天数
HHVBARS(n)N日最高值到当前周期数
LLVBARS(n)N日最低值到当前周期数

3.8 风险收益指标(需指数基准)

函数名说明
roll_alpha(n)N日Alpha(5/10/20/30/60/120日)
roll_beta(n)N日Beta
roll_sharpe_ratio(n)N日夏普比率
roll_annual_volatility(n)N日年化波动率
roll_max_drawdown(n)N日最大回撤
roll_up_capture(n)N日上涨捕获率
roll_down_capture(n)N日下跌捕获率
calculate_momentum_score(n)N日回归动量评分

3.9 价格与统计类因子

函数名说明
cacal_zdf(n)N日涨跌幅(5/10/20/30/60/120日)
cacal_price_line_zdf(n)价格距离N日均线涨跌幅
cacal_line_line_zdf(n1,n2)N1均线距离N2均线涨跌幅
cacal_skew(n)N日偏度
cacal_kurt(n)N日峰度
SLOPE(n)N日回归斜率
STD(n)N日标准差

3.10 神系指标

函数名说明
SG_XDT_QR() / SG_XDT_MQR1() / SG_XDT_MQR2()心电图(需指数数据)
SG_NDB_DK() / SG_NDB_MDK1() / SG_NDB_MDK2()脑电波
SG_SMX_ZY1() / SG_SMX_ZY2() / SG_SMX_ZY3()生命线(需指数数据)
SG_LB_量比() / SG_LB_MA5() / SG_LB_MA10()量比(需指数数据)
SG_PF()强势股评分(需指数数据)

3.11 龙系指标

函数名说明
RAD_RADER1() / RAD_RADERMA()威力雷达(需指数数据)
LON_LON() / LON_LONMA() / LON_LONT()龙系长线
SHT_SHT() / SHT_SHTMA()龙系短线
ZLJC_JCS() / ZLJC_JCM() / ZLJC_JCL()主力进出
ZLMM_MMS() / ZLMM_MMM() / ZLMM_MML()主力买卖
SLZT_白龙() / SLZT_黄龙() / SLZT_紫龙() / SLZT_青龙() / SLZT_红龙() / SLZT_蓝龙()神龙在天
ADVOL_ADVOL() / ADVOL_MA1() / ADVOL_MA2()龙系离散量

3.12 鬼系及其他指标

函数名说明
CYS()市场盈亏
CYW()主力控盘
JAX_J() / JAX_A() / JAX_X()济安线
XJDX_J() / XJDX_D() / XJDX_K()超级短线
ZJTJ_无庄控盘() / ZJTJ_开始控盘() / ZJTJ_有庄控盘() / ZJTJ_主力出货()庄家抬轿
BDZX_AK() / BDZX_AD1() / BDZX_AJ() / BDZX_买进() / BDZX_卖出()波段之星
LHXJ_主力弃盘() / LHXJ_主力控盘()猎狐先觉
LYJH_机构做空能量线() / LYJH_机构做多能量线()猎鹰歼狐
JFZX_多头力量() / JFZX_空头力量()飓风智能中线
CYHT_SK() / CYHT_SD() / CYHT_卖出() / CYHT_买进()财运亨通
BSQJ_B买() / BSQJ_持仓() / BSQJ_S卖() / BSQJ_空仓()买卖区间
CDP_STD_CDP() / CDP_STD_AH() / CDP_STD_NH() / CDP_STD_NL() / CDP_STD_AL()逆势操作

3.13 交易策略类(含买卖信号)

函数名说明
MA_交易_MA1() / MA_交易_MA2() / MA_交易_平空开多() / MA_交易_平多开空()MA均线交易系统
MACD_交易_DIFF() / MACD_交易_DEA() / MACD_交易_MACD() / MACD_交易_平空开多() / MACD_交易_平多开空()MACD交易系统
KDJ_交易_K() / KDJ_交易_D() / KDJ_交易_J() / KDJ_交易_平空开多() / KDJ_交易_平多开空()KDJ交易系统

4. 系统架构

4.1 核心类:xg_factor

class xg_factor:
    """
    小果因子库核心计算类
    
    功能:提供所有因子计算方法的统一入口
    """
    def __init__(self, df='', index_df=''):
        """
        初始化因子计算实例
        
        参数:
            df: pandas.DataFrame,股票OHLCV数据
                必须包含列: date, open, high, low, close, volume, amount
            index_df: pandas.DataFrame,指数数据(可选)
                用于计算Alpha、Beta等相对指标
                必须包含列: date, close
        """
据列名自动映射
系统自动将标准列名映射为内部简写,便于快速调用:

原始列名	重命名后	简写别名
close	closePrice	C / close
open	openPrice	O / open
high	highestPrice	H / high
low	lowestPrice	L / low
volume	turnoverVol	V / volume
amount	turnoverValue	AMOUNT / amount
4.3 底层技术指标函数库(xg_tdx_func)
系统内置了通达信风格的底层技术指标计算函数:

函数名	说明	函数名	说明
MA(S,N)	简单移动平均	EMA(S,N)	指数移动平均
SMA(S,N,M)	中国式移动平均	WMA(S,N)	加权移动平均
HHV(S,N)	N日最高值	LLV(S,N)	N日最低值
HHVBARS(S,N)	最高值位置	LLVBARS(S,N)	最低值位置
REF(S,N)	引用N日前数据	DIFF(S,N)	差分
STD(S,N)	N日标准差	SUM(S,N)	N日累和
MAX(S1,S2)	最大值	MIN(S1,S2)	最小值
IF(S,A,B)	条件判断	CROSS(S1,S2)	金叉判断
COUNT(S,N)	N日条件计数	BARSLAST(S)	上次条件成立至今
SLOPE(S,N)	N日回归斜率	AVEDEV(S,N)	平均绝对偏差
FORCAST(S,N)	N日预测值	BACKSET(X,N)	未来函数(向后赋值)
ZIG(CLOSE,X)	之字转向	PEAK() / TROUGH()	波峰/波谷

# 例子单只股票因子计算
'''
from xg_factor_trader import xg_factor_trader

# 1. 初始化批量计算器(增量模式)
api = xg_factor_trader(
    max_workers=4,              # 使用4个进程
    start_date='20240101',      # 数据起始日期
    end_date='20241231',        # 数据截止日期
    verbose=True,               # 显示详细信息
    use_multiprocess=True,      # 使用多进程
    chunk_size=50,              # 每批50只
    stage_size=200,             # 每阶段200只
    use_async_io=True,          # 使用异步IO
    force_recalc=False          # 增量计算,跳过已计算
)

# 2. 生成因子列表
api.get_all_factor_table()
# 输出: data/全部因子/全部因子.xlsx 和 全部因子.json

# 3. 执行批量计算
api.cacal_all_stock_factor()

# 4. 查看结果
# 每个股票生成一个因子文件: data/全部因子数据/{stock_code}.parquet
df_513100 = api.get_factor_data('513100.SH')
print(df_513100.shape)  # (交易日数, 因子数+基础列)
print(df_513100.columns.tolist())

# 5. 获取所有股票因子数据(合并)
all_factors = api.get_all_factor_data()
print(f"全部数据: {all_factors.shape}")

# 6. 查看失败列表
# data/全部因子数据/失败列表.xlsx
'''
# 例子2批量计算全市场因子
'''
from xg_factor_trader import xg_factor_trader

# 1. 初始化批量计算器(增量模式)
api = xg_factor_trader(
    max_workers=4,              # 使用4个进程
    start_date='20240101',      # 数据起始日期
    end_date='20241231',        # 数据截止日期
    verbose=True,               # 显示详细信息
    use_multiprocess=True,      # 使用多进程
    chunk_size=50,              # 每批50只
    stage_size=200,             # 每阶段200只
    use_async_io=True,          # 使用异步IO
    force_recalc=False          # 增量计算,跳过已计算
)

# 2. 生成因子列表
api.get_all_factor_table()
# 输出: data/全部因子/全部因子.xlsx 和 全部因子.json

# 3. 执行批量计算
api.cacal_all_stock_factor()

# 4. 查看结果
# 每个股票生成一个因子文件: data/全部因子数据/{stock_code}.parquet
df_513100 = api.get_factor_data('513100.SH')
print(df_513100.shape)  # (交易日数, 因子数+基础列)
print(df_513100.columns.tolist())

# 5. 获取所有股票因子数据(合并)
all_factors = api.get_all_factor_data()
print(f"全部数据: {all_factors.shape}")

# 6. 查看失败列表
# data/全部因子数据/失败列表.xlsx
'''
# 3完整例子
'''
# ============================================================
# 小果量化因子库 - 快速开始示例
# ============================================================

from xg_factor import xg_factor
from xg_factor_trader import xg_factor_trader
import pandas as pd
import numpy as np

print("=" * 60)
print("小果量化因子库 - 快速开始")
print("=" * 60)

# ============================================================
# 第一部分:单只股票因子计算
# ============================================================
print("\n[1] 单只股票因子计算")

# 1.1 加载数据
stock = '513100.SH'
df = pd.read_parquet(f'data/历史数据/{stock}.parquet')
df['date'] = pd.to_datetime(df['date'].astype(str), format='%Y%m%d')
df = df.sort_values('date').reset_index(drop=True)

# 1.2 加载指数数据
index_df = pd.read_parquet('data/指数数据/000300.SH.parquet')
index_df['date'] = pd.to_datetime(index_df['date'].astype(str), format='%Y%m%d')
index_df = index_df.sort_values('date').reset_index(drop=True)

# 1.3 初始化因子计算器
models = xg_factor(df=df, index_df=index_df)

# 1.4 计算因子
df['5日涨跌幅'] = models.cacal_zdf(5)
df['10日涨跌幅'] = models.cacal_zdf(10)
df['MACD金叉'] = models.MACD_金叉()
df['KDJ金叉'] = models.KDJ_KD金叉()
df['RSI'] = models.RSI1()
df['CCI'] = models.CCI()
df['BBI'] = models.BBI()
df['SAR'] = models.SAR()
df['Alpha001'] = models.alpha001()
df['Alpha005'] = models.alpha005()

# 1.5 查看最新数据
latest = df.iloc[-1]
print(f"\n最新因子数据 ({latest['date']}):")
print(f"  收盘价: {latest['close']:.4f}")
print(f"  5日涨跌幅: {latest['5日涨跌幅']:.2f}%")
print(f"  10日涨跌幅: {latest['10日涨跌幅']:.2f}%")
print(f"  MACD金叉: {latest['MACD金叉']}")
print(f"  KDJ金叉: {latest['KDJ金叉']}")
print(f"  RSI: {latest['RSI']:.2f}")
print(f"  CCI: {latest['CCI']:.2f}")
print(f"  Alpha001: {latest['Alpha001']:.6f}")

# ============================================================
# 第二部分:批量计算全市场因子
# ============================================================
print("\n[2] 批量计算全市场因子(增量模式)")

# 2.1 初始化批量计算器
api = xg_factor_trader(
    max_workers=4,
    start_date='20240101',
    end_date='20241231',
    verbose=True,
    use_multiprocess=True,
    force_recalc=False        # 增量模式
)

# 2.2 生成因子列表
api.get_all_factor_table()

# 2.3 执行批量计算
# api.cacal_all_stock_factor()  # 取消注释以执行

# 2.4 获取结果
df_result = api.get_factor_data('513100.SH')
print(f"\n因子数据形状: {df_result.shape}")
print(f"因子列数: {len(df_result.columns)}")

# ============================================================
# 第三部分:因子数据导出
# ============================================================
print("\n[3] 因子数据导出")

# 3.1 导出最新日期的因子数据
latest_date = df['date'].max()
df_latest = df[df['date'] == latest_date].copy()
df_latest['date'] = df_latest['date'].dt.strftime('%Y-%m-%d')

# 3.2 选择关键因子列
key_columns = ['date', '证券代码', '证券名称', 'close', '5日涨跌幅', '10日涨跌幅',
               'MACD金叉', 'KDJ金叉', 'RSI', 'CCI', 'BBI', 'Alpha001']
df_export = df_latest[key_columns]

# 3.3 保存
df_export.to_excel('因子结果_最新.xlsx', index=False)
print(f"最新因子数据已保存: 因子结果_最新.xlsx")
print(f"共 {len(df_export)} 条记录")

print("\n" + "=" * 60)
print("小果量化因子库 - 运行完成")
print("=" * 60)
'''
# 全部的因子库计算
from xg_tdx_func.xg_tdx_func import *
import empyrical as ep
import pandas as pd
import numpy as np
import os
from datetime import datetime, timedelta
import json
import warnings
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
from scipy import stats
import statsmodels.api as sm
import math
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning, module="pandas")

class xg_factor:
    '''
    小果因子库计算系统
    '''
    def __init__(self,
                df='',
                index_df='',):
        self.path = os.path.dirname(os.path.abspath(__file__))
        self.df = df.copy() if df is not None and not isinstance(df, str) and hasattr(df, 'copy') else df
        self.index_df = index_df.copy() if index_df is not None and not isinstance(index_df, str) and hasattr(index_df, 'copy') else index_df
        
        # 数据重命名(一次性完成)
        if isinstance(self.df, pd.DataFrame) and not self.df.empty:
            rename_dict = {
                "close": "closePrice",
                "open": "openPrice",
                "low": "lowestPrice",
                "high": "highestPrice",
                "volume": "turnoverVol",
                "amount": "turnoverValue"
            }
            # 只重命名存在的列
            self.df.rename(columns={k: v for k, v in rename_dict.items() if k in self.df.columns}, inplace=True)
            
            # 提取核心数据列(使用重命名后的列名)
            self.closePrice = self.df['closePrice'] if 'closePrice' in self.df.columns else pd.Series()
            self.openPrice = self.df['openPrice'] if 'openPrice' in self.df.columns else pd.Series()
            self.lowestPrice = self.df['lowestPrice'] if 'lowestPrice' in self.df.columns else pd.Series()
            self.highestPrice = self.df['highestPrice'] if 'highestPrice' in self.df.columns else pd.Series()
            self.turnoverVol = self.df['turnoverVol'] if 'turnoverVol' in self.df.columns else pd.Series()
            self.turnoverValue = self.df['turnoverValue'] if 'turnoverValue' in self.df.columns else pd.Series()
            
            # 统一简写命名(方便调用)
            self.C = self.closePrice
            self.H = self.highestPrice
            self.L = self.lowestPrice
            self.O = self.openPrice
            self.V = self.turnoverVol
            self.AMOUNT = self.turnoverValue
            
            # 保留原始简写(兼容旧代码)
            self.close = self.closePrice
            self.high = self.highestPrice
            self.low = self.lowestPrice
            self.open = self.openPrice
            self.volume = self.turnoverVol
            self.amount = self.turnoverValue
        else:
            # 空数据时的默认值
            self.closePrice = pd.Series()
            self.openPrice = pd.Series()
            self.lowestPrice = pd.Series()
            self.highestPrice = pd.Series()
            self.turnoverVol = pd.Series()
            self.turnoverValue = pd.Series()
            self.C = pd.Series()
            self.H = pd.Series()
            self.L = pd.Series()
            self.O = pd.Series()
            self.V = pd.Series()
            self.AMOUNT = pd.Series()
            self.close = pd.Series()
            self.high = pd.Series()
            self.low = pd.Series()
            self.open = pd.Series()
            self.volume = pd.Series()
            self.amount = pd.Series()

    # ========== 辅助函数 ==========
    def _sma(self, series, n, m):
        """SMA: 移动平均,alpha = m/n"""
        return series.ewm(adjust=False, alpha=m/n, min_periods=0, ignore_na=False).mean()
    
    def _tsrank(self, series, n):
        """TSRANK: 时间序列排名"""
        def rank_last(x):
            return stats.rankdata(x)[-1] / len(x) if len(x) > 0 else np.nan
        return series.rolling(window=n, min_periods=n).apply(rank_last)
    
    def _tsrank_fixed(self, series, n):
        """改进的TSRANK函数"""
        result = pd.Series(index=series.index, dtype=float)
        for i in range(len(series)):
            start = max(0, i - n + 1)
            window_data = series.iloc[start:i+1]
            valid_data = window_data.dropna()
            if len(valid_data) >= max(2, n // 2):
                current_val = series.iloc[i]
                rank = (valid_data < current_val).sum() + 1
                result.iloc[i] = rank / len(valid_data)
            else:
                result.iloc[i] = np.nan
        return result.fillna(method='ffill').fillna(method='bfill')
    
    def _decaylinear(self, series, n):
        """DECAYLINEAR: 线性衰减加权和"""
        w = np.arange(1, n + 1)
        return series.rolling(window=n, min_periods=n).apply(lambda x: np.dot(x, w))
    
    def _regbeta(self, y, x):
        """REGBETA: 回归beta"""
        y_vals = y.values
        x_vals = x.values if isinstance(x, pd.Series) else np.array(x)
        x_vals = sm.add_constant(x_vals)
        try:
            result = sm.OLS(y_vals, x_vals).fit()
            return result.params[1]
        except:
            return np.nan
    def six_pulse_excalibur_hist(self):
        '''
        六脉神剑
        '''
        
        markers=0
        signal=0
        #df=self.data.get_hist_data_em(stock=stock)
        CLOSE=self.C
        LOW=self.L
        HIGH=self.H
        DIFF=EMA(CLOSE,8)-EMA(CLOSE,13)
        DEA=EMA(DIFF,5)
        #如果满足DIFF>DEA 在1的位置标记1的图标
        #DRAWICON(DIFF>DEA,1,1);
        markers+=IF(DIFF>DEA,1,0)
        #如果满足DIFFDEA
        signal+=IF(ABC1,1,0)
        尊重市场1=(CLOSE-LLV(LOW,8))/(HHV(HIGH,8)-LLV(LOW,8))*100
        K=SMA(尊重市场1,3,1)
        D=SMA(K,3,1)
        #如果满足k>d 在2的位置标记1的图标
        markers+=IF(K>D,1,0)
        #DRAWICON(K>D,2,1);
        markers+=IF(KD
        signal+=IF(ABC2,1,0)
        指标营地=REF(CLOSE,1)
        RSI1=(SMA(MAX(CLOSE-指标营地,0),5,1))/(SMA(ABS(CLOSE-指标营地),5,1))*100
        RSI2=(SMA(MAX(CLOSE-指标营地,0),13,1))/(SMA(ABS(CLOSE-指标营地),13,1))*100
        markers+=IF(RSI1>RSI2,1,0)
        #DRAWICON(RSI1>RSI2,3,1);
        markers+=IF(RSI1RSI2
        signal+=IF(ABC3,1,0)
        尊重市场=-(HHV(HIGH,13)-CLOSE)/(HHV(HIGH,13)-LLV(LOW,13))*100
        LWR1=SMA(尊重市场,3,1)
        LWR2=SMA(LWR1,3,1)
        #DRAWICON(LWR1>LWR2,4,1);
        markers+=IF(LWR1>LWR2,1,0)
        #DRAWICON(LWR1LWR2
        signal+=IF(ABC4,1,0)
        BBI=(MA(CLOSE,3)+MA(CLOSE,5)+MA(CLOSE,8)+MA(CLOSE,13))/4
        #DRAWICON(CLOSE>BBI,5,1);
        markers+=IF(CLOSE>BBI,1,0)
        #DRAWICON(CLOSEBBI
        signal+=IF(ABC5,1,0)
        MTM=CLOSE-REF(CLOSE,1)
        MMS=100*EMA(EMA(MTM,5),3)/EMA(EMA(ABS(MTM),5),3)
        MMM=100*EMA(EMA(MTM,13),8)/EMA(EMA(ABS(MTM),13),8)
        markers+=IF(MMS>MMM,1,0)
        #DRAWICON(MMS>MMM,6,1);
        markers+=IF(MMSMMM
        signal+=IF(ABC6,1,0)
        return signal
    def small_fruit_band_trading_1(self):
        '''
        小波段交易
        '''
        df=self.df
        CLOSE=self.C
        C=self.C
        LOW=self.L
        L=self.L
        HIGH=self.H
        H=self.H
        OPEN=self.O
        O=self.O
        volume=self.V
        V=self.V
        N1=7
        N2=5
        N3=3
        ABC1=(((HIGH + LOW)+(CLOSE*2)) / 4)
        ABC3=EMA(ABC1,N1)
        ABC4=STD(ABC1,N1)
        ABC5=((ABC1 - ABC3)*100) / ABC4
        ABC6=EMA(ABC5,N2)
        RK7=EMA(ABC6,N1)
        UP=(EMA(ABC6,10)+(100 / 2)) - 5
        DOWN=EMA(UP,N3)
        ACB1=EMA(DOWN,N3)
        ACB2=EMA(ACB1,N3)
        ACB3=EMA(ACB2,N3)
        ACB4=EMA(ACB3,N3)
        #STICKLINE(UP < REF(UP,1),UP,MA(UP,3),5,0),COLORBLUE;
        #STICKLINE(UP > REF(UP,1),UP,EMA(UP,3),5,0),COLORMAGENTA;
        df['柱子']=IF(UP > REF(UP,1),'红色','蓝色')
        df['买']=IF(AND(UP > REF(UP,1),REF(UP,1) < REF(UP,2)),'买',None)
        df['卖']=IF(AND(UP < REF(UP,1),REF(UP,1) > REF(UP,2)),'卖',None)
        #DRAWTEXT(UP > REF(UP,1)  AND  REF(UP,1) < REF(UP,2) ,UP,'买'),COLORRED;
        #DRAWTEXT(UP < REF(UP,1)  AND  REF(UP,1) > REF(UP,2) ,UP,'卖'),COLORGREEN;
        stats_list=[]
        for buy,sell in zip(df['买'].tolist(),df['卖'].tolist()):
            if buy=='买':
                stats_list.append(True)
            elif sell=='卖':
                stats_list.append(False)
            else:
                stats_list.append(None)
        df['stats']=stats_list
        df['stats']=df['stats'].fillna(method='ffill')
        return df['stats']
    def small_fruit_band_trading_2(self):
        '''
        大波段交易
        '''
        df=self.df
        CLOSE=self.C
        C=self.C
        LOW=self.L
        L=self.L
        HIGH=self.H
        H=self.H
        OPEN=self.O
        O=self.O
        volume=self.V
        V=self.V
        N1=18
        N2=15
        N3=12
        ABC1=(((HIGH + LOW)+(CLOSE*2)) / 4)
        ABC3=EMA(ABC1,N1)
        ABC4=STD(ABC1,N1)
        ABC5=((ABC1 - ABC3)*100) / ABC4
        ABC6=EMA(ABC5,N2)
        RK7=EMA(ABC6,N1)
        UP=(EMA(ABC6,10)+(100 / 2)) - 5
        DOWN=EMA(UP,N3)
        ACB1=EMA(DOWN,N3)
        ACB2=EMA(ACB1,N3)
        ACB3=EMA(ACB2,N3)
        ACB4=EMA(ACB3,N3)
        #STICKLINE(UP < REF(UP,1),UP,MA(UP,3),5,0),COLORBLUE;
        #STICKLINE(UP > REF(UP,1),UP,EMA(UP,3),5,0),COLORMAGENTA;
        df['柱子']=IF(UP > REF(UP,1),'红色','蓝色')
        df['买']=IF(AND(UP > REF(UP,1),REF(UP,1) < REF(UP,2)),'买',None)
        df['卖']=IF(AND(UP < REF(UP,1),REF(UP,1) > REF(UP,2)),'卖',None)
        #DRAWTEXT(UP > REF(UP,1)  AND  REF(UP,1) < REF(UP,2) ,UP,'买'),COLORRED;
        #DRAWTEXT(UP < REF(UP,1)  AND  REF(UP,1) > REF(UP,2) ,UP,'卖'),COLORGREEN;
        stats_list=[]
        for buy,sell in zip(df['买'].tolist(),df['卖'].tolist()):
            if buy=='买':
                stats_list.append(True)
            elif sell=='卖':
                stats_list.append(False)
            else:
                stats_list.append(None)
        df['stats']=stats_list
        df['stats']=df['stats'].fillna(method='ffill')
        return df['stats']
    def band_supe_buy_sell(self):
        '''
        波段超级买卖
        尊重市场1赋值:收盘价的6.5日[1日权重]移动平均
        尊重市场2赋值:收盘价的13.5日[1日权重]移动平均
        尊重市场11赋值:收盘价的3日[1日权重]移动平均
        尊重市场21赋值:收盘价的8日[1日权重]移动平均
        当满足条件尊重市场1>尊重市场2时,在尊重市场1和尊重市场2位置之间画柱状线,宽度为2.5,0不为0则画空心柱.,画红色,线宽为2
        当满足条件尊重市场2>尊重市场1时,在尊重市场1和尊重市场2位置之间画柱状线,宽度为2.5,0不为0则画空心柱.,画蓝色,线宽为2
        当满足条件尊重市场1上穿尊重市场2时,在最低价*0.98位置画5号图标
        当满足条件尊重市场21上穿尊重市场11时,在最高价*1.02位置书写文字,画黄色
        BBI赋值:(收盘价的3日简单移动平均+收盘价的6日简单移动平均+收盘价的12日简单移动平均+收盘价的24日简单移动平均)/4
        UPR赋值:BBI+3*BBI的13日估算标准差,线宽为2
        DWN赋值:BBI-3*BBI的13日估算标准差
        安全赋值:收盘价的60日简单移动平均,线宽为2
        LC赋值:1日前的收盘价
        RSI赋值:收盘价-LC和0的较大值的6日[1日权重]移动平均/收盘价-LC的绝对值的6日[1日权重]移动平均*100
        A7赋值:(2*收盘价+最高价+最低价)/4
        输出操作线:A7的5日简单移动平均,线宽为1
        操作线1赋值:A7的5日简单移动平均*1.03,线宽为2
        操作线2赋值:A7的5日简单移动平均*0.97,线宽为2
        输出ABC1:21日内A7的最低值
        输出ABC2:21日内A7的最高值
        SK赋值:(A7-ABC1)/(ABC2-ABC1)*100的7日指数移动平均
        SD赋值:0.667*1日前的SK+0.333*SK的5日指数移动平均
        当满足条件如果统计8日中满足收盘价<1日前的收盘价的天数/8>6/10ANDVOL>=1.5*成交量(手)的5日简单移动平均ANDCOUNT(SK>=SD,3)ANDREF(最低价,1)=120日内最低价的最低值,返回1,否则返回0时,在最低价*0.98位置画9号图标
        当满足条件如果统计13日中满足收盘价<1日前的收盘价的天数/13>6/10ANDCOUNT(SK>SD,6)ANDREF(最低价,5)=120日内最低价的最低值ANDREF(收盘价>=开盘价,4)ANDREF(收阳线,3)ANDREF(收阳线,2)ANDREF(开盘价>CLOS,返回?,否则返回?时,在,1)ANDOPEN>1日前的收盘价,1,0)位置书写文字 ,画黄色
        当满足条件如果统计13日中满足收盘价<1日前的收盘价的天数/13>6/10ANDCOUNT(SK>SD,6)ANDREF(最低价,5)=120日内最低价的最低值ANDREF(收盘价>=开盘价,4)ANDREF(收阳线,3)ANDREF(收阳线,2)ANDREF(开盘价>CLOS,返回?,否则返回?时,在,1)ANDOPEN>1日前的收盘价,1,0)位置画最低价*0.98号图标
        '''
        df=self.df
        CLOSE=self.C
        C=self.C
        LOW=self.L
        L=self.L
        HIGH=self.H
        H=self.H
        OPEN=self.O
        O=self.O
        volume=self.V
        V=self.V
        尊重市场1=SMA(C,6.5,1)
        尊重市场2=SMA(C,13.5,1)
        尊重市场11=SMA(C,3,1)
        尊重市场21=SMA(C,8,1)
        '''
        STICKLINE(尊重市场1>尊重市场2 , 尊重市场1,尊重市场2 ,2.5, 0),COLORRED,LINETHICK2;
        STICKLINE(尊重市场2>尊重市场1,尊重市场1,尊重市场2,2.5,0),COLORBLUE,LINETHICK2;
        '''
        df['柱子']=IF(尊重市场1>尊重市场2,'红色','蓝色')
        #DRAWICON( CROSS(尊重市场1,尊重市场2),L*0.98,5);
        df['笑脸']=CROSS(尊重市场1,尊重市场2)
        #DRAWTEXT(CROSS(尊重市场21,尊重市场11),H*1.02,''),COLORYELLOW;
        df['标记文字']=CROSS(尊重市场21,尊重市场11)
        BBI=(MA(CLOSE,3)+MA(CLOSE,6)+MA(CLOSE,12)+MA(CLOSE,24))/4
        UPR=BBI+3*STD(BBI,13)
        DWN=BBI-3*STD(BBI,13)
        安全=MA(CLOSE,60)
        LC=REF(CLOSE,1)
        RSI=SMA(MAX(CLOSE-LC,0),6,1)/SMA(ABS(CLOSE-LC),6,1)*100
        A7=(2*C+H+L)/4
        操作线=MA(A7,5)
        df['操作线']=操作线
        操作线1=MA(A7,5)*1.03
        df['操作线1']=操作线1
        操作线2=MA(A7,5)*0.97
        df['操作线2']=操作线2
        ABC1=LLV(A7,21)
        ABC2=HHV(A7,21)
        SK=EMA((A7-ABC1)/(ABC2-ABC1)*100,7)
        SD=EMA(0.667*REF(SK,1)+0.333*SK,5)
        '''
        DRAWICON(IF(COUNT(CLOSE6/10 AND VOL>=1.5*MA(VOL,5) AND
        COUNT(SK>=SD,3) AND REF(LOW,1)=LLV(LOW,120),1,0),L*0.98,9);
        {DRAWTEXT(IF(COUNT(CLOSE6/10 AND VOL>=1.5*MA(VOL,5) AND
        COUNT(SK>=SD,3) AND REF(LOW,1)=LLV(LOW,120),1,0),LOW*0.98,'底买') ,COLOR0099FF;}
        DRAWTEXT(IF(COUNT(CLOSE6/10 AND
        COUNT(SK>SD,6) AND REF(LOW,5)=LLV(LOW,120) AND REF(CLOSE>=OPEN,4) AND
        REF(CLOSE>OPEN,3) AND REF(CLOSE>OPEN,2) AND REF(OPEN>CLOSE,1) AND
        OPEN>REF(CLOSE,1),1,0),LOW*0.98,'底买') ,COLORYELLOW;
        DRAWICON(IF(COUNT(CLOSE6/10 AND
        COUNT(SK>SD,6) AND REF(LOW,5)=LLV(LOW,120) AND REF(CLOSE>=OPEN,4) AND
        REF(CLOSE>OPEN,3) AND REF(CLOSE>OPEN,2) AND REF(OPEN>CLOSE,1) AND
        OPEN>REF(CLOSE,1),1,0),L*0.98,9);
        '''
        趋势=CLOSE>=操作线
        df['趋势']=CLOSE>=操作线
        df['stats']=IF(AND(趋势,尊重市场1>尊重市场2),True,False)
        return df['stats']
    def KDJ_KD金叉(self):
        '''
        KDJ_KD金叉 的 Docstring
        '''
        K,D,J=KDJ(CLOSE=self.C,HIGH=self.H,LOW=self.L)
        result=CROSS(K,D)
        #result=IF(result==True,0,1)
        return result
    def KDJ_KD死叉(self):
        '''
        KDJ_KD金叉 的 Docstring
        '''
        K,D,J=KDJ(CLOSE=self.C,HIGH=self.H,LOW=self.L)
        result=CROSS(D,K)
        #result=IF(result==True,0,1)
        return result
    def RSI_金叉(self):
        '''
        RSI_金叉 的 Docstring
        '''
        RSI1,RSI2,RSI3=RSI(CLOSE=self.C)
        result=CROSS(RSI1,RSI2)
        #result=IF(result==True,0,1)
        return result
    def RSI_死叉(self):
        '''
        RSI_金叉 的 Docstring
        '''
        RSI1,RSI2,RSI3=RSI(CLOSE=self.C)
        result=CROSS(RSI2,RSI1)
        #result=IF(result==True,0,1)
        return result

    def WR_金叉(self):
        '''
        WR_金叉 的 Docstring
        '''
        WR1,WR2=WR(CLOSE=self.C,LOW=self.L,HIGH=self.H)
        result=CROSS(WR1,WR2)
        #result=IF(result==True,0,1)
        return result
    def WR_金叉(self):
        '''
        WR_金叉 的 Docstring
        '''
        WR1,WR2=WR(CLOSE=self.C,LOW=self.L,HIGH=self.H)
        result=CROSS(WR1,WR2)
        #result=IF(result==True,0,1)
        return result
    def MACD_金叉(self):
        '''
        MACD_金叉 的 Docstring
        '''
        DIF,DEA,MACD_1=MACD(CLOSE=self.C)
        result=CROSS(DIF,DEA)
        #result=IF(result==True,0,1)
        return result
    def MACD_死叉(self):
        '''
        MACD_金叉 的 Docstring
        '''
        DIF,DEA,MACD_1=MACD(CLOSE=self.C)
        result=CROSS(DEA,DIF)
        #result=IF(result==True,0,1)
        return result
    def PSY_金叉(self):
        '''
        PSY_金叉 的 Docstring
        '''
        PSY_1,PSYMA=PSY(CLOSE=self.C)
        result=CROSS(PSY_1,PSYMA)
        #result=IF(result==True,0,1)
        return result
    def PSY_死叉(self):
        '''
        PSY_金叉 的 Docstring
        '''
        PSY_1,PSYMA=PSY(CLOSE=self.C)
        result=CROSS(PSYMA,PSY_1)
        #result=IF(result==True,0,1)  
        return result
    def roll_alpha(self,n=5):
        '''
        5日alpha
        '''
        result=ep.roll_alpha(self.C.pct_change(),self.index_df['close'].pct_change(),window=n)
        return result
    def roll_beta(self,n=5):
        '''
        5日beta
        '''
        result=ep.roll_beta(self.C.pct_change(),self.index_df['close'].pct_change(),window=n)
        return result
    def roll_sharpe_ratio(self,n=5):
        '''
        5日夏普
        '''
        result=ep.roll_sharpe_ratio(self.C.pct_change(),window=n)
        return result
    def roll_annual_volatility(self,n=5):
        '''
        5日年华波动率
        '''
        result=ep.roll_annual_volatility(self.C.pct_change(),window=n)
        return result
    def roll_max_drawdown(self,n=5):
        '''
        5日最大回撤
        '''
        result=ep.roll_max_drawdown(self.C.pct_change(),window=n)
        return result
    def roll_up_capture(self,n=5):
        '''
        5日上涨捕获率
        '''
    
        result=ep.roll_up_capture(self.C.pct_change(),self.index_df['close'].pct_change(),window=n)
        return result
    def roll_down_capture(self,n=5):
        '''
        5日下跌捕获率
        '''
        result=ep.roll_down_capture(self.C.pct_change(),self.index_df['close'].pct_change(),window=n)
        return result
    
    
    


    


    # ========== 因子方法 ==========
    def SMA(self, period=5):
        """
        SMA
        """
        return MA(self.C, N=period)
    
    def CROSS_UP(self, n1=5, n2=10):
        """
        金叉判断
        """
        result = CROSS(MA(self.C, n1), MA(self.C, n2))
        return result
    
    def CROSS_DOWN(self, n1=10, n2=5):
        """
        死叉判断
        """
        result = CROSS(MA(self.C, n1), MA(self.C, n2))
        return result
    
    def BARSLASTCOUNT_UP(self):
        """
        连续上涨
        """
        return BARSLASTCOUNT(self.C > self.O)
    
    def BARSLASTCOUNT_DOWN(self):
        """
        连续下跌
        """
        return BARSLASTCOUNT(self.C < self.O)
    
    def PRICE_MA_LINE_ANAL(self, n=5):
        """
        价格在5均线上
        """
        #IF(self.C >= MA(self.C, n), 0, 1)
        return self.C >= MA(self.C, n)
    
    def MA_LINE_ANAL(self, n1=5, n2=10):
        """
        5均线在10均线上
        """
        #IF(MA(self.C, n1) >= MA(self.C, n2), 0, 1)
        return MA(self.C, n1) >= MA(self.C, n2)
    
    def HHVBARS(self, n=5):
        """
        5日最高值到当前周期
        """
        return HHVBARS(self.C, n)
    
    def LLVBARS(self, n=5):
        """
        5日最低值到当前周期
        """
        return LLVBARS(self.C, n)
    
    def cacal_zdf(self, n=5):
        """
        5日涨跌幅
        """
        return (self.C / REF(self.C, n) - 1) * 100
    def cacal_price_line_zdf(self, n=5):
        """
        价格距离5日均线涨跌幅
        """
        result=((self.C-MA(self.C,n))/MA(self.C,n))*100
        return result
    def cacal_line_line_zdf(self, n1=5,n2=10):
        """
        5日均线距离10日均线涨跌幅
        """
        result=((MA(self.C,n1)-MA(self.C,n2))/MA(self.C,n2))*100
        return result
    def cacal_skew(self,n=5):
        '''
        5日偏度
        '''
        result=self.C.rolling(window=n).skew()
        return result
    def cacal_kurt(self,n=5):
        '''
        5日峰度
        '''
        result=self.C.rolling(window=n).kurt()
        return result
    
    def calculate_momentum_score(self, n=3):
        """
        n日回归动量 - 返回时间序列
        """
        df = self.df.copy()
        mom_daily = n
        
        # 创建与df相同索引的Series,初始全部为NaN
        result = pd.Series(index=df.index, dtype=float)
        
        # 从 n-1 开始,因为需要至少 n 个数据点来计算
        for i in range(mom_daily - 1, len(df)):
            # 获取从 i-n+1 到 i 的窗口数据 (共 n 个数据点)
            start_idx = i - mom_daily + 1
            df_sub = df.iloc[start_idx:i+1].copy()
            
            # 检查数据是否足够
            if len(df_sub) < mom_daily:
                continue
            
            # 检查价格数据是否有效
            close_data = df_sub['closePrice'].values
            if np.any(np.isnan(close_data)) or np.any(np.isinf(close_data)) or np.any(close_data <= 0):
                continue
            
            try:
                y = np.log(close_data)
                y_len = len(y)
                weights = np.linspace(1, 2, y_len)
                x = np.arange(y_len)
                slope, intercept = np.polyfit(x, y, 1, w=weights)
                annualized_returns = math.pow(math.exp(slope), 250) - 1
                residuals = y - (slope * x + intercept)
                weighted_residuals = weights * residuals**2
                y_mean = np.mean(y)
                r_squared = 1 - (np.sum(weighted_residuals) / np.sum(weights * (y - y_mean)**2))
                score = annualized_returns * r_squared
                result.iloc[i] = score
            except Exception as e:
                continue
        
        return result
    
    def SLOPE(self, n=5):
        '''
        5日回归斜率
        '''
        result = SLOPE(self.close, N=n)
        return result
    
    def STD(self, n=5):
        '''
        5日标准差
        '''
        result = STD(self.close, N=n)
        return result

    # ===== 超卖超买类 =====

    def CCI(self):
        '''
        CCI商品路径指标
        '''
        TYP = (self.H + self.L + self.C) / 3
        result = (TYP - MA(TYP, 14)) * 1000 / (15 * AVEDEV(TYP, 14))
        return result

    def MFI(self):
        '''
        最近流量指标
        '''
        return MFI(CLOSE=self.C, HIGH=self.H, LOW=self.L, VOL=self.V, N=14)

    def MTM_MTM(self):
        '''动量线 - MTM值'''
        mtm_val, mtmma_val = MTM(CLOSE=self.C, N=12, M=6)
        return mtm_val

    def MTM_MTMMA(self):
        '''动量线 - MTMMA值'''
        mtm_val, mtmma_val = MTM(CLOSE=self.C, N=12, M=6)
        return mtmma_val


    def RSI1(self):
        '''相对强弱指标 - RSI1'''
        rsi1_val, rsi2_val, rsi3_val = RSI(CLOSE=self.C, N1=6, N2=12, N3=24)
        return rsi1_val

    def RSI2(self):
        '''相对强弱指标 - RSI2'''
        rsi1_val, rsi2_val, rsi3_val = RSI(CLOSE=self.C, N1=6, N2=12, N3=24)
        return rsi2_val

    def RSI3(self):
        '''相对强弱指标 - RSI3'''
        rsi1_val, rsi2_val, rsi3_val = RSI(CLOSE=self.C, N1=6, N2=12, N3=24)
        return rsi3_val

    def KDJ_K(self):
        '''KDJ指标 - K值'''
        k_val, d_val, j_val = KDJ(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=9, M1=3, M2=3)
        return k_val

    def KDJ_D(self):
        '''KDJ指标 - D值'''
        k_val, d_val, j_val = KDJ(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=9, M1=3, M2=3)
        return d_val

    def KDJ_J(self):
        '''KDJ指标 - J值'''
        k_val, d_val, j_val = KDJ(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=9, M1=3, M2=3)
        return j_val

    def SKDJ_K(self):
        '''慢速随机指标 - K值'''
        k_val, d_val = SKDJ(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=9, M=3)
        return k_val

    def SKDJ_D(self):
        '''慢速随机指标 - D值'''
        k_val, d_val = SKDJ(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=9, M=3)
        return d_val

    def UDL_UDL(self):
        '''引力线 - UDL值'''
        udl_val, maudl_val = UDL(CLOSE=self.C, N1=3, N2=5, N3=10, N4=20, M=6)
        return udl_val

    def UDL_MAUDL(self):
        '''引力线 - MAUDL值'''
        udl_val, maudl_val = UDL(CLOSE=self.C, N1=3, N2=5, N3=10, N4=20, M=6)
        return maudl_val

    def WR1(self):
        '''威廉指标 - WR1'''
        wr1_val, wr2_val = WR(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=10, N1=6)
        return wr1_val

    def WR2(self):
        '''威廉指标 - WR2'''
        wr1_val, wr2_val = WR(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=10, N1=6)
        return wr2_val

    def LWR1(self):
        '''LWR指标 - LWR1'''
        lwr1_val, lwr2_val = LWR(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=9, M1=3, M2=3)
        return lwr1_val

    def LWR2(self):
        '''LWR指标 - LWR2'''
        lwr1_val, lwr2_val = LWR(CLOSE=self.C, LOW=self.L, HIGH=self.H, N=9, M1=3, M2=3)
        return lwr2_val

    def MARSI1(self):
        '''相对强弱平均线 - RSI1'''
        rsi1_val, rsi2_val = MARSI(CLOSE=self.C, M1=10, M2=6)
        return rsi1_val

    def MARSI2(self):
        '''相对强弱平均线 - RSI2'''
        rsi1_val, rsi2_val = MARSI(CLOSE=self.C, M1=10, M2=6)
        return rsi2_val

    def BIAS1(self):
        '''乖离率 - BIAS1(6日)'''
        bias1_val, bias2_val, bias3_val = BIAS(CLOSE=self.C, N1=6, N2=12, N3=24)
        return bias1_val

    def BIAS2(self):
        '''乖离率 - BIAS2(12日)'''
        bias1_val, bias2_val, bias3_val = BIAS(CLOSE=self.C, N1=6, N2=12, N3=24)
        return bias2_val

    def BIAS3(self):
        '''乖离率 - BIAS3(24日)'''
        bias1_val, bias2_val, bias3_val = BIAS(CLOSE=self.C, N1=6, N2=12, N3=24)
        return bias3_val

    def BIAS_QL_BIAS(self):
        '''乖离率-传统版 - BIAS值'''
        bias_val, biasma_val = BIAS_QL(CLOSE=self.C, N=6, M=6)
        return bias_val

    def BIAS_QL_BIASMA(self):
        '''乖离率-传统版 - BIASMA值'''
        bias_val, biasma_val = BIAS_QL(CLOSE=self.C, N=6, M=6)
        return biasma_val

    def BIAS36_BIAS36(self):
        '''三六乖离 - BIAS36'''
        bias36_val, bias612_val, mabias_val = BIAS36(CLOSE=self.C, M=6)
        return bias36_val

    def BIAS36_BIAS612(self):
        '''三六乖离 - BIAS612'''
        bias36_val, bias612_val, mabias_val = BIAS36(CLOSE=self.C, M=6)
        return bias612_val

    def BIAS36_MABIAS(self):
        '''三六乖离 - MABIAS'''
        bias36_val, bias612_val, mabias_val = BIAS36(CLOSE=self.C, M=6)
        return mabias_val

    def ACCER(self):
        '''幅度涨速'''
        return ACCER(CLOSE=self.C, N=8)

    # ===== 趋势类型 =====

    def ASI_ASI(self):
        '''振动升降指标 - ASI'''
        asi_val, asit_val = ASI(OPEN=self.O, CLOSE=self.C, HIGH=self.H, LOW=self.L, M1=26, M2=10)
        return asi_val

    def ASI_ASIT(self):
        '''振动升降指标 - ASIT'''
        asi_val, asit_val = ASI(OPEN=self.O, CLOSE=self.C, HIGH=self.H, LOW=self.L, M1=26, M2=10)
        return asit_val

    def CHO_CHO(self):
        '''佳庆指标 - CHO'''
        cho_val, macho_val = CHO(CLOSE=self.C, OPEN=self.O, LOW=self.L, HIGH=self.H, VOL=self.V, N1=10, N2=20, M=6)
        return cho_val

    def CHO_MACHO(self):
        '''佳庆指标 - MACHO'''
        cho_val, macho_val = CHO(CLOSE=self.C, OPEN=self.O, LOW=self.L, HIGH=self.H, VOL=self.V, N1=10, N2=20, M=6)
        return macho_val

    def DMA_XT_DIF(self):
        '''平均差 - DIF'''
        dif_val, difma_val = DMA_XT(CLOSE=self.C, N1=10, N2=50, M=10)
        return dif_val

    def DMA_XT_DIFMA(self):
        '''平均差 - DIFMA'''
        dif_val, difma_val = DMA_XT(CLOSE=self.C, N1=10, N2=50, M=10)
        return difma_val

    def DMI_PDI(self):
        '''趋向指标 - PDI'''
        pdi_val, mdi_val, adx_val, adxr_val = DMI(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=14, M=6)
        return pdi_val

    def DMI_MDI(self):
        '''趋向指标 - MDI'''
        pdi_val, mdi_val, adx_val, adxr_val = DMI(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=14, M=6)
        return mdi_val

    def DMI_ADX(self):
        '''趋向指标 - ADX'''
        pdi_val, mdi_val, adx_val, adxr_val = DMI(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=14, M=6)
        return adx_val

    def DMI_ADXR(self):
        '''趋向指标 - ADXR'''
        pdi_val, mdi_val, adx_val, adxr_val = DMI(CLOSE=self.C, HIGH=self.H, LOW=self.L, N=14, M=6)
        return adxr_val

    def DPO_DPO(self):
        '''区间震荡线 - DPO'''
        dpo_val, madpo_val = DPO(C

Related skills

小果量化因子分析系统助手,作者(微信:xg_quant)基于 Alphalens 和自定义分析框架,提供因子数据清洗、IC分析、分层收益、多空组合、换手率、Fama-MacBeth回归、综合评分等完整因子评价功能。 触发关键词:因子分析、因子评价、Alphalens、IC分析、分层收益、多空组合、因子回测、因子评分、xg_alphalens、量化因子、因子有效性。

小果(微信:xg_quant)量化交易平台助手技能。小果量化是一个专业的量化交易系统,提供完整的回测、模拟交易、社区策略分享等功能。 【核心功能】 - 📊 历史行情数据获取(股票、ETF、可转债) - 📈 多维度因子数据提取(技术指标、Alpha因子、动量因子等) - 💰 财务数据分析(资产负债表、利润表、现金流量表等) - 🔄 多种策略回测(定投、动量、资产配置、网格、海龟、均值方差等) - 🤖 模拟交易和社区策略管理 - 📉 多标的量化分析(相关性矩阵、协方差矩阵、投资组合优化) - 📊 股票组合收益分析(绩效指标、夏普比率、最大回撤等) - ⏰ 分钟级K线数据

小果(微信:xg_quant)基金量化分析助手专注于基金量化分析工具,基于小果量化策略系统,提供基金历史行情数据、基金因子数据、基金策略回测、基金组合分析等核心功能。适用于基金投资者、资产配置研究员和量化策略开发者。

小果(微信:xg_quant)股票量化分析助手专注于股票量化分析工具,基于小果量化策略系统,提供股票历史行情数据、股票分钟数据、股票因子数据、股票财务数据、指数数据、 股票策略回测、股票组合分析等核心功能。 适用于股票投资者、量化研究员和策略开发者。 触发关键词:股票量化、股票回测、股票分析、股票策略、股票数据、分钟数据、财务数据、指数数据。

小果量化回测系统助手 (微信:xg_quant)。基于业界领先的Backtrader回测框架,提供从数据加载、策略开发、回测执行到绩效分析的全流程量化交易解决方案。 支持多品种(股票、期货、外汇、加密货币)、多周期(Tick, 秒, 分钟, 日, 周, 月)、多策略回测与参数优化。 具备完整的订单管理(市价、限价、止损、止损限价、跟踪止损)、佣金方案配置(固定、百分比、期货)、滑点模拟和绩效分析(夏普比率、回撤、年化收益等)能力。 作者:小果 (xg_quant),联系方式:微信 xg_quant。 触发关键词:小果、xg_quant、回测系统、量化回测、Backtrader、策略开发、策略回

小果(微信:xg_quant)可转债量化分析助手专注于可转债量化分析工具,基于小果量化策略系统,提供可转债历史行情数据、可转债因子数据、可转债策略回测、可转债组合分析等核心功能。适用于可转债投资者、量化研究员和策略开发者。 触发关键词:可转债量化、可转债回测、可转债分析、可转债策略、可转债数据、转债策略。