|
@@ -65,6 +65,8 @@ func CheckAnalysisCorrelationExtraConfig(extraConfig tradeAnalysisModel.Correlat
|
|
|
|
|
|
// GetCorrelationTableRowsDataByConfig 根据配置获取相关性表格数据
|
|
// GetCorrelationTableRowsDataByConfig 根据配置获取相关性表格数据
|
|
func GetCorrelationTableRowsDataByConfig(tableConfig tradeAnalysisModel.CorrelationTableExtraConfig) (tables []*tradeAnalysisModel.CorrelationTableData, err error) {
|
|
func GetCorrelationTableRowsDataByConfig(tableConfig tradeAnalysisModel.CorrelationTableExtraConfig) (tables []*tradeAnalysisModel.CorrelationTableData, err error) {
|
|
|
|
+ tables = make([]*tradeAnalysisModel.CorrelationTableData, 0)
|
|
|
|
+
|
|
// 获取标的指标数据
|
|
// 获取标的指标数据
|
|
baseDateData := make(map[time.Time]float64)
|
|
baseDateData := make(map[time.Time]float64)
|
|
{
|
|
{
|
|
@@ -103,7 +105,7 @@ func GetCorrelationTableRowsDataByConfig(tableConfig tradeAnalysisModel.Correlat
|
|
}
|
|
}
|
|
|
|
|
|
// [合约+期货公司]持仓数据
|
|
// [合约+期货公司]持仓数据
|
|
- tradeData, e := GetCorrelationTableTradeData(tableConfig.Exchange, []string{tableConfig.ClassifyName}, contracts, tableConfig.CompanyNames, tableConfig.PredictRatio)
|
|
|
|
|
|
+ tradeData, e := GetCorrelationTableTradeData(tableConfig.Exchange, tableConfig.ClassifyName, contracts, tableConfig.CompanyNames, tableConfig.PredictRatio, tableConfig.ContractType)
|
|
if e != nil {
|
|
if e != nil {
|
|
err = fmt.Errorf("获取[合约+期货公司]持仓数据失败, %v", e)
|
|
err = fmt.Errorf("获取[合约+期货公司]持仓数据失败, %v", e)
|
|
return
|
|
return
|
|
@@ -118,34 +120,37 @@ func GetCorrelationTableRowsDataByConfig(tableConfig tradeAnalysisModel.Correlat
|
|
|
|
|
|
// 遍历相关性配置(目前最多有两个滚动相关性), 遍历指标, 分别计算滚动相关性
|
|
// 遍历相关性配置(目前最多有两个滚动相关性), 遍历指标, 分别计算滚动相关性
|
|
maxPre := 10 // 需要展示的以标的指标日期为准往前推N个交易日的滚动相关性
|
|
maxPre := 10 // 需要展示的以标的指标日期为准往前推N个交易日的滚动相关性
|
|
- startDate := baseDate.AddDate(0, 0, -maxPre)
|
|
|
|
- endDate := baseDate
|
|
|
|
- rowDays := utils.GetTradingDays(baseDate.AddDate(0, 0, -20), baseDate) // 从20个自然日里截取11个数据对应的交易日,且当日排最前,后面依次为0、-1到-10
|
|
|
|
|
|
+ startBase := baseDate.AddDate(0, 0, -maxPre)
|
|
|
|
+
|
|
|
|
+ // 从20个自然日里截取11个数据对应的交易日,且当日排最前,后面依次为0、-1到-10
|
|
|
|
+ rowDays := utils.GetTradingDays(baseDate.AddDate(0, 0, -20), baseDate)
|
|
rowDays = utils.ReverseTimeSlice(rowDays)
|
|
rowDays = utils.ReverseTimeSlice(rowDays)
|
|
rowDays = rowDays[:11]
|
|
rowDays = rowDays[:11]
|
|
- tables = make([]*tradeAnalysisModel.CorrelationTableData, 0)
|
|
|
|
for _, rc := range tableConfig.RollConfig {
|
|
for _, rc := range tableConfig.RollConfig {
|
|
tableData := new(tradeAnalysisModel.CorrelationTableData)
|
|
tableData := new(tradeAnalysisModel.CorrelationTableData)
|
|
tableData.CalculateValue = rc.CalculateValue
|
|
tableData.CalculateValue = rc.CalculateValue
|
|
tableData.LeadValue = rc.LeadValue
|
|
tableData.LeadValue = rc.LeadValue
|
|
tableData.RowsData = make([]*tradeAnalysisModel.CorrelationTableRowData, 0)
|
|
tableData.RowsData = make([]*tradeAnalysisModel.CorrelationTableRowData, 0)
|
|
|
|
|
|
|
|
+ // 计算滚动相关性的开始日期, 用计算窗口往前推(可以往前多推俩月否则可能取不到)
|
|
|
|
+ startDate := startBase.AddDate(0, 0, -(rc.CalculateValue + rc.LeadValue + 60))
|
|
|
|
+
|
|
for kd, kv := range tradeEdbList {
|
|
for kd, kv := range tradeEdbList {
|
|
row := new(tradeAnalysisModel.CorrelationTableRowData)
|
|
row := new(tradeAnalysisModel.CorrelationTableRowData)
|
|
row.Exchange = kv.Exchange
|
|
row.Exchange = kv.Exchange
|
|
row.CompanyName = kv.CompanyName
|
|
row.CompanyName = kv.CompanyName
|
|
row.ClassifyName = kv.ClassifyName
|
|
row.ClassifyName = kv.ClassifyName
|
|
row.ClassifyType = kv.ClassifyType
|
|
row.ClassifyType = kv.ClassifyType
|
|
- // 数据为合约加总时名称为合约名,否则为合约+期货公司+方向
|
|
|
|
|
|
+ // 数据为合约加总时名称为品种名+方向,否则为合约+期货公司+方向
|
|
if kv.IsTotal {
|
|
if kv.IsTotal {
|
|
- row.RowName = kv.ClassifyType
|
|
|
|
|
|
+ row.RowName = fmt.Sprintf("%s%s%s", kv.ClassifyName, kv.CompanyName, tradeAnalysisModel.WarehouseTypeSuffixNames[kv.ContractPosition])
|
|
} else {
|
|
} else {
|
|
row.RowName = fmt.Sprintf("%s%s%s", kv.ClassifyType, kv.CompanyName, tradeAnalysisModel.WarehouseTypeSuffixNames[kv.ContractPosition])
|
|
row.RowName = fmt.Sprintf("%s%s%s", kv.ClassifyType, kv.CompanyName, tradeAnalysisModel.WarehouseTypeSuffixNames[kv.ContractPosition])
|
|
}
|
|
}
|
|
row.DayData = make([]*tradeAnalysisModel.CorrelationTableRowDayData, 0)
|
|
row.DayData = make([]*tradeAnalysisModel.CorrelationTableRowDayData, 0)
|
|
|
|
|
|
// 这里加行数据
|
|
// 这里加行数据
|
|
- rd, e := CalculateRollCorrelationData(rc.CalculateValue, rc.LeadValue, baseDateData, tradeEdbDataMap[kd], startDate, endDate)
|
|
|
|
|
|
+ rd, e := CalculateRollCorrelationData(rc.CalculateValue, rc.LeadValue, baseDateData, tradeEdbDataMap[kd], startDate, baseDate)
|
|
if e != nil {
|
|
if e != nil {
|
|
err = fmt.Errorf("计算行数据-滚动相关性失败, %v", e)
|
|
err = fmt.Errorf("计算行数据-滚动相关性失败, %v", e)
|
|
return
|
|
return
|
|
@@ -211,154 +216,76 @@ func GetTopContractsByType(contractType int, exchange, classifyName string, base
|
|
|
|
|
|
// CalculateRollCorrelationData 计算滚动相关性
|
|
// CalculateRollCorrelationData 计算滚动相关性
|
|
func CalculateRollCorrelationData(calculateValue, leadValue int, baseEdbData map[time.Time]float64, changeEdbData map[time.Time]int, startDate, endDate time.Time) (dateRatio map[time.Time]float64, err error) {
|
|
func CalculateRollCorrelationData(calculateValue, leadValue int, baseEdbData map[time.Time]float64, changeEdbData map[time.Time]int, startDate, endDate time.Time) (dateRatio map[time.Time]float64, err error) {
|
|
- //dataList = make([]*data_manage.EdbDataList, 0)
|
|
|
|
|
|
+ dateRatio = make(map[time.Time]float64)
|
|
|
|
|
|
// 计算窗口,不包含第一天
|
|
// 计算窗口,不包含第一天
|
|
- //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
|
- //startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
|
|
|
|
startDate = startDate.AddDate(0, 0, 1)
|
|
startDate = startDate.AddDate(0, 0, 1)
|
|
|
|
|
|
- //baseEdbInfo := edbInfoMappingA
|
|
|
|
- //changeEdbInfo := edbInfoMappingB
|
|
|
|
-
|
|
|
|
- // 获取时间基准指标在时间区间内的值
|
|
|
|
- //aDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
|
- //switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
|
- //case 0:
|
|
|
|
- // aDataList, err = data_manage.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
|
- //case 1:
|
|
|
|
- // _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, true)
|
|
|
|
- //default:
|
|
|
|
- // err = errors.New("指标base类型异常")
|
|
|
|
- // return
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- // 获取变频指标所有日期的值, 插值法完善数据
|
|
|
|
- //bDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
|
- //switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
|
- //case 0:
|
|
|
|
- // bDataList, err = data_manage.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
|
|
|
|
- //case 1:
|
|
|
|
- // _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
|
- //default:
|
|
|
|
- // err = errors.New("指标change类型异常")
|
|
|
|
- // return
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- // 数据平移变频指标领先/滞后的日期(单位天)
|
|
|
|
- // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
|
- //baseDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
|
- //baseDataMap := make(map[string]float64)
|
|
|
|
- //changeDataList := make([]*data_manage.EdbDataList, 0)
|
|
|
|
- changeDataMap := make(map[time.Time]float64)
|
|
|
|
-
|
|
|
|
- // A指标不管三七二十一,先变个频再说
|
|
|
|
- //{
|
|
|
|
- // _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
|
|
|
|
- // if e != nil {
|
|
|
|
- // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
|
- // return
|
|
|
|
- // }
|
|
|
|
- // //baseDataList = tmpNewChangeDataList
|
|
|
|
- //}
|
|
|
|
- // B指标不管三七二十一,先变个频再说
|
|
|
|
- //{
|
|
|
|
- // tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
|
- // if e != nil {
|
|
|
|
- // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
|
- // return
|
|
|
|
- // }
|
|
|
|
- // changeDataList = tmpNewChangeDataList
|
|
|
|
- //
|
|
|
|
- // // 平移下日期
|
|
|
|
- // moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
|
- // _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- // TODO:平移下日期
|
|
|
|
- //moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
|
- //_, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue)
|
|
|
|
- changeDataMap = MoveDataDaysToNewDataList(changeEdbData, leadValue)
|
|
|
|
|
|
+ // 平移变频指标
|
|
|
|
+ changeDataMap := MoveDataDaysToNewDataList(changeEdbData, leadValue)
|
|
|
|
|
|
// 计算计算时,需要多少个日期内数据
|
|
// 计算计算时,需要多少个日期内数据
|
|
- //calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
|
|
|
|
calculateDay := calculateValue
|
|
calculateDay := calculateValue
|
|
|
|
|
|
var minRatio, maxRatio float64
|
|
var minRatio, maxRatio float64
|
|
- dateRatio = make(map[time.Time]float64)
|
|
|
|
// 计算 每个日期的相关性值
|
|
// 计算 每个日期的相关性值
|
|
- {
|
|
|
|
- startDateTime := startDate
|
|
|
|
- //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
|
- //if endDate == `` {
|
|
|
|
- // endDate = baseEdbInfo.EndDate
|
|
|
|
- //}
|
|
|
|
- //endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
|
|
|
|
- endDateTime := endDate.AddDate(0, 0, -(calculateDay - 1))
|
|
|
|
-
|
|
|
|
- // 是否开始第一条数据
|
|
|
|
- var isStart, isNotFirst bool
|
|
|
|
- for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
|
|
|
|
- yCalculateData := make([]float64, 0)
|
|
|
|
- baseCalculateData := make([]float64, 0)
|
|
|
|
-
|
|
|
|
- // 取出对应的基准日期的值
|
|
|
|
- for i := 0; i < calculateDay; i++ {
|
|
|
|
- //iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
|
|
|
|
- iDay := currDay.AddDate(0, 0, i)
|
|
|
|
-
|
|
|
|
- tmpBaseValue, ok1 := baseEdbData[iDay]
|
|
|
|
- tmpChangeValue, ok2 := changeDataMap[iDay]
|
|
|
|
- if !ok1 || !ok2 {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
- baseCalculateData = append(baseCalculateData, tmpBaseValue)
|
|
|
|
- yCalculateData = append(yCalculateData, tmpChangeValue)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 没有数据的话,那就不返回
|
|
|
|
- if len(baseCalculateData) == 0 {
|
|
|
|
|
|
+ startDateTime := startDate
|
|
|
|
+ endDateTime := endDate.AddDate(0, 0, -(calculateDay - 1))
|
|
|
|
+
|
|
|
|
+ // 是否开始第一条数据
|
|
|
|
+ var isStart, isNotFirst bool
|
|
|
|
+ for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
|
|
|
|
+ yCalculateData := make([]float64, 0)
|
|
|
|
+ baseCalculateData := make([]float64, 0)
|
|
|
|
+
|
|
|
|
+ // 取出对应的基准日期的值
|
|
|
|
+ for i := 0; i < calculateDay; i++ {
|
|
|
|
+ iDay := currDay.AddDate(0, 0, i)
|
|
|
|
+
|
|
|
|
+ tmpBaseValue, ok1 := baseEdbData[iDay]
|
|
|
|
+ tmpChangeValue, ok2 := changeDataMap[iDay]
|
|
|
|
+ if !ok1 || !ok2 {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
- // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
|
- ratio := utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
|
|
|
|
|
|
+ baseCalculateData = append(baseCalculateData, tmpBaseValue)
|
|
|
|
+ yCalculateData = append(yCalculateData, tmpChangeValue)
|
|
|
|
+ }
|
|
|
|
|
|
- // 过滤前面都是0的数据
|
|
|
|
- {
|
|
|
|
- if ratio != 0 {
|
|
|
|
- isStart = true
|
|
|
|
- }
|
|
|
|
|
|
+ // 没有数据的话,那就不返回
|
|
|
|
+ if len(baseCalculateData) == 0 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
|
+ ratio := utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
|
|
|
|
|
|
- if !isStart {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
|
|
+ // 过滤前面都是0的数据
|
|
|
|
+ {
|
|
|
|
+ if ratio != 0 {
|
|
|
|
+ isStart = true
|
|
}
|
|
}
|
|
|
|
|
|
- dataTime := currDay.AddDate(0, 0, calculateDay-1)
|
|
|
|
- //dataList = append(dataList, data_manage.EdbDataList{
|
|
|
|
- // //EdbDataId: 0,
|
|
|
|
- // EdbInfoId: 0,
|
|
|
|
- // DataTime: dataTime.Format(utils.FormatDate),
|
|
|
|
- // DataTimestamp: dataTime.UnixNano() / 1e6,
|
|
|
|
- // Value: ratio,
|
|
|
|
- //})
|
|
|
|
- // 保留4位小数
|
|
|
|
- ratio = math.Round(ratio*10000) / 10000
|
|
|
|
- dateRatio[dataTime] = ratio
|
|
|
|
-
|
|
|
|
- if !isNotFirst {
|
|
|
|
- minRatio = ratio
|
|
|
|
- maxRatio = ratio
|
|
|
|
- isNotFirst = true
|
|
|
|
- }
|
|
|
|
- if minRatio > ratio {
|
|
|
|
- minRatio = ratio
|
|
|
|
- }
|
|
|
|
- if maxRatio < ratio {
|
|
|
|
- maxRatio = ratio
|
|
|
|
|
|
+ if !isStart {
|
|
|
|
+ continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- //dataResp.DataList = dataList
|
|
|
|
|
|
+
|
|
|
|
+ dataTime := currDay.AddDate(0, 0, calculateDay-1)
|
|
|
|
+
|
|
|
|
+ // 保留4位小数
|
|
|
|
+ ratio = math.Round(ratio*10000) / 10000
|
|
|
|
+ dateRatio[dataTime] = ratio
|
|
|
|
+
|
|
|
|
+ if !isNotFirst {
|
|
|
|
+ minRatio = ratio
|
|
|
|
+ maxRatio = ratio
|
|
|
|
+ isNotFirst = true
|
|
|
|
+ }
|
|
|
|
+ if minRatio > ratio {
|
|
|
|
+ minRatio = ratio
|
|
|
|
+ }
|
|
|
|
+ if maxRatio < ratio {
|
|
|
|
+ maxRatio = ratio
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|