<template>
  <card>
    <div class="row">
      <div class="col-md-6">
        <div class="row">
          <div class="col-md-3">
            <base-button @click="excelImport">导入数据源</base-button>
          </div>
          <div class="col-md-4">
            <base-input>
              <el-date-picker
                class="select-danger"
                v-model="startTime"
                type="datetime"
                placeholder="选择开始日期与时间"
              >
              </el-date-picker>
            </base-input>
          </div>
          <div class="col-md-4">
            <base-input>
              <el-date-picker
                v-model="endTime"
                type="datetime"
                placeholder="选择结束日期与时间"
                @change="timepIkcer"
              >
              </el-date-picker>
            </base-input>
          </div>
        </div>
      </div>
      <div class="col-md-6">
        <el-select
          class="select-danger"
          style="width:200px"
          placeholder="策略选择"
          v-model="policyMode"
        >
          <el-option
            v-for="item in RobotPolicyType"
            class="select-danger"
            :label="item.title"
            :key="item.value"
            :value="item.value"
          >
          </el-option>
        </el-select>
        <base-button @click="executeTest" class="ml-2">执行回测</base-button>
        <base-button class="ml-2">重置回测</base-button>
      </div>
    </div>
    <!-- <a-row type="flex">
      <a-col :span="16">
        <a-row type="flex"
          ><a-col><a-button @click="excelImport">导入数据源</a-button></a-col
          ><a-col :offset="1"
            ><a-date-picker v-model="startTime"></a-date-picker></a-col
          ><a-col :offset="1"
            ><a-date-picker v-model="endTime"></a-date-picker></a-col
          ><a-col :offset="1"
            ><a-select
              v-model="policyMode"
              placeholder="选择策略"
              style="width:160px"
            >
              <a-select-option
                v-for="i in RobotPolicyType"
                :key="i.value"
                :value="i.value"
              >
                {{ i.title }}</a-select-option
              >
            </a-select></a-col
          >
        </a-row></a-col
      >
      <a-col :span="4">
        <a-row type="flex">
          <a-col><a-button @click="executeTest">执行回测</a-button></a-col>
          <a-col :offset="1"> <a-button>重置回测</a-button></a-col>
        </a-row>
      </a-col>
    </a-row> -->

    <div>
      <el-tabs value="1">
        <el-tab-pane name="1" label="K线图表">
          <div class="row">
            <div class="col-md-3">
              <p class="form-label">文件列表</p>
              <el-select
                class="select-danger"
                style="width:200px"
                placeholder="不限"
                v-model="lineSelect"
                @change="onKlineExcelChange"
              >
                <el-option
                  v-for="item in kLinesFromExcels"
                  class="select-danger"
                  :label="item.name"
                  :key="item.name"
                  :value="item.name"
                >
                </el-option>
              </el-select>
            </div>
            <div class="col-md-2">
              <p class="form-label">购买信号数显示过滤：</p>
              <el-select
                class="select-danger"
                style="width:100px"
                placeholder="不限"
                v-model="keyFilter.buy"
                @change="changeFilter($event, 1)"
              >
                <el-option
                  v-for="item in buyPointCountList"
                  class="select-danger"
                  :value="item.value"
                  :label="item.title"
                  :key="item.value"
                >
                </el-option>
              </el-select>
            </div>
            <div class="col-md-2">
              <p class="form-label">卖出信号数显示过滤：</p>
              <el-select
                class="select-danger"
                style="width:100px"
                placeholder="不限"
                v-model="keyFilter.sale"
                @change="changeFilter($event, 0)"
              >
                <el-option
                  v-for="item in salePointCountList"
                  class="select-danger"
                  :value="item.value"
                  :label="item.title"
                  :key="item.value"
                >
                </el-option>
              </el-select>
            </div>
          </div>
          <!-- k线Excel选择 -->

          <KLine :data="kLineData" :keyFilter="keyFilter" />
          <!-- <HQKline /> -->
        </el-tab-pane>
        <el-tab-pane name="2" label="编译策略">
          <movement-policy-form
            v-if="policyMode == 0"
            v-model="policyFormData"
          />
          <!-- <top-end-policy v-else v-model="policyFormData" /> -->
        </el-tab-pane>
      </el-tabs>
    </div>
    <div>
      <el-tabs value="1">
        <!-- 交易清单 -->
        <el-tab-pane name="1" label="交易清单">
          <order-table v-model="tradeData"></order-table>
        </el-tab-pane>

        <!-- 信号记录 -->
        <el-tab-pane name="2" label="信号记录">
          根据时间范围筛选信号记录：
          <!-- <a-range-picker
            style="margin: 10px 0"
            v-model="dateRange"
            :show-time="{ format: 'HH:mm' }"
            format="YYYY-MM-DD HH:mm"
            :placeholder="['开始时间', '结束时间']"
            @change="onOk"
          /> -->
          <el-date-picker
            v-model="dateRange"
            type="datetimerange"
            range-separator="~"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            @change="onOk"
          >
          </el-date-picker>
          <custom-base-table
            size="small"
            :columns="logColumns"
            :dataSource="logData.filter(logShowCondition)"
          >
            <template slot="LogType" slot-scope="text">
              {{ LogTypes.filter(item => item.value == text)[0].title }}
            </template>
          </custom-base-table>
        </el-tab-pane>
        <!-- 绩效总结 -->
        <el-tab-pane name="3" label="绩效总结">
          <account-info v-model="accountInfo" />
        </el-tab-pane>
      </el-tabs>
    </div>
  </card>
</template>
<script>
/* eslint-disable */
import { tradeColumns, logColumns } from "../prePages/js/columns";
import Excel from "../../utils/ExcelUtils";
import KLine from "../../oldComponents/EchartTable/kLine";
// import HQKline from "../../oldComponents/EchartTable/hqKline";
import { secToMin } from "../../utils/TimeUtils";
import AccountInfo from "./AccountInfo";
import {
  RobotPolicyType,
  ResetMomentumWaveTest,
  LogTypes
} from "../prePages/js/selectoptions";
import MovementPolicyForm from "../../components/MovementPolicyForm";
import moment from "moment";
import OrderTable from "./OrderTable";
import CustomBaseTable from "../../components/CustomBaseTable.vue";
// import TopEndPolicy from "../components/TopEndPolicy.vue";
export default {
  components: {
    KLine,
    AccountInfo,
    MovementPolicyForm,
    OrderTable,
    CustomBaseTable
    // HQKline

    //    TopEndPolicy
  },
  data() {
    return {
      moment,
      secToMin,
      LogTypes,
      spinning: false,
      lineSelect: "",
      kLinesFromExcels: [],
      tradeColumns,
      logColumns,
      logData: [],
      RobotPolicyType,
      policyMode: 0,
      tradeData: [],
      startTime: null,
      endTime: null,
      kLineData: {},
      keyFilter: {},
      policyFormData: {},
      kLineDataList: [],
      dateRange: [],
      accountInfo: {},
      topTempDataList: [],
      buyPointCountList: [],
      salePointCountList: [],
      logShowCondition: i => true
    };
  },
  mounted() {
    this.policyFormData = ResetMomentumWaveTest;
  },
  methods: {
    onOk(value) {
      this.logShowCondition = item =>
        moment(item.CreateTime).isBetween(moment(value[0]), moment(value[1]));
    },
    changeFilter(value, type) {
      console.log(value, type);
      this.keyFilter = Object.assign({}, this.keyFilter);
    },
    splitData(rawData) {
      var categoryData = [];
      var keyPoint = [];
      var values = [];
      this.buyPointCountList = [];
      this.salePointCountList = [];

      for (var i = 0; i < rawData.length; i++) {
        categoryData.push(rawData[i].splice(0, 1)[0]);
        let buyKey = rawData[i].splice(4, 1)[0];

        if (buyKey && JSON.stringify(buyKey) != "{}") {
          keyPoint.push(buyKey);
          if (!this.buyPointCountList.some(item => item.value == buyKey.value))
            this.buyPointCountList.push(buyKey);
        }

        let saleKey = rawData[i].splice(4, 1)[0];
        if (saleKey && JSON.stringify(saleKey) != "{}") {
          keyPoint.push(saleKey);
          if (
            !this.salePointCountList.some(item => item.value == saleKey.value)
          )
            this.salePointCountList.push(saleKey);
        }

        values.push(rawData[i]);
      }
      console.log({
        categoryData,
        values,
        keyPoint
      });
      return {
        categoryData,
        values,
        keyPoint
      };
    },
    //选择不同的excel表展示
    onKlineExcelChange(model) {
      console.log(model);
      if (
        this.kLinesFromExcels &&
        this.kLinesFromExcels.length > 0 &&
        this.kLinesFromExcels.some(item => item.name == model)
      ) {
        let result = [];
        if (this.policyMode == 0) {
          let data = this.kLinesFromExcels.filter(item => item.name == model)[0]
            .data;
          let temp = this.mutateData(data); //分别操作出接口需要的data和图标data
          result = this.splitData(temp.kLineData); //图表data处理
          this.kLineDataList = temp.postData;
          this.kLineData = result;
        } else {
          let index = 0;
          for (let i = 0; i < this.kLinesFromExcels.length; i++) {
            if (this.kLinesFromExcels[i].name == model) {
              index = i;
              break;
            }
          }
          let temp = this.topMutateData(this.topTempDataList[index]);
          result = this.splitData(temp.kLineData); //图表data处理
          this.kLineData = result;
        }
      }
    },
    excelImport() {
      let that = this;
      let result = [];
      this.spinning = true;
      Excel.importExcel(data => {
        that.spinning = false;
        if (data && data[0]) {
          if (this.policyMode == 1) {
            this.kLinesFromExcels = data;
            this.lineSelect = data[0].name;
            let _data = [];
            data.forEach(element => {
              _data.push(element.data);
            });
            this.topEndMutateData(_data);
            console.log("final", _data);
            this.topTempDataList = _data;
            let temp = that.topMutateData(_data[0]);
            result = this.splitData(temp.kLineData); //图表data处理
            this.kLineData = result;
          } else {
            this.kLinesFromExcels = data;
            this.lineSelect = data[0].name;
            let temp = that.mutateData(data[0].data); //分别操作出接口需要的data和图标data
            result = this.splitData(temp.kLineData); //图表data处理
            console.log("what i got", result);
            this.kLineDataList = temp.postData;
            this.kLineData = result;
          }
        }
      });
    },

    //顶底策略数据处理
    topEndMutateData(data) {
      if (data && data[0]) {
        let originalArray = data[0];
        var offset = [];
        for (let oi = 1; oi < originalArray.length; oi++) {
          let target = originalArray[oi];
          var redTotal = target[5] == 1 ? 1 : 0; //以首表Red[5]为初始值
          var greenTotal = target[6] == 1 ? 1 : 0;
          // console.log(
          //   "为时间戳:" + target[0] + "找匹配",
          //   " redTotal:" + redTotal
          // );
          for (let di = 1; di < data.length; di++) {
            let r = this.getOffset(
              offset,
              target,
              data,
              oi,
              di,
              redTotal,
              greenTotal
            );
            if (r && r.redTotal) redTotal = r.redTotal;
            if (r && r.greenTotal) greenTotal = r.greenTotal;
          }
          target[7] = target[5] == 1 ? redTotal : 0;
          target[8] = target[6] == 1 ? greenTotal : 0;
          for (let tempIndex = 1; tempIndex < data.length; tempIndex++) {
            if (data[tempIndex][oi + offset[tempIndex]]) {
              let condition = data[tempIndex][oi + offset[tempIndex]][5] == 1;
              data[tempIndex][oi + offset[tempIndex]][7] = condition
                ? redTotal
                : 0;

              let condition2 = data[tempIndex][oi + offset[tempIndex]][6] == 1;
              data[tempIndex][oi + offset[tempIndex]][8] = condition2
                ? greenTotal
                : 0;
            }
          }
        }
      }
    },

    //得出offset计算
    getOffset(offset, target, source, tIndex, sIndex, redTotal, greenTotal) {
      // console.log(offset);
      if (offset[sIndex] == null || offset[sIndex] == undefined)
        offset[sIndex] = 0;
      // console.log(target[0], source[sIndex][tIndex + offset[sIndex]][0]);
      //先判读同个索引是否对其有对应时间戳
      if (!source[sIndex][tIndex + offset[sIndex]]) return;
      if (target[0] == source[sIndex][tIndex + offset[sIndex]][0]) {
        //相同索引有时间戳的
        redTotal =
          redTotal + (source[sIndex][tIndex + offset[sIndex]][5] == 1 ? 1 : 0);
        greenTotal =
          greenTotal +
          (source[sIndex][tIndex + offset[sIndex]][6] == 1 ? 1 : 0);
        // console.log(
        //   target[0],
        //   redTotal,
        //   source[sIndex][tIndex + offset[sIndex]][0],
        //   "找到相等的"
        // );
        return { redTotal, greenTotal };
      } else if (target[0] > source[sIndex][tIndex + offset[sIndex]][0]) {
        // console.log("目标大", offset[sIndex]);
        //目标时间戳大于比对的时间戳
        offset[sIndex] = offset[sIndex] + 1;
        this.getOffset(
          offset,
          target,
          source,
          tIndex,
          sIndex,
          redTotal,
          greenTotal
        );
      } else if (target[0] < source[sIndex][tIndex + offset[sIndex]][0]) {
        offset[sIndex] = offset[sIndex] - 1;
        // console.log("目标小", offset);
        //目标时间戳小于比对的时间戳
        return;
      }
    },

    //动量回测数据处理
    mutateData(data) {
      let result = [];
      let postResult = [];
      if (data.length > 1) {
        for (let i = 0; i < data.length; i++) {
          if (i == 0) continue;
          let subArray = [];
          let postObj = { N: null };
          for (let j = 0; j < data[i].length; j++) {
            if (j == 0) {
              if (
                this.startTime &&
                this.endTime &&
                !moment(data[i][j] * 1000).isBetween(
                  moment(this.startTime),
                  moment(this.endTime)
                )
              ) {
                break;
              } else if (
                this.startTime &&
                !moment(data[i][j] * 1000).isAfter(moment(this.startTime))
              ) {
                break;
              }

              subArray[0] = moment(data[i][j] * 1000).format(
                "YYYY-MM-DD HH:mm:ss"
              );
              postObj.T = data[i][j];
            } else if (j == 1) {
              //open
              subArray[1] = data[i][j];
              postObj.O = data[i][j];
            } else if (j == 2) {
              //highest
              subArray[4] = data[i][j];
              postObj.H = data[i][j];
            } else if (j == 3) {
              //lowest
              subArray[3] = data[i][j];
              postObj.L = data[i][j];
            } else if (j == 4) {
              //close
              subArray[2] = data[i][j];
              postObj.C = data[i][j];
            } else if (j == 7) {
              postObj.TP = data[i][j];
            } else if (j == 13) {
              if (data[i][j] != 0) postObj.N = 3;
            } else if (j == 11) {
              if (data[i][j] != 0) postObj.N = 2;
            } else if (j == 15) {
              subArray[5] = {};
              if (data[i][j] != 0) {
                postObj.N = 1;
                subArray[5] = {
                  name: "卖出Point",
                  coord: [
                    `${moment(data[i][0] * 1000).format(
                      "YYYY-MM-DD HH:mm:ss"
                    )}`,
                    data[i][2]
                  ],
                  value: "1",
                  itemStyle: {
                    color: "rgb(23,160,93)"
                  }
                };
              }
            } else if (j == 14) {
              subArray[6] = {};
              if (data[i][j] != 0) {
                postObj.N = 0;
                subArray[6] = {
                  name: "买入Point",
                  symbol: "diamond",
                  symbolSize: [15, 25],
                  symbolOffset: [0, 25],
                  coord: [
                    `${moment(data[i][0] * 1000).format(
                      "YYYY-MM-DD HH:mm:ss"
                    )}`,
                    data[i][3]
                  ],
                  value: "0",
                  itemStyle: {
                    color: "rgb(221,82,70)"
                  }
                };
              }
            }
          }
          if (subArray.length > 0) result.push(subArray);
          if (postObj.T != null) postResult.push(postObj);
        }
      }
      return { kLineData: result, postData: postResult };
    },

    //订底回测数据处理
    topMutateData(data) {
      let result = [];
      let postResult = [];
      if (data.length > 1) {
        for (let i = 0; i < data.length; i++) {
          if (i == 0) continue;
          let subArray = [];
          let postObj = { N: null };
          for (let j = 0; j < data[i].length; j++) {
            if (j == 0) {
              if (
                this.startTime &&
                this.endTime &&
                !moment(data[i][j] * 1000).isBetween(
                  this.startTime.startOf("day"),
                  this.endTime.endOf("day")
                )
              ) {
                break;
              } else if (
                this.startTime &&
                !moment(data[i][j] * 1000).isAfter(
                  this.startTime.startOf("day")
                )
              ) {
                break;
              }

              subArray[0] = moment(data[i][j] * 1000).format(
                "YYYY-MM-DD HH:mm:ss"
              );
              postObj.T = data[i][j];
            } else if (j == 1) {
              //open
              subArray[1] = data[i][j];
              postObj.OpenPrice = data[i][j];
            } else if (j == 2) {
              //highest
              subArray[4] = data[i][j];
              postObj.H = data[i][j];
            } else if (j == 3) {
              //lowest
              subArray[3] = data[i][j];
              postObj.L = data[i][j];
            } else if (j == 4) {
              //close
              subArray[2] = data[i][j];
              postObj.C = data[i][j];
            } else if (j == 5) {
              postObj.TP = data[i][j];
            } else if (j == 6) {
              if (data[i][j] != 0) postObj.N = 3;
            } else if (j == 7) {
              subArray[5] = {};
              if (data[i][j] && data[i][j] != 0) {
                postObj.N = 1;
                subArray[5] = {
                  name: "买入Point",
                  coord: [
                    `${moment(data[i][0] * 1000).format(
                      "YYYY-MM-DD HH:mm:ss"
                    )}`,
                    data[i][3]
                  ],
                  value: data[i][j],
                  itemStyle: {
                    color: "rgb(23,160,93)"
                  }
                };
              }
            } else if (j == 8) {
              subArray[6] = {};
              if (data[i][j] && data[i][j] != 0) {
                postObj.N = 0;
                subArray[6] = {
                  name: "卖出Point",
                  symbol: "diamond",
                  symbolSize: [15, 25],
                  symbolOffset: [0, 25],
                  coord: [
                    `${moment(data[i][0] * 1000).format(
                      "YYYY-MM-DD HH:mm:ss"
                    )}`,
                    data[i][2]
                  ],
                  value: data[i][j],
                  itemStyle: {
                    color: "rgb(221,82,70)"
                  }
                };
              }
            }
          }
          if (subArray.length > 0) result.push(subArray);
          if (postObj.T != null) postResult.push(postObj);
        }
      }
      return { kLineData: result, postData: postResult };
    },

    executeTest() {
      if (this.policyFormData && this.kLineDataList.length > 0) {
        this.spinning = true;
        this.$http
          .post("/Api/Simulation/MomentumWaveTest", {
            MomentumWavePolicy: this.policyFormData,
            kLineDataList: this.kLineDataList
          })
          .then(res => {
            this.logShowCondition = i => true;
            this.spinning = false;
            if (res.Code == 200) {
              console.log("回测成功");
              this.logData = res.Data.ExecutionLogList;
              if (this.logData.length > 0) {
                this.dateRange[0] = this.logData[
                  this.logData.length - 1
                ].CreateTime;
                this.dateRange[1] = this.logData[0].CreateTime;
              }
              res.Data.OrderList.sort(
                (a, b) => b.PurchaseKLineId - a.PurchaseKLineId
              );
              this.tradeData = res.Data.OrderList;
              //accountInfo
              this.accountInfo.MaxOrderTotalPurchasePricePerRound =
                res.Data.MaxOrderTotalPurchasePricePerRound;
              this.accountInfo.MaxTotalPurchasePricePerDay =
                res.Data.MaxTotalPurchasePricePerDay;
              this.accountInfo.MaxOrderHoldTime = res.Data.MaxOrderHoldTime;
              this.accountInfo.MinOrderHoldTime = res.Data.MinOrderHoldTime;
              this.accountInfo.MaxOrderLossRatio = res.Data.MaxOrderLossRatio;
              this.accountInfo.MaxAccountLossRatio =
                res.Data.MaxAccountLossRatio;
              this.accountInfo.MaxOrderProfit = res.Data.MaxOrderProfit;
              this.accountInfo.MaxOrderProfitRatio =
                res.Data.MaxOrderProfitRatio;
              this.accountInfo.MinOrderProfit = res.Data.MinOrderProfit;
              this.accountInfo.MinOrderProfitRatio =
                res.Data.MinOrderProfitRatio;
            }
          });
      }
    },
    timepIkcer() {
      console.log(this.startTime, this.endTime);
    }
  }
};
</script>

<style></style>
