gitee.com/quant1x/engine@v1.8.4/factors/feature_misc_base.go (about)

     1  package factors
     2  
     3  import (
     4  	"gitee.com/quant1x/engine/cache"
     5  	"gitee.com/quant1x/engine/datasource/base"
     6  	"gitee.com/quant1x/engine/market"
     7  	"gitee.com/quant1x/engine/utils"
     8  	"gitee.com/quant1x/exchange"
     9  	"gitee.com/quant1x/gotdx/securities"
    10  	"gitee.com/quant1x/num"
    11  	"gitee.com/quant1x/pandas"
    12  	. "gitee.com/quant1x/pandas/formula"
    13  )
    14  
    15  // MiscKLine K线特征
    16  type MiscKLine struct {
    17  	Date                string  // 日期
    18  	Code                string  // 证券代码
    19  	Shape               uint64  // K线形态
    20  	MV3                 float64 // 3日均量
    21  	MA3                 float64 // 3日均价
    22  	MV5                 float64 // 5日均量
    23  	MA5                 float64 // 5日均价
    24  	MA10                float64 // 10日均价
    25  	MA20                float64 // 20日均价
    26  	VolumeRatio         float64 // 成交量比
    27  	TurnoverRate        float64 // 换手率
    28  	AmplitudeRatio      float64 // 振幅
    29  	AveragePrice        float64 // 均价线
    30  	Change5             float64 // 5日涨幅
    31  	Change10            float64 // 10日涨幅
    32  	InitialPrice        float64 // 短线底部(Short-Term Bottom),股价最近一次上串5日均线
    33  	ShortIntensity      float64 // 短线强度
    34  	ShortIntensityDiff  float64 // 短线强度增幅
    35  	MediumIntensity     float64 // 中线强度
    36  	MediumIntensityDiff float64 // 中线强度增幅
    37  	Vix                 float64 // 波动率
    38  	Sentiment           float64 // 情绪值
    39  	Consistent          int     // 情绪一致
    40  }
    41  
    42  // NewMiscKLine 构建制定日期的K线数据
    43  func NewMiscKLine(code, date string) *MiscKLine {
    44  	securityCode := exchange.CorrectSecurityCode(code)
    45  	klines := base.CheckoutKLines(securityCode, date)
    46  	if len(klines) < cache.KLineMin {
    47  		return nil
    48  	}
    49  	digits := 2
    50  	securityInfo, ok := securities.CheckoutSecurityInfo(securityCode)
    51  	if ok {
    52  		digits = int(securityInfo.DecimalPoint)
    53  	}
    54  	ek := &MiscKLine{
    55  		Date: date,
    56  		Code: securityCode,
    57  	}
    58  	df := pandas.LoadStructs(klines)
    59  	var (
    60  		OPEN   = df.ColAsNDArray("open")
    61  		CLOSE  = df.ColAsNDArray("close")
    62  		HIGH   = df.ColAsNDArray("high")
    63  		LOW    = df.ColAsNDArray("low")
    64  		VOL    = df.ColAsNDArray("volume")
    65  		AMOUNT = df.ColAsNDArray("amount")
    66  		UP     = df.ColAsNDArray("up")
    67  		DOWN   = df.ColAsNDArray("down")
    68  	)
    69  	// 2. 计算3日均量
    70  	mv3 := MA(VOL, 3)
    71  	ma3 := MA(CLOSE, 3)
    72  	ek.MV3 = utils.Float64IndexOf(mv3, -1)
    73  	ek.MA3 = utils.Float64IndexOf(ma3, -1)
    74  	// 2. 计算5日分钟均量
    75  	mv5 := MA(VOL, 5) // 5日均量
    76  	mv5m := mv5.Div(exchange.CN_DEFAULT_TOTALFZNUM)
    77  	ma5Volume := utils.Float64IndexOf(mv5m, -1)
    78  	ek.MV5 = num.Decimal(ma5Volume, digits)
    79  	ma5 := MA(CLOSE, 5)
    80  	ek.MA5 = utils.Float64IndexOf(ma5, -1)
    81  	ma10 := MA(CLOSE, 10)
    82  	ek.MA10 = utils.Float64IndexOf(ma10, -1)
    83  	ma20 := MA(CLOSE, 20)
    84  	ek.MA20 = utils.Float64IndexOf(ma20, -1)
    85  	// 3. 隔日成交量放大比例
    86  	vr := VOL.Div(REF(VOL, 1))
    87  	volumeChangeRate := utils.Float64IndexOf(vr, -1)
    88  	ek.VolumeRatio = num.Decimal(volumeChangeRate, digits)
    89  	// 换手率
    90  	f10 := GetL5F10(securityCode)
    91  	if f10 != nil {
    92  		turnoverRate := VOL.Div(f10.Capital).Mul(100.00)
    93  		ek.TurnoverRate = num.Decimal(utils.Float64IndexOf(turnoverRate, -1))
    94  	}
    95  	// 振幅, 这里只比对最高价和最低价的幅度, 不参考前一天的收盘价
    96  	ar := HIGH.Div(LOW).Sub(1.00).Mul(100.00)
    97  	ek.AmplitudeRatio = utils.Float64IndexOf(ar, -1)
    98  
    99  	// 4. 当日K线图形概要
   100  	shape := KLineShape(df, securityCode)
   101  	ek.Shape = shape
   102  	// 均价线
   103  	averagePrice := AMOUNT.Div(VOL)
   104  	ap := utils.Float64IndexOf(averagePrice, -1)
   105  	ek.AveragePrice = num.Decimal(ap, digits)
   106  	// 5. 计算阶段涨幅
   107  	chg5 := CLOSE.Div(REF(CLOSE, 5)).Sub(1.00).Mul(100)
   108  	chg10 := CLOSE.Div(REF(CLOSE, 10)).Sub(1.00).Mul(100)
   109  	change5 := utils.Float64IndexOf(chg5, -1)
   110  	change10 := utils.Float64IndexOf(chg10, -1)
   111  	ek.Change5 = num.Decimal(change5, digits)
   112  	ek.Change10 = num.Decimal(change10, digits)
   113  
   114  	// 6. 多空强度
   115  	//QDMA5:=MA(CLOSE,5);
   116  	//ma5 := MA(CLOSE, 5)
   117  	//QDMA10:=MA(CLOSE,10);
   118  	//ma10 := MA(CLOSE, 10)
   119  	//QDMA20:=MA(CLOSE,20);
   120  	//ma20 := MA(CLOSE, 20)
   121  	//QDV1:=QDMA5*100/QDMA20-100;
   122  	//qdv1 := ma5.Div(ma20).Sub(1.00).Mul(100)
   123  	qdv1 := utils.SeriesChangeRate(ma20, ma5)
   124  	//QDV2:=QDMA10*100/QDMA20-100;
   125  	qdv2 := utils.SeriesChangeRate(ma20, ma10)
   126  	//QD1:=ABS(QDV1-REF(QDV1,1));
   127  	//qd1 := ABS(qdv1.Sub(REF(qdv1, 1)))
   128  	qd1 := qdv1.Sub(REF(qdv1, 1))
   129  	//QD2:=ABS(QDV2-REF(QDV2,1));
   130  	//qd2 := ABS(qdv2.Sub(REF(qdv2, 1)))
   131  	qd2 := qdv2.Sub(REF(qdv2, 1))
   132  	//QDCD:=CLOSE*100/REF(CLOSE,1)-100;
   133  	//超短线:QDCD-REF(QDCD,1),NODRAW;
   134  	//短线强度:QD1-REF(QD1,1),NODRAW;
   135  	shortIntensity := qd1
   136  	//中线强度:QD2-REF(QD2,1),NODRAW;
   137  	mediumIntensity := qd2
   138  	ek.ShortIntensity = utils.Float64IndexOf(shortIntensity, -1)
   139  	shortIntensityDiff := qd1.Sub(REF(qd1, 1))
   140  	ek.ShortIntensityDiff = utils.Float64IndexOf(shortIntensityDiff, -1)
   141  	ek.MediumIntensity = utils.Float64IndexOf(mediumIntensity, -1)
   142  	mediumIntensityDiff := qd2.Sub(REF(qd2, 1))
   143  	ek.MediumIntensityDiff = utils.Float64IndexOf(mediumIntensityDiff, -1)
   144  
   145  	// 7. 波动率
   146  	N := 3
   147  	M := 21
   148  	//TYPICAL_PRICE:=(OPEN+CLOSE+HIGH+LOW)/4;
   149  	TYPICAL_PRICE := OPEN.Add(CLOSE).Add(HIGH).Add(LOW).Div(4.00)
   150  	//METHOD:=EMA(TYPICAL_PRICE,N);
   151  	METHOD := EMA(TYPICAL_PRICE, N)
   152  	//APPLY_TO:=TYPICAL_PRICE;
   153  	APPLY_TO := TYPICAL_PRICE
   154  	//MYSTDDEV:=SQRT(SUM(POW(APPLY_TO-METHOD,2),N)/N);
   155  	var1 := APPLY_TO.Sub(METHOD)
   156  	var2 := var1.Mul(var1)
   157  	var3 := SUM(var2, N)
   158  	var4 := SQRT(var3.Div(N))
   159  	MYSTDDEV := pandas.ToSeries[num.DType](var4...)
   160  	//MAXB:=HHV(MYSTDDEV,M);
   161  	MAXB := HHV(MYSTDDEV, M)
   162  	//MINB:=LLV(MYSTDDEV,M);
   163  	MINB := LLV(MYSTDDEV, M)
   164  	//VIX:100*(MYSTDDEV-MINB)/(MAXB-MINB);
   165  	//10,DOTLINE,COLORGREEN;
   166  	//50,DOTLINE,COLORYELLOW;
   167  	vix := MYSTDDEV.Sub(MINB).Div(MAXB.Sub(MINB)).Mul(100)
   168  	ek.Vix = utils.Float64IndexOf(vix, -1)
   169  
   170  	// 8. 短线底部(Short-Term Bottom),股价最近一次上穿5日均线
   171  	closeCrossMa5 := CROSS(CLOSE, ma5)
   172  	crossPeriod := BARSLAST(closeCrossMa5)
   173  	crossPrice := REF(OPEN, crossPeriod)
   174  	ek.InitialPrice = num.Decimal(utils.Float64IndexOf(crossPrice, -1))
   175  
   176  	// 指数类情绪值 情绪一致
   177  	up := utils.Float64IndexOf(UP, -1)
   178  	down := utils.Float64IndexOf(DOWN, -1)
   179  	ek.Sentiment, ek.Consistent = market.SecuritySentiment(up, down)
   180  
   181  	return ek
   182  }
   183  
   184  func (k *MiscKLine) Kind() cache.Kind {
   185  	return FeatureKLineShap
   186  }
   187  
   188  func (k *MiscKLine) Name() string {
   189  	return "K线形态"
   190  }