-
为什么要写这个策略代码呢?
原因很简单,在平时测试托管者功能的时候,每次要对 BotVS 各个 API 进行测试。每次的测试代码很大程度上类似,干脆就写个 测试策略吧。写好以后,感觉不仅可以测试托管者。同样对于 初识 BotVS量化平台的 新同学 在学习使用商品期货 仿真账户 或者 实盘的时候也是个很好的工具。
-
用途:
如上所述,该策略仅仅是为了方便BotVS新用户快速熟悉 BotVS 商品期货程序化交易,测试模拟账户、实盘账户下单 等功能 。透过对该策略的源代码的剖析和学习也可以学习到 策略编写方面的一些技巧、经验。
那么简单介绍下吧!
-
显示UI
UI
-
策略参数
参数参数很简单,只有2个,第一个是 程序轮询间隔 (BotVS 策略是轮询架构的),该参数可以控制每次轮询后暂停多少毫秒,防止策略访问 交易所过于频繁。第二个参数就是 合约代码了,默认的是 rb1801 即 :螺纹钢1801合约
-
交互
交互交互就是 策略使用时主要用到的 功能了。
-
修改合约
changeSymbol
可以在该交互控件 中填写 合约代码,如填写 MA801 ,后点击 changeSymbol 就可以将 策略中当前的合约代码 比如 rb1801 切换成 MA801。
-
开当前合约 多单:
编辑框写上开仓手数,点击 OPEN_LONG 按钮就会 进行开多仓操作。
-
开空 同理不赘述
-
按数量平仓:
点击 COVER 就会按编辑框写入的 数量平仓,如果 此时 同时持有多头和空头仓位,会随机先平 一边,如果平仓数量大于一边的数量,会平完后,按剩余的计划数量继续平仓另一边。(鉴于测试的时候同时持有多空的情况不多,所以平仓没有单独写)
-
获取当前合约合约未完成的订单:
点击后在日志 显示区域会 显示出 未完成的订单(挂单状态) -
获取当前合约指定ID的订单
可以 传入 一个 ID 获取 该ID 的订单
-
获取当前合约持仓信息:
获取当前的合约的持仓。
-
获取所有合约持仓信息:
获取所有持仓信息 列表 (数组形式)
-
取消订单:
编辑框 写入 要取消的订单的 ID 号 ,点击 CANCEL_ORDER 就可以取消挂单。
-
调用JS 代码 ,可以在编辑框内写 要执行的 JS 代码, 点击 按钮 JS_CODE 就可以执行。
-
源码:
// 商品期货 测试 程序
/*
1、 行情部分测试
2、 交易 测试
3、 交互界面
*/
// var _Interval = 500
// var _StrContractType = "rb1801"
//
var CONNECTED = 1
var NOTCONNECTED = 2
var _TableObj = {
type : "table",
title : "test",
cols : ["value"],
rows : [],
}
var _templeteObj = null
// var _isFirst = true
var _chart = null // 配置对象 ,并非控制对象
var _chartObj = null
var _LogStatusMessage = ""
function E(obj) {
if(!obj){
return obj
}
var cloneObj = function(obj) { // 深拷贝 对象函数
var str, newobj = obj.constructor === Array ? [] : {};
if (typeof obj !== 'object') {
return;
} else if (JSON) {
str = JSON.stringify(obj); //系列化对象
newobj = JSON.parse(str); //还原
} else {
for (var i in obj) {
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
}
if(obj && typeof(obj) == "object" && typeof(obj.Info) !== "undefined"){
var newObj = cloneObj(obj)
delete newObj.Info
return newObj
}else if(typeof(obj.length) == "number"){
///*
var newArray = []
for(var n = 0; n < obj.length; n++){
newArray.push(E(obj[n]))
}
return newArray
//*/
/*
var newObj = cloneObj(obj)
delete newObj.Info
return newObj
*/
}else{
// Log(obj, "is not object or not have attribute 'Info'")
return obj
}
}
function onTick(symbol){
if(!$.IsTrading(symbol)){
_LogStatusMessage = symbol + " 不在交易时间段内!" + "#FF0000"
return
}else{
_LogStatusMessage = symbol + " 在交易时间段!"
}
var contractTypeInfo = exchange.SetContractType(symbol)
if(!contractTypeInfo){
return
}
var account = exchange.GetAccount()
var ticker = exchange.GetTicker()
var records = exchange.GetRecords()
var depth = exchange.GetDepth()
if(!account || !ticker || !depth || !records || records.length < 2){
return
}
_TableObj.rows = [] // 每次清空
_TableObj.rows.push([JSON.stringify(E(contractTypeInfo))])
_TableObj.rows.push([JSON.stringify(E(account))])
_TableObj.rows.push([JSON.stringify(E(ticker))])
_TableObj.rows.push([JSON.stringify(E(records[records.length - 1])) + JSON.stringify(E(records[records.length - 2])) + " records.length : " + records.length])
_TableObj.rows.push([JSON.stringify(E(depth.Asks[0])) + JSON.stringify(E(depth.Bids[0])) + "Asks`s length is:" + depth.Asks.length + "Bids`s length is:" + depth.Bids.length])
_chartObj = $.PlotRecords(records, "K线")
/*
if(_isFirst){
_chart.reset()
_isFirst = false
}
*/
}
function Custom_GetPositons(symbol){
var positions = exchange.GetPosition()
if(!positions){
Log("Custom_GetPositons failed", positions)
}
if(typeof(symbol) != "undefined"){
Log("PD_LONG:", E(_templeteObj.GetPosition(symbol, PD_LONG, positions)))
Log("PD_SHORT:", E(_templeteObj.GetPosition(symbol, PD_SHORT, positions)))
Log("positions:", E(positions))
}else{
Log("positions:", E(positions))
}
}
function Custom_Buy(symbol, amount){
// exchange.SetDirection("buy")
if(!$.IsTrading(symbol)){
Log(symbol, " 不在交易时间段内,禁止下单!")
return
}
var tradeInfo = _templeteObj.OpenLong(symbol, amount)
Log(tradeInfo)
}
function Custom_Pending_Buy(diffPrice, amount, direction){
if(!$.IsTrading(_StrContractType)){
Log(_StrContractType, " 不在交易时间段内,禁止下单!")
return
}
exchange.SetContractType(_StrContractType)
var ticker = _C(exchange.GetTicker)
exchange.SetDirection(direction)
var id = exchange.Buy(ticker.Last - diffPrice, amount)
Log("id:", id)
}
function Custom_Pending_Sell(diffPrice, amount, direction){
if(!$.IsTrading(_StrContractType)){
Log(_StrContractType, " 不在交易时间段内,禁止下单!")
return
}
exchange.SetContractType(_StrContractType)
var ticker = _C(exchange.GetTicker)
exchange.SetDirection(direction)
var id = exchange.Sell(ticker.Last + diffPrice, amount)
Log("id:", id)
}
function Custom_Sell(symbol, amount){
// exchange.SetDirection("sell")
if(!$.IsTrading(symbol)){
Log(symbol, " 不在交易时间段内,禁止下单!")
return
}
var tradeInfo = _templeteObj.OpenShort(symbol, amount)
Log(tradeInfo)
}
function Custom_Cover(symbol, amount){
if(!$.IsTrading(symbol)){
Log(symbol, " 不在交易时间段内,禁止下单!")
return
}
_templeteObj.Cover(symbol, amount)
}
function ChangeContractType(symbol){
_StrContractType = symbol
Log("测试 合约更改为:", _StrContractType)
Log("清空图表!", "#FF0000")
if(_chartObj){
_chartObj.reset()
$.SetPreBarTime(0)
}
}
function Custom_GetPendingOrders(symbol){
var orders = _C(exchange.GetOrders)
if(orders.length == 0){
Log(E(orders))
}
for(var i = 0 ; i < orders.length ; i++){
if(typeof(symbol) == "undefined"){
Log(E(orders[i]))
}else{
if(symbol == orders[i].ContractType){
Log(E(orders[i]))
}else if(i == orders.length - 1){
Log(E(orders))
}
}
}
}
function Custom_GetOrder(symbol, id){
_C(exchange.SetContractType, symbol)
var order = exchange.GetOrder(id)
if(!order){
Log("GetOrder failed, the order is", order)
return false
}else{
Log(E(order))
}
}
function Custom_CancelOrder(symbol, id){
Log("取消的订单 id 是:", symbol, id)
if(typeof(id) == "undefined"){
id = symbol
symbol = _StrContractType
}
if(!$.IsTrading(symbol)){
Log(symbol, " 不在交易时间段内,禁止下单!")
return
}
exchange.CancelOrder(id) // CancelOrder(orderId)
}
function main(){
LogReset()
Log("启动!")
_chart = $.GetCfg()
Chart(_chart).reset()
SetErrorFilter("login");
var connectState = null
_templeteObj = $.NewPositionManager()
while(true){
if(exchange.IO("status")){
onTick(_StrContractType)
connectState = CONNECTED
}else{
connectState = NOTCONNECTED
}
var cmd = GetCommand()
if(cmd){
Log("接收到命令:", cmd, "#0000FF")
var array_cmd = cmd.split(':')
if(array_cmd.length > 2){
for(var idx = 2; idx < array_cmd.length; idx++){
array_cmd[1] += (':' + array_cmd[idx])
}
array_cmd = [array_cmd[0], array_cmd[1]] // 重新赋值
}
if(array_cmd.length == 1){ // button
switch(array_cmd[0]){
case "GET_PNEDING" :
Custom_GetPendingOrders(_StrContractType)
break
case "GET_ALL_POSITION" :
Custom_GetPositons()
break
default :
Log("unknow command:" + array_cmd, "#FF0000")
}
}else if(array_cmd.length == 2){ // other
switch(array_cmd[0]){
case "OPEN_LONG" :
var amount = parseInt(array_cmd[1])
Custom_Buy(_StrContractType, amount)
break
case "OPEN_SHORT":
var amount = parseInt(array_cmd[1])
Custom_Sell(_StrContractType, amount)
break
case "COVER" :
var amount = parseInt(array_cmd[1])
Custom_Cover(_StrContractType, amount)
break
case "GET_ORDER" :
Custom_GetOrder(_StrContractType, array_cmd[1])
break
case "GET_POSITION" :
if(array_cmd[1] == "空"){
Custom_GetPositons(_StrContractType)
}else{
Custom_GetPositons(array_cmd[1])
}
break
case "changeSymbol" :
ChangeContractType(array_cmd[1])
break
case "CANCEL_ORDER" :
// Log("CANCEL_ORDER:", array_cmd)
Custom_CancelOrder(array_cmd[1])
break
case "JS_CODE" :
var js = cmd.split(':', 2)[1]; // 分割 返回的消息 字符串, 限制返回2个, 把索引为1的 元素 赋值给 名为js 的变量
Log("执行调试代码:", js); // 输出 执行的代码
try { // 异常检测
eval(js); // 执行 eval函数, 该函数执行传入的参数(代码)。
} catch(e) { // 抛出异常
Log("Exception", e); // 输出错误信息
}
break
default :
Log("unknow command:" + array_cmd, "#FF0000")
}
}
}
var strConnectState = connectState == CONNECTED ? "已经连接!" : "未连接!"
LogStatus(_D(), strConnectState, _LogStatusMessage, '\n`' + JSON.stringify(_TableObj) + '`' + '\n' +
'Custom_CancelOrder("", "") // symbol, id' + '\n' +
'Custom_Pending_Buy( , , "") // diffPrice, amount, direction' + '\n' +
'Custom_Pending_Sell( , , "") // diffPrice, amount, direction' + '\n' )
Sleep(_Interval)
}
}
测试 截图:
1.png 2.png 3.png
要注意 测试 自己的 账号要在 商品期货 开市时间。
策略源码地址: https://www.botvs.com/strategy/59120
BotVS 量化未来
网友评论