gitee.com/quant1x/engine@v1.8.4/datasource/base/tdx_fundflow.go (about)

     1  package base
     2  
     3  import (
     4  	"gitee.com/quant1x/exchange"
     5  	"gitee.com/quant1x/gotdx"
     6  	"gitee.com/quant1x/gox/api"
     7  	"gitee.com/quant1x/num"
     8  	"gitee.com/quant1x/pandas"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  const (
    14  	kCompanyInfoFundFlow = "资金动向"
    15  	kCategoryFundFlow    = "资金流向"
    16  )
    17  
    18  //【5.资金流向】
    19  //日期        主力净额  主力净额 超大单净买入 超大单净买入 大单净买入 大单净买入  主买净额  主买净额
    20  //            金额(元)   占比(%)   金额(元)      占比(%)    金额(元)    占比(%)   金额(元)   占比(%)
    21  //─────────────────────────────────────────────────
    22  //2023-05-15 -8581.10万    -4.95   -3069.63万        -1.77 -5511.47万      -3.18    -1.46亿    -8.44
    23  //2023-05-12    -3.26亿   -16.20      -3.01亿       -14.95 -2525.27万      -1.26    -1.62亿    -8.05
    24  //2023-05-11     2.75亿    17.10       2.95亿        18.35 -2007.90万      -1.25  -878.46万    -0.55
    25  //2023-05-10    -3.27亿   -14.45      -2.35亿       -10.37 -9216.30万      -4.07    -2.43亿   -10.75
    26  //2023-05-09     1.96亿    25.91       1.97亿        26.02   -87.68万      -0.12    -3.76亿   -49.78
    27  //2023-05-08 -1161.92万    -1.30   -1778.75万        -1.98   616.83万       0.69 -3290.33万    -3.67
    28  //2023-05-05  -515.71万    -0.56   -1642.56万        -1.79  1126.85万       1.23 -3437.44万    -3.75
    29  //2023-05-04  7685.06万     6.09    3398.48万         2.69  4286.57万       3.40     1.09亿     8.67
    30  //2023-04-28  2158.92万     3.00    1249.07万         1.74   909.85万       1.27  4346.58万     6.05
    31  //2023-04-27    -1.30亿   -17.61   -7470.81万       -10.13 -5517.81万      -7.48 -2907.44万    -3.94
    32  //2023-04-26  2127.77万     2.14    1367.42万         1.37   760.34万       0.76     1.13亿    11.34
    33  //2023-04-25   664.05万     1.08   -1458.93万        -2.36  2122.98万       3.44  -139.47万    -0.23
    34  //2023-04-24  -126.71万    -0.21     295.24万         0.48  -421.95万      -0.69  -791.00万    -1.29
    35  //2023-04-21 -8501.18万   -12.44   -3843.78万        -5.62 -4657.39万      -6.81 -8237.27万   -12.05
    36  //2023-04-20  8625.04万     8.14    3603.48万         3.40  5021.56万       4.74     1.23亿    11.57
    37  //2023-04-19  9310.97万     8.27       1.11亿         9.82 -1752.71万      -1.56     1.09亿     9.71
    38  //2023-04-18  1312.51万     4.22    1552.84万         4.99  -240.34万      -0.77 -1989.31万    -6.39
    39  //2023-04-17 -3970.27万   -10.76   -1600.06万        -4.34 -2370.21万      -6.42 -1318.26万    -3.57
    40  //2023-04-14 -1514.15万    -3.66    -405.87万        -0.98 -1108.28万      -2.68 -1296.30万    -3.13
    41  //2023-04-13    -1.09亿   -14.38   -5319.72万        -7.03 -5555.62万      -7.35 -5555.62万    -7.35
    42  //─────────────────────────────────────────────────
    43  
    44  var (
    45  	TdxFieldsFundFlow = []string{"日期", "主力净额金额(元)", "主力净额占比(%)", "超大单净买入金额(元)", "超大单净买入占比(%)", "大单净买入金额(元)", "大单净买入占比(%)", "主买净额金额(元)", "主买净额占比(%)"}
    46  )
    47  
    48  func splitContent(content, unit string) (headers []string, lines [][]string) {
    49  	//c := strings.ReplaceAll(content, "-\\u003e", "->")
    50  	//arr := strings.Split(c, "\\r\\n\\r\\n")
    51  	arr := strings.Split(content, "\r\n\r\n")
    52  	for i, block := range arr {
    53  		block = strings.TrimSpace(block)
    54  		if i > 0 && strings.Index(block, unit) >= 0 {
    55  			arr := strings.Split(block, "\r\n")
    56  			tmpHeaders := []string{}
    57  			numberFound := false
    58  			for _, v := range arr {
    59  				if strings.Index(v, unit) >= 0 {
    60  					continue
    61  				}
    62  				if strings.HasPrefix(v, "──") {
    63  					continue
    64  				}
    65  				v = strings.TrimSpace(v)
    66  				// 非数字开头是表头, 数字开头为数据
    67  				ch := v[0]
    68  				if ch >= '0' && ch <= '9' {
    69  					if !numberFound {
    70  						numberFound = true
    71  					}
    72  					cols := []string{}
    73  					foundDate := false
    74  					for _, tmp := range strings.Fields(v) {
    75  						tf := float64(0)
    76  						tmp = strings.TrimSpace(tmp)
    77  						//if tmp == "2023-04-17" {
    78  						//	fmt.Println("found")
    79  						//}
    80  						if !foundDate {
    81  							if _, err := api.ParseTime(tmp); err == nil {
    82  								cols = append(cols, tmp)
    83  								foundDate = true
    84  								continue
    85  							}
    86  						}
    87  						if fs, _, ok := strings.Cut(tmp, "万"); ok {
    88  							tf = num.AnyToFloat64(fs) * 10000
    89  						} else if fs, _, ok := strings.Cut(tmp, "亿"); ok {
    90  							tf = num.AnyToFloat64(fs) * 100000000
    91  						} else {
    92  							tf = num.AnyToFloat64(fs)
    93  						}
    94  						f := strconv.FormatFloat(tf, 'f', -1, 64)
    95  						cols = append(cols, f)
    96  					}
    97  					lines = append(lines, cols)
    98  
    99  				} else {
   100  					tmpHeaders = append(tmpHeaders, v)
   101  				}
   102  
   103  			}
   104  			if numberFound {
   105  				tmpHeadersCount := len(tmpHeaders)
   106  				if tmpHeadersCount >= 1 {
   107  					headers = strings.Fields(tmpHeaders[0])
   108  				}
   109  				numberOfHeaderFields := len(headers)
   110  				for j := 1; j < tmpHeadersCount; j++ {
   111  					remaining := strings.Fields(tmpHeaders[j])
   112  					numberOfRemainingFields := len(remaining)
   113  					for k := 0; k < numberOfRemainingFields; k++ {
   114  						pos := 1 + k
   115  						headers[numberOfHeaderFields-pos] += remaining[numberOfRemainingFields-pos]
   116  					}
   117  
   118  				}
   119  			}
   120  			break
   121  		}
   122  	}
   123  	return
   124  }
   125  
   126  // FundFlow 资金流向
   127  //
   128  //	deprecated: 不推荐
   129  func FundFlow(securityCode string) pandas.DataFrame {
   130  	tdxApi := gotdx.GetTdxApi()
   131  	securityCode = exchange.CorrectSecurityCode(securityCode)
   132  	reply, err := tdxApi.GetCompanyInfoContent(securityCode, kCompanyInfoFundFlow)
   133  	if err != nil {
   134  		return pandas.DataFrame{Err: err}
   135  	}
   136  	//fmt.Println("code:", securityCode)
   137  	//fmt.Printf("%+v\n", reply)
   138  	//data, _ := json.Marshal(reply)
   139  	//text := api.Bytes2String(data)
   140  	//fmt.Println(text)
   141  	//dict := reply.Map("资金流向")
   142  	//dict.Each(func(key interface{}, value interface{}) {
   143  	//	fmt.Println(key, value)
   144  	//})
   145  
   146  	headers, lines := splitContent(reply.Content, kCategoryFundFlow)
   147  	//for _, v := range headers {
   148  	//	fmt.Printf("%s|", v)
   149  	//}
   150  	//fmt.Println()
   151  	//for _, vv := range lines {
   152  	//	for _, v := range vv {
   153  	//		fmt.Printf("%s|", v)
   154  	//	}
   155  	//	fmt.Println()
   156  	//}
   157  	//fmt.Println()
   158  	if len(headers) == 0 || len(lines) == 0 || len(headers) != len(lines[0]) {
   159  		return pandas.DataFrame{}
   160  	}
   161  	rows := [][]string{}
   162  	rows = append(rows, headers)
   163  	fieldsNum := len(headers)
   164  	for _, v := range lines {
   165  		if len(v) != fieldsNum {
   166  			continue
   167  		}
   168  		rows = append(rows, v)
   169  	}
   170  
   171  	df := pandas.LoadRecords(rows)
   172  	return df
   173  }