add create strategy dialog

This commit is contained in:
simple321vip
2022-09-12 19:22:07 +08:00
parent 766dea9c24
commit da7bbc8e2e
6 changed files with 235 additions and 48 deletions
+21 -3
View File
@@ -10,6 +10,14 @@ const get_strategy_files = () => {
})
}
"strategy file list"
const get_strategy_load_files = () => {
return trader_service({
url: '/trader/api/v1/strategy_file/load',
method: 'GET',
})
}
"upload a strategy file"
const upload_strategy_file = (file: any) => {
const formData = new FormData();
@@ -58,11 +66,11 @@ const get_strategies = () => {
}
"create a strategy"
const create_strategy = () => {
const create_strategy = (ruleForm: object) => {
return trader_service({
url: '/trader/api/v1/strategy',
method: 'POST',
data: {}
data: ruleForm
})
}
@@ -98,8 +106,17 @@ const get_strategy_status = (strategy_name: string) => {
})
}
"get a strategy status"
const get_vt_symbols = () => {
return trader_service({
url: '/trader/api/v1/strategy/vt_symbols',
method: 'GET',
})
}
export {
get_strategy_files,
get_strategy_load_files,
upload_strategy_file,
load_strategy_file,
unload_strategy_file,
@@ -109,5 +126,6 @@ export {
start_strategy,
stop_strategy,
remove_strategy,
get_strategy_status
get_strategy_status,
get_vt_symbols
}
+9 -9
View File
@@ -61,25 +61,25 @@ const routes: Array<RouteRecordRaw> = [
name: '一键打包'
}
},
{
path: '/trader',
component: () => import('../view/trader/index.vue'),
meta: {
name: 'trader'
}
},
// {
// path: '/trader',
// component: () => import('../view/trader/index.vue'),
// meta: {
// name: 'trader'
// }
// },
{
path: '/strategy',
component: () => import('../view/trader/cta_strategy_file.vue'),
meta: {
name: '策略文件管理'
name: '策略文件'
}
},
{
path: '/strategy_instance',
component: () => import('../view/trader/cta_strategy.vue'),
meta: {
name: '策略管理'
name: 'CTA策略'
}
},
]
+13
View File
@@ -0,0 +1,13 @@
import { acceptHMRUpdate, defineStore } from "pinia"
export const strategyStore = defineStore({
id: 'strategy',
state: () => ({
class_names: [],
vt_symbols: []
}),
})
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(strategyStore, import.meta.hot))
}
+44 -33
View File
@@ -1,19 +1,7 @@
<template>
<div class="bookmark">
<!-- <el-form>
<el-row>
<el-col :span="6">
<el-form-item>
<el-input v-model="search_form.comment" placeholder="请输入" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="doSearch">检索</el-button>
</el-col>
</el-row>
</el-form> -->
<div class="startegy">
<div class="create_dialog">
<el-button type="primary" @click="on_create">新建</el-button>
<el-button type="primary" @click="handle_create">新建策略</el-button>
</div>
<el-table ref="multipleTableRef" :data="strategy_list" style="width: 100%">
@@ -66,30 +54,30 @@
</template>
</el-table-column>
</el-table>
<el-dialog v-model="createStrategyDialogVisible">
<create_strategy_dialog ref="dialogRef" @on-create="on_list"></create_strategy_dialog>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { reactive, ref } from 'vue'
import create_strategy_dialog from './dialog.vue'
import {
get_strategies,
create_strategy,
start_strategy,
stop_strategy,
get_strategy_status,
get_strategy_load_files,
get_vt_symbols
} from '../../api/cta_strategy'
import { genFileId } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
import { h } from 'vue'
import { ElMessage } from 'element-plus'
import { strategyStore } from '../../store/strategy'
const upload = ref<UploadInstance>()
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
upload.value!.handleStart(file)
}
const store = strategyStore()
let createStrategyDialogVisible = ref(false)
type Strategy = {
@@ -110,21 +98,22 @@ const on_list = () => {
})
})
}
const on_create = () => {
const dialogRef = ref()
const handle_create = () => {
createStrategyDialogVisible.value = true
dialogRef.value.clear_form()
}
const on_start = (row: any) => {
start_strategy(row.strategy_name).then(res => {
row.status = 2
})
}
const on_stop = (row: any) => {
stop_strategy(row.strategy_name).then(res => {
row.status = 3
})
}
@@ -140,9 +129,31 @@ const on_status = (row: any) => {
})
}
// init process
on_list()
const init = () => {
on_list()
get_strategy_load_files().then(res => {
store.$patch({ class_names: res.data.class_names })
}).catch(error => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取策略文件失败"),
]),
})
})
// get_vt_symbols().then(res => {
// console.log(res)
// }).catch(error => {
// ElMessage({
// message: h('p', null, [
// h('i', { style: 'color: teal' }, "读取vt_symbols失败"),
// ]),
// })
// })
}
// init process
init()
</script>
+4 -3
View File
@@ -3,14 +3,15 @@
<el-upload ref="upload" class="upload-demo" action="http://localhost:5000/trader/api/v1/strategy_file" :limit="1"
:on-exceed="handleExceed" :auto-upload="false">
<template #trigger>
<el-button type="primary">select file</el-button>
<el-button type="primary">添加策略文件</el-button>
</template>
->
<el-button class="ml-3" type="success" @click="on_upload">
upload to server
上传策略文件
</el-button>
<template #tip>
<div class="el-upload__tip text-red">
limit 1 file, new file will cover the old file
一次只能上传一个文件
</div>
</template>
</el-upload>
+144
View File
@@ -0,0 +1,144 @@
<template>
<div class="strategy_form">
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="140px" class="strategy-ruleForm"
:size="formSize" status-icon>
<el-form-item label="strategy_name" prop="strategy_name">
<el-input v-model="ruleForm.strategy_name" placeholder="demo_strategy_symbol" />
</el-form-item>
<el-form-item label="vt_symbol" prop="vt_symbol">
<el-select v-model="ruleForm.vt_symbol" placeholder="select a vt_symbol">
<el-option v-for="vt_symbol in store.vt_symbols" :value="vt_symbol" />
</el-select>
</el-form-item>
<el-form-item label="class_name" prop="class_name">
<el-select v-model="ruleForm.class_name" placeholder="select a class_name">
<el-option v-for="name in store.class_names" :value="name" />
</el-select>
</el-form-item>
<el-form-item label="setting:">
</el-form-item>
<el-form-item label="" prop="setting">
<el-select v-model="ruleForm.setting.interval" placeholder="select a interval">
<el-option label="interval:1DAILY" value=24 />
<el-option label="interval:4HOUR" value=240 />
<el-option label="interval:1HOUR" value=60 />
<el-option label="interval:30MIN" value=30 />
<el-option label="interval:15MIN" value=15 />
<el-option label="interval:5MIN" value=5 />
<el-option label="interval:1MIN" value=1 />
</el-select>
</el-form-item>
<!-- <el-form-item label="" prop="name">
<el-input v-model="ruleForm.name" placeholder="Please input">
<template #prepend>interval:</template>
</el-input>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">Create</el-button>
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { create_strategy } from '../../api/cta_strategy'
import { h } from 'vue'
import { ElMessage } from 'element-plus'
import { strategyStore } from '../../store/strategy'
const store = strategyStore()
const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
strategy_name: '',
class_name: '',
vt_symbol: '',
setting: {
interval: '',
},
})
const clear_form = () => {
ruleForm.strategy_name = ''
ruleForm.class_name = ''
ruleForm.vt_symbol = ''
ruleForm.setting.interval = ''
}
defineExpose({
clear_form
})
const rules = reactive<FormRules>({
strategy_name: [
{ required: true, message: 'Please input strategy name', trigger: 'blur' },
{ min: 8, max: 30, message: 'Length should be 8 to 30', trigger: 'blur' },
],
interval: [
{
required: true,
message: 'Please select interval',
trigger: 'change',
},
],
class_name: [
{
required: true,
message: 'Please select class_name'
},
],
vt_symbol: [
{
required: true,
message: 'Please select vt_symbol'
},
],
})
const emit = defineEmits(['on-create'])
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
create_strategy(ruleForm).then(res => {
emit('on-create')
})
} else {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, 'error submit!' + fields),
]),
})
}
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
</script>
<style scoped>
.el-button--text {
margin-right: 15px;
}
.el-select {
width: 300px;
}
.el-input {
width: 300px;
}
.dialog-footer button:first-child {
margin-right: 10px;
}
</style>