vnpy/examples/WebTrader/templates/index.html
2018-02-15 14:43:14 +08:00

1067 lines
56 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcss.com/socket.io/2.0.4/socket.io.slim.js"></script>
<link href="https://cdn.bootcss.com/element-ui/2.0.11/theme-chalk/index.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
</head>
<body>
<div id="app">
<el-dialog title="请登录" :visible.sync="LoginFormVisible" :close-on-click-modal="false" :show-close ="false" :lock-scroll="true">
<el-form :model="loginForm">
<el-form-item label="用户名" :label-width="formLabelWidth">
<el-input v-model="loginForm.user" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="密码" :label-width="formLabelWidth">
<el-input v-model="loginForm.pwd" auto-complete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="onLogin">确 定</el-button>
</div>
</el-dialog>
<template>
<el-tabs v-model="activeTab" @tab-click="handleTab">
<el-tab-pane label="交易" name="home">
<el-container style="margin-top: 12px;">
<el-aside class="leftTrade" :style="{ height: leftTradeHeight, width:'320px'}">
<el-row>
<el-form class="el-col el-col el-col-24" ref="form" :model="form" label-width="50px" show-message="true" inline-message="true" validate="formValidate">
<div class="el-form-item">
<label class="el-form-item__label" style="width: 50px;">代码</label>
<div class="el-form-item__content" style="margin-left: 50px;">
<div class="el-input--suffix el-input el-input-group el-input-group--append">
<input autocomplete="off" type="text" rows="2" validateevent="true" clearable="true" class="el-input__inner" @keyup.enter="onSubscribe" v-model="form.vtSymbol">
<div class="el-input-group__append">
<button type="button" class="el-button el-button--default" @click="onSubscribe">
<!-- <i class="el-icon-plus"></i> -->订阅</button>
</div>
</div>
<p>卖五</p>
</div>
</div>
<!-- <el-form-item label="代码">
<el-input class="el-input--suffix" clearable @keyup.enter="enter" v-model="form.vtSymbol">
<el-button slot="append" @click="onSubscribe" v-loading="loading.subScribe" icon="el-icon-plus"></el-button>
</el-input>
<p>卖五</p>
</el-form-item> -->
<!--<el-form-item label="名称">
<el-input class="el-input--suffix" v-model="form.name"></el-input>
<p>卖四</p>
</el-form-item> -->
<el-form-item label="方向类型">
<el-select v-model="form.direction" placeholder="请选择">
<el-option label="多" value="DIRECTION_LONG"></el-option>
<el-option label="空" value="DIRECTION_SHORT"></el-option>
</el-select>
<p>卖三</p>
</el-form-item>
<el-form-item label="开平">
<el-select v-model="form.offset" placeholder="请选择">
<el-option label="开仓" value="OFFSET_OPEN"></el-option>
<el-option label="平仓" value="OFFSET_CLOSETODAY"></el-option>
<el-option label="平昨" value="OFFSET_CLOSEYESTERDAY"></el-option>
<el-option label="平今" value="OFFSET_CLOSETODAY"></el-option>
</el-select>
<p>卖二</p>
</el-form-item>
<el-form-item label="价格">
<el-input class="el-input--suffix" v-model="form.lastPrice"></el-input>
<p>卖一 {{leftTrade.askPrice1}} {{leftTrade.askVolume1}}</p>
</el-form-item>
<el-form-item label="数量">
<el-input-number :min="1" class="el-input--suffix" v-model="form.volume"></el-input-number>
<p>最新 {{leftTrade.lastPrice}} {{leftTrade.priceRatio}}</p>
</el-form-item>
<el-form-item label="价格类型">
<el-select v-model="form.priceType" placeholder="请选择">
<el-option label="限价" value="PRICETYPE_LIMITPRICE"></el-option>
<el-option label="市价" value="PRICETYPE_MARKETPRICE"></el-option>
<el-option label="FAK" value="PRICETYPE_FAK"></el-option>
<el-option label="FOK" value="PRICETYPE_FOK"></el-option>
</el-select>
<p>买一 {{leftTrade.bidPrice1}} {{leftTrade.bidVolume1}}</p>
</el-form-item>
<!--<el-form-item label="交易接口">
<el-select v-model="form.region" placeholder="请选择">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
<p>买二</p>
</el-form-item>-->
</el-form>
</el-row>
<el-row class="body-left__btn">
<div class="el-col el-col-18">
<el-button class="el-col el-col-24" type="primary" @click="onSubmit" v-loading="loading.order">发单</el-button>
<el-button class="el-col el-col-24" @click="dAllOrder">全撤</el-button>
<el-button class="el-col el-col-24" v-loading="loading.token" @click="gGateway">连接CTP</el-button>
</div>
</el-row>
<el-row class="body-left__connection">
<div>服务器连接:
<p>{{connection}}</p>
</div>
</el-row>
</el-aside>
<el-main>
<el-row :gutter="10">
<el-col :span="24">
<template>
<el-table :data="eTick" :height="table_height" @cell-click="clickTick" border style="width: 100%">
<el-table-column sortable fixed prop="symbol" width="80" label="合约代码">
</el-table-column>
<!--<el-table-column sortable prop="available" label="名称">
</el-table-column>-->
<el-table-column sortable prop="lastPrice" label="最新价">
</el-table-column>
<el-table-column sortable prop="preClosePrice" label="昨收盘">
</el-table-column>
<el-table-column sortable prop="volume" label="成交量">
</el-table-column>
<el-table-column sortable prop="openInterest" label="持仓量">
</el-table-column>
<el-table-column sortable prop="openPrice" label="开盘价">
</el-table-column>
<el-table-column sortable prop="highPrice" label="最高价">
</el-table-column>
<el-table-column sortable prop="lowPrice" label="最低价">
</el-table-column>
<el-table-column sortable prop="bidPrice1" label="买一价">
</el-table-column>
<el-table-column sortable prop="bidVolume1" label="买一量">
</el-table-column>
<el-table-column sortable prop="askPrice1" label="卖一价">
</el-table-column>
<el-table-column sortable prop="askVolume1" label="卖一量">
</el-table-column>
<el-table-column sortable prop="date" label="日期">
</el-table-column>
<el-table-column sortable prop="gatewayName" label="接口">
</el-table-column>
</el-table>
</template>
</el-col>
<el-col :span="24">
<template>
<el-table :data="order" :height="table_height" border @cell-dblclick="dOrder">
<el-table-column fixed sortable prop="orderID" width="80" label="委托编号">
</el-table-column>
<el-table-column sortable width="80" prop="symbol" label="合约代码">
</el-table-column>
<!--<el-table-column sortable width="80" prop="name" label="名称">
</el-table-column>-->
<el-table-column sortable width="80" prop="direction" label="方向">
</el-table-column>
<el-table-column sortable width="80" prop="offset" label="开平">
</el-table-column>
<el-table-column sortable width="80" prop="price" label="价格">
</el-table-column>
<el-table-column sortable width="80" prop="totalVolume" label="委托数量">
</el-table-column>
<el-table-column sortable width="80" prop="tradedVolume" label="成交数量">
</el-table-column>
<el-table-column sortable width="80" prop="status" label="委托状态">
</el-table-column>
<el-table-column sortable prop="address" label="委托时间">
</el-table-column>
<el-table-column sortable prop="cancelTime" label="撤销时间">
</el-table-column>
<el-table-column sortable width="80" prop="gatewayName" label="接口">
</el-table-column>
</el-table>
</template>
</el-col>
<el-col :span="24">
<el-row :gutter="10">
<el-col :span="12">
<template>
<el-tabs v-model="activeTabLeft" type="card" @tab-click="handleTabLeft">
<el-tab-pane label="成交" name="trade">
<el-table :data="trade" :height="table_height" border style="width: 100%">
<el-table-column fixed sortable width="80" prop="tradeID" label="成交编号">
</el-table-column>
<el-table-column sortable width="80" prop="orderID" label="委托编号">
</el-table-column>
<el-table-column sortable width="80" prop="symbol" label="合约代码">
</el-table-column>
<!--<el-table-column sortable width="80" prop="askPrice3" label="名称">
</el-table-column>-->
<el-table-column sortable width="80" prop="direction" label="方向">
</el-table-column>
<el-table-column sortable width="80" prop="offset" label="开平">
</el-table-column>
<el-table-column sortable width="80" prop="price" label="价格">
</el-table-column>
<el-table-column sortable width="80" prop="volume" label="成交量">
</el-table-column>
<el-table-column sortable width="80" prop="tradeTime" label="成交时间">
</el-table-column>
<el-table-column sortable width="80" prop="gatewayName" label="接口">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="错误" name="error">
<el-table :data="error" :height="table_height" border style="width: 100%">
<el-table-column sortable prop="errorTime" width="80" label="错误时间">
</el-table-column>
<el-table-column sortable width="80" prop="errorID" label="错误代码">
</el-table-column>
<el-table-column sortable width="80" prop="gatewayName" label="接口">
</el-table-column>
<el-table-column sortable prop="errorMsg" label="错误信息">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="日志" name="log">
<el-table :data="log" :height="table_height" border style="width: 100%">
<el-table-column fixed width="80" sortable prop="logTime" label="时间">
</el-table-column>
<el-table-column sortable prop="logContent" label="内容">
</el-table-column>
<el-table-column sortable width="140" prop="gatewayName" label="接口">
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</template>
</el-col>
<el-col :span="12">
<template>
<el-tabs v-model="activeTabRight" type="card" @tab-click="handleTabLeft">
<el-tab-pane label="持仓" name="position">
<el-table :data="position" :height="table_height" border style="width: 100%">
<el-table-column fixed sortable prop="symbol" width="80" label="合约代码">
</el-table-column>
<!--<el-table-column sortable width="80" prop="" label="名称">
</el-table-column>-->
<el-table-column sortable width="80" prop="direction" label="方向">
</el-table-column>
<el-table-column sortable width="80" prop="position" label="持仓">
</el-table-column>
<el-table-column sortable width="80" prop="ydPosition" label="昨持仓">
</el-table-column>
<el-table-column sortable width="80" prop="frozen" label="冻结量">
</el-table-column>
<el-table-column sortable width="80" prop="price" label="价格">
</el-table-column>
<el-table-column sortable width="80" prop="gatewayName" label="持仓盈亏">
</el-table-column>
<el-table-column sortable width="80" prop="askPrice3" label="接口">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="资金" name="money">
<el-table :data="account" :height="table_height" width="80" border style="width: 100%">
<el-table-column fixed sortable width="80" prop="accountID" label="账户">
</el-table-column>
<el-table-column sortable width="80" prop="preBalance" label="昨结">
</el-table-column>
<el-table-column sortable width="80" prop="balance" label="净值">
</el-table-column>
<el-table-column sortable width="80" prop="available" label="可用">
</el-table-column>
<el-table-column sortable width="80" prop="commission" label="手续费">
</el-table-column>
<el-table-column sortable width="80" prop="margin" label="保证金">
</el-table-column>
<el-table-column sortable width="80" prop="closeProfit" label="平仓盈亏">
</el-table-column>
<el-table-column sortable width="80" prop="positionProfit" label="持仓盈亏">
</el-table-column>
<el-table-column sortable width="80" prop="gatewayName" label="接口">
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</template>
</el-col>
</el-row>
</el-col>
</el-row>
</el-main>
</el-container>
</el-tab-pane>
<el-tab-pane label="查询" name="search" v-loading="loading.contract">
<template>
<el-table :data="contract" stripe :height="window.innerHeight" style="width: 100%">
<el-table-column prop="symbol" label="合约代码"></el-table-column>
<el-table-column prop="exchange" label="交易所"></el-table-column>
<el-table-column prop="vtSymbol" label="vt系统代码"></el-table-column>
<el-table-column prop="name" label="日期"></el-table-column>
<el-table-column prop="productClass" label="合约类型"></el-table-column>
<el-table-column prop="size" label="大小"></el-table-column>
<el-table-column prop="priceTick" label="最小价格变动"></el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">订阅</el-button>
</template>
</el-table-column>
</el-table>
</template>
</el-tab-pane>
<el-tab-pane label="CTA" name="cta">
<el-main style="padding:8px 0px;">
<el-row>
<el-col :span='24'>
<el-button type="primary" plain @click="doOnLoad">加载策略</el-button>
<el-button type="success" plain @click="doAction('','init')">全部初始化</el-button>
<el-button type="danger" plain @click="doAction('','start')">全部启动</el-button>
<el-button type="warning" plain @click="doAction('','stop')">全部停止</el-button>
<!--<el-button type="info" plain>保持持仓</el-button>-->
</el-col>
<el-col :span='24' class="cta-frame cta-frame__top" :style="{ height: topFrame}" v-loading="loading.strategy">
<div class="cta-frame__top_section" v-for="item,index in strategy">
<div class="itemName">{{item.name}}</div>
<el-button size="mini" :id="item.name" round @click="doAction(item.name,'init')">初始化</el-button>
<el-button size="mini" round @click="doAction(item.name,'start')">启动</el-button>
<el-button size="mini" round @click="doAction(item.name,'stop')">停止</el-button>
<template>
<el-table :data="[item.par]" stripe style="width: 100%; margin-bottom: 12px;">
<el-table-column :pro="subindex" :label="subindex" v-for="(subitem, subindex) in item.par" width="120">
<template scope="scope">
{{[item.par][scope.$index][subindex]}}
</template>
</el-table-column>
</el-table>
</template>
<template>
<el-table :data="[item.var]" stripe style="width: 100%">
<el-table-column :pro="subindex" :label="subindex" v-for="(subitem, subindex) in item.var" width="120">
<template scope="scope">
{{[item.var][scope.$index][subindex]}}
</template>
</el-table-column>
</el-table>
</template>
</div>
</el-col>
<el-col :span='24' :style="{ height: topFrame}">
<el-table :data="ctaLog" height="200" border style="width: 100%">
<el-table-column fixed width="120" sortable prop="logTime" label="时间">
</el-table-column>
<el-table-column prop="logContent" label="内容">
</el-table-column>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-main>
</el-tab-pane>
</el-tabs>
</template>
</div>
</body>
<!-- 先引入 Vue -->
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
<!-- 引入组件库 -->
<script src="https://cdn.bootcss.com/element-ui/2.1.0/index.js"></script>
<script>
var host = window.location;
var socket = io.connect(host + "", { transports: ['websocket'] });
var _strategy = new Object()
function sortTime(a, b) {
return b.logTime.replace(/:/g,"") - a.logTime.replace(/:/g,"")
}
function sortVtOrderID(a, b) {
return parseInt(b.match(/[0-9]*/g).join("")) - parseInt(a.match(/[0-9]*/g).join(""))
}
new Vue({
el: '#app',
data: function() {
return {
table_height: (window.innerHeight - 70) / 3 - 15 || 250,
winHeight: window.innerHeight,
topFrame: window.innerHeight * 2 / 3 - 65 + "px",
bottomFrame: window.innerHeight / 3 - 65 + "px",
leftTradeHeight: (window.innerHeight - 50) + 'px',
selected_data: [],
form: {
volume: 1,
vtSymbol: '',
lastPrice: '',
direction: '',
offset: '',
priceType: '',
},
loginForm: {
user: "",
pwd: ""
},
LoginFormVisible: true,
formLabelWidth: '120px',
eAccount: [],
eTick: [],
tickObj: {},
eContract: [],
connection: '未连接',
activeTab: "home",
activeTabLeft: 'trade',
activeTabRight: 'position',
log: [], //日志
position: [], //持仓
order: [], //委托
orderObj: {}, //委托对象
trade: [], //成交
account: [], //资金
error: [], //错误
contract: [], //合约查询结果
leftTrade: {}, //存放左侧交易区显示数据
config: {}, //存放token等数据
strategy: {}, //策略名
ctaLog: [],
loading: {
subScribe: false,
order: false,
contract: false,
strategy: false,
token: false,
},
}
},
created: function() {
this.gAccount()
this.gConnectionStatus()
this.gTick()
this.gLog()
this.gPosition()
this.gError()
this.gOrder()
this.gTrade()
},
methods: {
onLogin() {
console.log(this.loginForm.user)
let userName = this.loginForm.user,
pwd = this.loginForm.pwd;
this.gToken(userName, pwd)
},
gToken(username, password) {
const that = this;
that.loading.token = true;
axios.get(host + '/token?username=' + username + '&password=' + password)
.then(function(res) {
that.loading.token = false;
if (res.status == 200 && res.data.result_code == "success") {
that.$message({ message: '已登录', type: 'success' });
that.config.token = res.data.data
that.LoginFormVisible = false
that.onLoadInfo('account', 'account')
that.onLoadInfo('trades', 'trade')
that.onLoadInfo('position', 'position')
that.onLoadInfo('order', 'order')
that.onLoadInfo('log', 'log')
that.onLoadInfo('error', 'error')
} else {
that.$notify({ title: '警告', message: 'token获取失败用户名或密码错误', type: 'warning', duration: 0, });
}
})
.catch(function(err) {
that.loading.token = false;
that.$notify({ title: '警告', message: 'token获取失败连接错误', type: 'warning', duration: 0, });
});
},
doAction(e, type) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
let name = e,
that = this,
info = "";
switch (type) {
case "init":
info = "初始化"
break;
case "stop":
info = "停止"
break;
case "start":
info = "启动"
break;
}
axios.post(host + "/ctastrategy/" + type, {
name: name,
token: this.config.token
})
.then(res => {
if (res.data.result_code == "success") {
that.$message({ message: name + info + '成功', type: 'success' });
if (type == "start") {
that.gCtaStrategy()
}
} else {
that.$message({ message: name + info + '成功', type: 'fail' });
}
})
.catch(res => {
that.$message({ message: name + info + '成功', type: 'fail' });
})
},
doOnLoad() {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
const that = this;
let strategy = {};
that.loading.strategy = true;
axios.post(host + '/ctastrategy/load', {
token: this.config.token
})
.then(res => {
if (res.data.result_code !== "success") {
that.$notify({ title: '警告', message: 'ctastrategy/load接口报错', type: 'warning', duration: 0, });
return;
} else {
let strategy = res.data.data;
strategy.forEach((item) => {
_strategy[item] = { name: item };
that.gParams(item)
that.gVar(item)
})
}
})
},
gVar(name) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
const that = this,
_var = new Object();
axios.get(host + "/ctastrategy/var?name=" + name + "&token=" + this.config.token)
.then(res => {
if (res.data.result_code !== "success") {
that.$notify({ title: '警告', message: 'ctastrategy/var接口报错', type: 'warning', duration: 0, });
return;
} else {
_strategy[name]['var'] = res.data.data;
that.strategy = _strategy;
that.loading.strategy = false;
}
})
.catch(res => {
that.$notify({ title: '警告', message: 'ctastrategy/var接口报错', type: 'warning', duration: 0, });
})
},
gCtaStrategy() {
let that = this;
socket.on("eCtaStrategy.", function(data) {
let name = data.name;
delete data['name'];
that.strategy[name]['var'] = data;
});
},
gCtaLog() {
let that = this,
logObj = new Object();
socket.on("eCtaLog", function(data) {
logObj[data.logTime] = data
let dataArr = that.ctaLog.concat(Object.values(logObj));
dataArr.sort(sortTime)
that.ctaLog = dataArr;
});
},
gParams(name) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
const that = this;
axios.get(host + "/ctastrategy/param?name=" + name + "&token=" + this.config.token)
.then(res => {
if (res.data.result_code !== "success") {
that.$notify({ title: '警告', message: 'ctastrategy/param接口报错', type: 'warning', duration: 0, });
return;
} else {
_strategy[name]['par'] = res.data.data;
that.strategy = _strategy;
that.loading.strategy = false;
}
})
.catch(res => {
that.$notify({ title: '警告', message: 'ctastrategy/param接口报错', type: 'warning', duration: 0, });
})
},
onLoadInfo(apiName, dataArr) {
const that = this;
if (this.config.token !== undefined) {
gInfo(apiName, this.config.token)
} else {
axios.get(host + '/token?username=test&password=test', {
})
.then(function(res) {
if (res.status == 200 && res.data.result_code == "success") {
let token = res.data.data
gInfo(apiName, token)
} else {
that.$notify({ title: '警告', message: 'token获取失败', type: 'warning', duration: 0, });
}
})
.catch(function(res) {
that.$notify({ title: '警告', message: 'token获取失败', type: 'warning', duration: 0, });
});
}
function gInfo(apiName, token) {
axios.get(host + "/" + apiName + "?token=" + token)
.then(res => {
if (res.data.result_code == "success") {
if (apiName == "order") {
res.data.data.forEach((item)=>{
item["_vtOrderID"] = item.vtOrderID.replace(/\./g,"")
that.orderObj[item._vtOrderID] = item;
})
sorted_order_list = Object.keys( that.orderObj ).sort( sortVtOrderID );
for(i in sorted_order_list){
that.order.push( that.orderObj[sorted_order_list[i]] );
}
}
else{
that[dataArr] = that[dataArr].concat(res.data.data).reverse()
}
} else {
that.$notify({ title: '警告', message: '服务异常获取信息失败1', type: 'warning', duration: 3000, });
}
})
.catch(res => {
that.$notify({ title: '警告', message: '服务异常获取信息失败2', type: 'warning', duration: 3000, });
})
}
},
onSubmit(e) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.vtSymbol == "") {
this.$alert('请填写代码!', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.lastPrice == "") {
this.$alert('请填写价格!', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.volume == "") {
this.$alert('请填写数量!', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.priceType == "") {
this.$alert('请选择价格类型!', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.direction == "") {
this.$alert('请选择方向类型!', '警告', {confirmButtonText: '确定',});
return;
}
if (this.form.offset == "") {
this.$alert('请选择开平!', '警告', {confirmButtonText: '确定',});
return;
}
this.loading.order = true;
const that = this;
axios.post(host + '/order', {
vtSymbol: this.form.vtSymbol,
price: this.form.lastPrice,
volume: this.form.volume,
priceType: this.form.priceType,
direction: this.form.direction,
offset: this.form.offset,
token: this.config.token,
})
.then(function(res) {
that.loading.order = false;
if (res.data.result_code == "success") {
that.$message({ message: '发单成功', type: 'success' });
} else {
that.$notify({ title: '警告', message: '服务异常,发单失败', type: 'warning', duration: 3000, });
}
})
.catch(function(err) {
that.loading.order = false;
that.$notify({ title: '警告', message: '服务异常,发单失败', type: 'warning', duration: 3000, });
});
},
onSubscribe(target) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
const that = this;
if (typeof(target) !== "object") {
var _vtSymbol = target
} else {
var _vtSymbol = this.form.vtSymbol
}
if (this.config.token == undefined || this.config.token == "") {
this.gToken()
}
if (_vtSymbol == undefined || _vtSymbol == "") {
return this.$alert('请输入代码', '提示', {
confirmButtonText: '确定',
});
} else {
this.loading.subScribe = true;
axios.post(host + "/tick", {
vtSymbol: _vtSymbol,
token: this.config.token
})
.then(res => {
that.loading.subScribe = false;
if (res.data.result_code == "success") {
let target = _vtSymbol
that.clickTick(target)
that.form.vtSymbol = target;
that.$message({ message: '订阅成功', type: 'success' });
} else {
that.$notify({ title: '警告', message: '订阅失败', type: 'warning', duration: 3000, });
}
})
.catch(res => {
that.loading.subScribe = false;
that.$notify({ title: '警告', message: '服务异常,订阅失败', type: 'warning', duration: 3000, });
})
}
},
dOrder(e) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
console.log(e.vtOrderID);
let vtOrderID = e.vtOrderID,
that = this;
axios.delete(host + "/order?vtOrderID=" + vtOrderID + "&token=" + this.config.token)
.then(res => {
if (res.data.result_code == "success") {
that.$message({ message: '撤单已提交', type: 'success' });
} else {
that.$notify({ title: '警告', message: '服务异常,撤单提交失败', type: 'warning', duration: 2000, });
}
})
.catch(res => {
that.$notify({ title: '警告', message: '服务异常,撤单提交失败', type: 'warning', duration: 2000, });
})
},
dAllOrder(e) {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
console.log(e.vtOrderID);
let vtOrderID = "",
that = this;
axios.delete(host + "/order?vtOrderID=" + vtOrderID + "&token=" + this.config.token)
.then(res => {
if (res.data.result_code == "success") {
that.$message({ message: '撤单已提交', type: 'success' });
} else {
that.$notify({ title: '警告', message: '服务异常,撤单提交失败', type: 'warning', duration: 2000, });
}
})
.catch(res => {
that.$notify({ title: '警告', message: '服务异常,撤单提交失败', type: 'warning', duration: 2000, });
})
},
handleClick(row) {
this.onSubscribe(row.vtSymbol)
},
handleTab(tab) {
const that = this;
that.loading.contract = true;
if (tab.name == "search") {
this.gContract()
} else if (tab.name == "cta") {
this.judgeIfStrategy()
this.gCtaLog()
}
},
judgeIfStrategy() {
if (this.config.token == undefined || this.config.token == "") {
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
let that = this;
axios.get(host + "/ctastrategy/name?token=" + this.config.token)
.then(res => {
let nameArray = res.data.data;
nameArray.forEach(function(item) {
_strategy[item] = { name: item };
that.gParams(item)
that.gVar(item)
})
})
.catch(res => {
that.$notify({ title: '警告', message: '连接异常', type: 'warning', duration: 4500, });
})
},
gContract() {
if (this.config.token == undefined || this.config.token == "") {
this.loading.contract = false;
this.$alert('请先登录', '警告', {confirmButtonText: '确定',});
return;
}
if (this.config.gateway == undefined || this.config.gateway == "") {
this.loading.contract = false;
this.$alert('请先连接CTP', '警告', {confirmButtonText: '确定',});
return;
}
const that = this;
if (that.contract.length == 0) {
axios.get(host + "/contract?token=" + this.config.token)
.then(res => {
that.loading.contract = false;
if (res.data.result_code == "success") {
that.contract = res.data.data
} else {
that.$notify({ title: '警告', message: '连接异常', type: 'warning', duration: 4500, });
}
})
.catch(res => {
that.$notify({ title: '警告', message: '连接异常', type: 'warning', duration: 4500, });
})
}
},
gGateway() {
const that = this;
axios.post(host + '/gateway', {
token: this.config.token,
gatewayName: 'CTP'
})
.then(function(res) {
that.config.gateway = true;
that.$message({ message: '已连接CTP', type: 'success' });
})
.catch(function(err) {
console.log("res",err)
});
},
gTick(target) {
let that = this,
tick = new Object(),
tickObj = new Object();
socket.on("eTick.", function(data) {
tick[data.vtSymbol] = data
that.tickObj = tick
that.eTick = Object.values(tick).reverse()
});
},
clickTick(e) {
let that = this,
tick = new Object(),
tickObj = new Object(),
target = e.vtSymbol || e;
if (that.tickObj[target] !== undefined) {
that.form.lastPrice = that.tickObj[target].lastPrice
}
that.form.vtSymbol = target
socket.on("eTick.", function(data) {
that.leftTrade = that.tickObj[target]
that.leftTrade.priceRatio = (((that.tickObj[target].lastPrice / that.tickObj[target].preClosePrice) - 1)*100.0).toFixed(2) + "%"
// if (that.tickObj[target] !== undefined) {
// if (that.tickObj[target].lastPrice == undefined) {
// that.form.lastPrice = that.tickObj[target].lastPrice
// }
// }
});
},
gOrder() {
let that = this,
orderObj = new Object();
socket.on("eOrder.", function(data) {
console.log( data );
data["_vtOrderID"] = data.vtOrderID.replace(/\./g,"")
that.orderObj[data._vtOrderID] = data;
sorted_order_list = Object.keys( that.orderObj ).sort( sortVtOrderID );
console.log( sorted_order_list );
order_tmp = []
for(i in sorted_order_list){
order_tmp.push( that.orderObj[sorted_order_list[i]] );
}
that.order = order_tmp
console.log( that.order )
});
},
gAccount() {
let that = this,
accounts = new Object();
socket.on("eAccount.", function(data) {
accounts[data.vtAccountID] = data
that.account = Object.values(accounts).reverse()
});
},
gPosition() {
let that = this,
positions = new Object();
socket.on("ePosition.", function(data) {
positions[data.vtSymbol] = data
that.position = Object.values(positions).reverse()
});
},
gTrade() {
let that = this,
trades = new Object();
socket.on("eTrade.", function(data) {
trades[data.vtOrderID] = data
that.trade = that.trade.concat(Object.values(trades)).reverse()
});
},
gError() {
let that = this,
errObj = new Object();
socket.on("eError.", function(data) {
errObj[data.errorTime] = data
that.error = that.error.concat(Object.values(errObj)).reverse()
// that.error = Object.values(errObj).reverse()
});
},
gLog() {
let that = this,
logObj = new Object();
socket.on("eLog", function(data) {
logObj[data.logTime] = data
that.log = that.log.concat(Object.values(logObj)).reverse()
});
},
handleTabLeft(tab, event) {},
handleTabRight(tab, event) {},
gConnectionStatus() {
const that = this;
socket.on('disconnect', function() {
that.connection = '已断开'
that.$notify({
title: '警告',
message: '服务器连接已断开',
type: 'warning',
duration: 4500,
});
});
socket.on('connect_failed', function() {
that.connection = '连接失败'
that.$notify({
title: '警告',
message: '服务器连接失败',
type: 'warning',
duration: 4500,
});
});
socket.on('connect', function() {
that.connection = '已连接'
that.$notify({
title: '成功',
message: '服务器连接成功',
type: 'success',
duration: 2000,
});
});
socket.on('connecting', function() {
that.connection = '正在连接'
});
socket.on('error', function() {
that.connection = '连接错误'
that.$notify({
title: '警告',
message: '服务器连接错误',
type: 'warning',
duration: 4500,
});
});
},
}
})
</script>
</html>