Browse Source

回测

master
lizhixin 4 years ago
parent
commit
8903983535
  1. 14
      src/App.vue
  2. 4
      src/main.js
  3. 54
      src/oldComponents/EchartTable/kLine.vue
  4. 22
      src/pages/ReCheck/OrderTable.vue
  5. 114
      src/pages/ReCheck/index.vue

14
src/App.vue

@ -27,6 +27,18 @@ export default {
<style lang="scss">
.el-tabs__item {
color: #C9CCD2;
color: #c9ccd2 !important;
}
.el-tabs__active-bar {
background-color: #333d54 !important;
}
.select-danger.el-select .el-input input {
background-color: transparent;
border-width: 1px;
border-color: #2b3553;
color: #fd5d93;
}
.el-input {
background-color: transparent;
}
</style>

4
src/main.js

@ -29,7 +29,8 @@ import {
Option,
Tabs,
TabPane,
Pagination
Pagination,
DatePicker
} from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import i18n from "./i18n";
@ -47,6 +48,7 @@ Vue.use(Option);
Vue.use(Tabs);
Vue.use(TabPane);
Vue.use(Pagination);
Vue.use(DatePicker);
/* eslint-disable no-new */
new Vue({
router,

54
src/oldComponents/EchartTable/kLine.vue

@ -12,7 +12,7 @@ import {
LegendComponent,
DataZoomComponent,
MarkLineComponent,
MarkPointComponent,
MarkPointComponent
} from "echarts/components";
import { CandlestickChart, LineChart } from "echarts/charts";
@ -29,7 +29,7 @@ echarts.use([
MarkPointComponent,
CandlestickChart,
LineChart,
CanvasRenderer,
CanvasRenderer
]);
var upColor = "#FCE4E4";
@ -45,8 +45,8 @@ export default {
type: Object,
default: () => {
return { sale: -1, buy: -1 };
},
},
}
}
},
watch: {
data(newVal, oldVal) {
@ -63,7 +63,7 @@ export default {
if (this.tempKeyPointArray && this.tempKeyPointArray[0]) {
if (newVal.buy && newVal.buy != -1) {
result = this.tempKeyPointArray.filter(
(item) =>
item =>
item.name == "卖出Point" ||
(item.name == "买入Point" &&
(item.value == newVal.buy || item.value > newVal.buy))
@ -72,7 +72,7 @@ export default {
if (newVal.sale && newVal.sale != -1) {
let _r = !newVal.buy ? this.tempKeyPointArray : result;
result = _r.filter(
(item) =>
item =>
item.name == "买入Point" ||
(item.name == "卖出Point" &&
(item.value == newVal.sale || item.value > newVal.sale))
@ -82,7 +82,7 @@ export default {
!newVal.buy && !newVal.sale ? this.tempKeyPointArray : result;
this.options && this.chart.setOption(this.options);
}
},
}
},
data() {
return {
@ -96,16 +96,16 @@ export default {
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
},
type: "cross"
}
},
legend: {
data: ["时分K"],
data: ["时分K"]
},
grid: {
left: "10%",
right: "10%",
bottom: "10%",
bottom: "10%"
},
xAxis: {
type: "category",
@ -116,27 +116,27 @@ export default {
splitLine: { show: false },
splitNumber: 20,
min: "dataMin",
max: "dataMax",
max: "dataMax"
},
yAxis: {
scale: true,
splitArea: {
show: true,
},
show: true
}
},
dataZoom: [
{
type: "inside",
start: 50,
end: 100,
end: 100
},
{
show: true,
type: "slider",
top: "90%",
start: 50,
end: 100,
},
end: 100
}
],
series: [
{
@ -148,23 +148,23 @@ export default {
color: upColor,
color0: downColor,
borderColor: upBorderColor,
borderColor0: downBorderColor,
borderColor0: downBorderColor
},
markPoint: {
label: {
normal: {
formatter: function(param) {
return param != null ? Math.round(param.value) : "";
},
},
}
}
},
data: [],
data: []
// tooltip: {
// formatter: function(param) {
// return param.name + "<br>" + (param.data.coord || "");
// },
// },
},
}
// markLine: {
// symbol: ["none", "none"],
// data: [
@ -211,7 +211,7 @@ export default {
// },
// ],
// },
},
}
// {
// name: "MA5",
// type: "line",
@ -248,8 +248,8 @@ export default {
// opacity: 0.5,
// },
// },
],
},
]
}
};
},
mounted() {
@ -272,8 +272,8 @@ export default {
result.push(sum / dayCount);
}
return result;
},
},
}
}
};
</script>

22
src/pages/ReCheck/OrderTable.vue

@ -13,13 +13,17 @@
<template slot="KLineId" slot-scope="item">
<p>
{{
moment(item.row.item.PurchaseKLineId * 1000).format("YYYY-MM-DD HH:mm:ss")
moment(item.row.item.PurchaseKLineId * 1000).format(
"YYYY-MM-DD HH:mm:ss"
)
}}
</p>
<p>
{{
item.row.item.SaleKLineId
? moment(item.row.item.SaleKLineId * 1000).format("YYYY-MM-DD HH:mm:ss")
? moment(item.row.item.SaleKLineId * 1000).format(
"YYYY-MM-DD HH:mm:ss"
)
: "-"
}}
</p>
@ -43,7 +47,12 @@
<template slot="Profit" slot-scope="item">
<p>{{ item.row.item.Profit }}</p>
<p v-if="item.row.item.Profit">
{{ ((item.row.item.Profit / item.row.item.TotalPurchasePrice) * 100).toFixed(2) }}%
{{
(
(item.row.item.Profit / item.row.item.TotalPurchasePrice) *
100
).toFixed(2)
}}%
</p>
<p v-else>-</p>
</template>
@ -52,7 +61,10 @@
<p>{{ item.row.item.TotalProfit }}</p>
<p v-if="item.row.item.TotalProfit">
{{
((item.row.item.TotalProfit / policyFormData.PositionFund) * 100).toFixed(2)
(
(item.row.item.TotalProfit / policyFormData.PositionFund) *
100
).toFixed(2)
}}%
</p>
<p v-else>-</p>
@ -67,7 +79,7 @@ import moment from "moment";
export default {
model: { prop: "data", event: "tableDataChange" },
props: { data: { type: Array, default: () => [] } },
components: CustomBaseTable,
components: { CustomBaseTable },
data() {
return { moment, columns: tradeColumns };
}

114
src/pages/ReCheck/index.vue

@ -1,5 +1,55 @@
<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"
@ -34,7 +84,7 @@
</a-row> -->
<div>
<el-tabs default-active-key="1">
<el-tabs value="1">
<el-tab-pane name="1" label="K线图表">
<div class="row">
<div class="col-md-3">
@ -101,13 +151,16 @@
<!-- <HQKline /> -->
</el-tab-pane>
<el-tab-pane name="2" label="编译策略">
<MomentumWavePolicy v-if="policyMode == 0" v-model="policyFormData" />
<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 default-active-key="1">
<el-tabs value="1">
<!-- 交易清单 -->
<el-tab-pane name="1" label="交易清单">
<order-table v-model="tradeData"></order-table>
@ -116,15 +169,24 @@
<!-- 信号记录 -->
<el-tab-pane name="2" label="信号记录">
根据时间范围筛选信号记录
<a-range-picker
<!-- <a-range-picker
style="margin: 10px 0"
v-model="dateRange"
:show-time="{ format: 'HH:mm' }"
format="YYYY-MM-DD HH:mm"
:placeholder="['开始时间', '结束时间']"
@ok="onOk"
/>
<a-table
@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)"
@ -132,7 +194,7 @@
<template slot="LogType" slot-scope="text">
{{ LogTypes.filter(item => item.value == text)[0].title }}
</template>
</a-table>
</custom-base-table>
</el-tab-pane>
<!-- 绩效总结 -->
<el-tab-pane name="3" label="绩效总结">
@ -155,16 +217,18 @@ import {
ResetMomentumWaveTest,
LogTypes
} from "../prePages/js/selectoptions";
import MomentumWavePolicy from "../../components/MovementPolicyForm";
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,
MomentumWavePolicy,
OrderTable
MovementPolicyForm,
OrderTable,
CustomBaseTable
// HQKline
// TopEndPolicy
@ -185,9 +249,9 @@ export default {
tradeData: [],
startTime: null,
endTime: null,
kLineData: [],
kLineData: {},
keyFilter: {},
policyFormData: ResetMomentumWaveTest,
policyFormData: {},
kLineDataList: [],
dateRange: [],
accountInfo: {},
@ -197,10 +261,13 @@ export default {
logShowCondition: i => true
};
},
mounted() {
this.policyFormData = ResetMomentumWaveTest;
},
methods: {
onOk(value) {
this.logShowCondition = item =>
moment(item.CreateTime).isBetween(value[0], value[1]);
moment(item.CreateTime).isBetween(moment(value[0]), moment(value[1]));
},
changeFilter(value, type) {
console.log(value, type);
@ -411,16 +478,14 @@ export default {
this.startTime &&
this.endTime &&
!moment(data[i][j] * 1000).isBetween(
this.startTime.startOf("day"),
this.endTime.endOf("day")
moment(this.startTime),
moment(this.endTime)
)
) {
break;
} else if (
this.startTime &&
!moment(data[i][j] * 1000).isAfter(
this.startTime.startOf("day")
)
!moment(data[i][j] * 1000).isAfter(moment(this.startTime))
) {
break;
}
@ -615,10 +680,10 @@ export default {
console.log("回测成功");
this.logData = res.Data.ExecutionLogList;
if (this.logData.length > 0) {
this.dateRange[0] = moment(
this.logData[this.logData.length - 1].CreateTime
);
this.dateRange[1] = moment(this.logData[0].CreateTime);
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
@ -643,6 +708,9 @@ export default {
}
});
}
},
timepIkcer() {
console.log(this.startTime, this.endTime);
}
}
};

Loading…
Cancel
Save