update
This commit is contained in:
@@ -4,10 +4,15 @@
|
||||
> 开源策略列表
|
||||
|
||||
|
||||
- [商品期货交易类库(增加下限价单功能)](https://www.botvs.com/strategy/14198)
|
||||
- [从回测数据获取K线 (商品期货版)](https://www.botvs.com/strategy/15498)
|
||||
- [图表模板](https://www.botvs.com/strategy/15524)
|
||||
- [时间转换模板](https://www.botvs.com/strategy/14517)
|
||||
- [非常简单的策略,但是很有效](https://www.botvs.com/strategy/15085)
|
||||
- [定时测试微信消息推送](https://www.botvs.com/strategy/15098)
|
||||
- [单独计算收益(代码来自zero)](https://www.botvs.com/strategy/1084)
|
||||
- [差价监控](https://www.botvs.com/strategy/1340)
|
||||
- [MACD 双向 滑动止损](https://www.botvs.com/strategy/12822)
|
||||
- [时间转换模板](https://www.botvs.com/strategy/14517)
|
||||
- [10行人品策略](https://www.botvs.com/strategy/14436)
|
||||
- [商品期货主力合约过滤](https://www.botvs.com/strategy/9837)
|
||||
- [从第三方网站获取K线 (0427更新)](https://www.botvs.com/strategy/12977)
|
||||
@@ -27,12 +32,9 @@
|
||||
- [自定义K线周期转换](https://www.botvs.com/strategy/11216)
|
||||
- [模板库使用例子](https://www.botvs.com/strategy/10991)
|
||||
- [价值0.418](https://www.botvs.com/strategy/10744)
|
||||
- [均线](https://www.botvs.com/strategy/10023)
|
||||
- [价值比例法](https://www.botvs.com/strategy/9784)
|
||||
- [传统期货差价监控 (CTP)](https://www.botvs.com/strategy/5379)
|
||||
- [期货做市高频交易策略 兼容OK/VC/796](https://www.botvs.com/strategy/1484)
|
||||
- [融资融币统计](https://www.botvs.com/strategy/8954)
|
||||
- [**********价值平均定投策略**********](https://www.botvs.com/strategy/8602)
|
||||
- [【Demo】如何利用“策略交互“动态调整策略参数](https://www.botvs.com/strategy/8379)
|
||||
- [【Demo】速度测试 websocket vs rest](https://www.botvs.com/strategy/7547)
|
||||
- [记录净资产变动情况2.0](https://www.botvs.com/strategy/8916)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
策略出处: https://www.botvs.com/strategy/15498
|
||||
策略名称: 从回测数据获取K线 (商品期货版)
|
||||
策略作者: 数·狂
|
||||
策略描述:
|
||||
|
||||
如果在策略开始时必须获取足够多的K线,使用本模板则可从BotVS的回测数据中直接获得平台的历史K线数据。
|
||||
注意:
|
||||
仅适用于实盘交易。
|
||||
作者不保证第三方数据准确性和程序正确性,仅供学习参考。
|
||||
|
||||
*/
|
||||
|
||||
$.BTRecords = function(instrument, timeframe, size, includeLastBar) {
|
||||
var info;
|
||||
var record = [];
|
||||
if (!size) size = 1;
|
||||
if (!timeframe) timeframe = 1;
|
||||
var fsize = size;
|
||||
var now = new Date();
|
||||
var to = Math.floor(now / 1000 / (timeframe * 60)) * (timeframe * 60);
|
||||
var from = to - fsize * timeframe * 60;
|
||||
do {
|
||||
try {
|
||||
info = JSON.parse(HttpQuery('https://www.botvs.com/chart/history?detail=true&symbol=' + instrument + '&resolution=' + timeframe + '&from=' + from + '&to=' + to));
|
||||
if (info && info.records) {
|
||||
info = info.records;
|
||||
} else {
|
||||
Log("获取K线时发生错误: 网络错误");
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
Log("获取K线时发生错误: 不完整的JSON数据");
|
||||
return null;
|
||||
}
|
||||
fsize = fsize * 2;
|
||||
from = to - fsize * timeframe * 60;
|
||||
} while (info.length < size + (!includeLastBar));
|
||||
for (var i = info.length - size - (!includeLastBar); i < info.length - (!includeLastBar); i++) {
|
||||
record.push({
|
||||
"Time": info[i][0]*1000,
|
||||
"Open": info[i][1],
|
||||
"High": info[i][2],
|
||||
"Low": info[i][3],
|
||||
"Close": info[i][4],
|
||||
"Volume": info[i][5]
|
||||
});
|
||||
}
|
||||
return record;
|
||||
};
|
||||
|
||||
function main() {
|
||||
Log(exchange.GetName());
|
||||
var rec = $.BTRecords('rb1610', 5, 100); // 获取螺纹钢1610的5分钟K线, 100条, 不含最后一条Bar
|
||||
if (rec) Log(rec.length, rec[rec.length - 1]);
|
||||
rec = $.BTRecords('i1609', 60, 100, true); // 获取铁矿石1609的1小时K线, 100条, 含最后一条Bar
|
||||
if (rec) Log(rec.length, rec[rec.length - 1]);
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
策略出处: https://www.botvs.com/strategy/14198
|
||||
策略名称: 商品期货交易类库(增加下限价单功能)
|
||||
策略作者: edwardgyw
|
||||
策略描述:
|
||||
|
||||
在原zero提供版本基础上,增加了下限价单和平限价单的功能,方便埋单
|
||||
增加了判断当前是否是交易时段的功能,同时提供自定义节假日的功能
|
||||
|
||||
|
||||
参数 默认值 描述
|
||||
------------ ------- ----------
|
||||
Interval 500 失败重试间隔(毫秒)
|
||||
SlidePrice false 下单滑价(元)
|
||||
nightType true 商品夜盘情况
|
||||
holidaysList 5.1,5.2 节假日情况
|
||||
*/
|
||||
|
||||
function GetPosition(e, contractType, direction) {
|
||||
var allCost = 0;
|
||||
var allAmount = 0;
|
||||
var allProfit = 0;
|
||||
var allFrozen = 0;
|
||||
var posMargin = 0;
|
||||
var positions = _C(e.GetPosition);
|
||||
for (var i = 0; i < positions.length; i++) {
|
||||
if (positions[i].ContractType == contractType &&
|
||||
(((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) && direction == PD_SHORT))
|
||||
) {
|
||||
posMargin = positions[i].MarginLevel;
|
||||
allCost += (positions[i].Price * positions[i].Amount);
|
||||
allAmount += positions[i].Amount;
|
||||
allProfit += positions[i].Profit;
|
||||
allFrozen += positions[i].FrozenAmount;
|
||||
}
|
||||
}
|
||||
if (allAmount === 0) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
MarginLevel: posMargin,
|
||||
FrozenAmount: allFrozen,
|
||||
Price: _N(allCost / allAmount),
|
||||
Amount: allAmount,
|
||||
Profit: allProfit,
|
||||
Type: direction,
|
||||
ContractType: contractType
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Open(e, contractType, direction, opAmount, price) {
|
||||
var initPosition = GetPosition(e, contractType, direction);
|
||||
var isFirst = true;
|
||||
var initAmount = initPosition ? initPosition.Amount : 0;
|
||||
var positionNow = initPosition;
|
||||
while (true) {
|
||||
var needOpen = opAmount;
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
positionNow = GetPosition(e, contractType, direction);
|
||||
if (positionNow) {
|
||||
needOpen = opAmount - (positionNow.Amount - initAmount);
|
||||
}
|
||||
}
|
||||
var insDetail = _C(e.SetContractType, contractType);
|
||||
//Log("初始持仓", initAmount, "当前持仓", positionNow, "需要加仓", needOpen);
|
||||
if (needOpen < insDetail.MinLimitOrderVolume) {
|
||||
break;
|
||||
}
|
||||
var depth = _C(e.GetDepth);
|
||||
var pr = price;
|
||||
if (!price) pr = direction == PD_LONG ? depth.Asks[0].Price : depth.Bids[0].Price;
|
||||
var amount = Math.min(insDetail.MaxLimitOrderVolume, needOpen);
|
||||
e.SetDirection(direction == PD_LONG ? "buy" : "sell");
|
||||
var orderId;
|
||||
if (direction == PD_LONG) {
|
||||
orderId = e.Buy(pr + SlidePrice, Math.min(amount, depth.Asks[0].Amount), contractType, 'Ask', depth);
|
||||
} else {
|
||||
orderId = e.Sell(pr - SlidePrice, Math.min(amount, depth.Bids[0].Amount), contractType, 'Bid', depth);
|
||||
}
|
||||
// CancelPendingOrders
|
||||
while (true) {
|
||||
Sleep(Interval);
|
||||
var orders = _C(e.GetOrders);
|
||||
if (orders.length === 0) {
|
||||
break;
|
||||
}
|
||||
for (var j = 0; j < orders.length; j++) {
|
||||
e.CancelOrder(orders[j].Id);
|
||||
if (j < (orders.length - 1)) {
|
||||
Sleep(Interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var ret = {
|
||||
price: 0,
|
||||
amount: 0,
|
||||
position: positionNow
|
||||
};
|
||||
if (!positionNow) {
|
||||
return ret;
|
||||
}
|
||||
if (!initPosition) {
|
||||
ret.price = positionNow.Price;
|
||||
ret.amount = positionNow.Amount;
|
||||
} else {
|
||||
ret.amount = positionNow.Amount - initPosition.Amount;
|
||||
ret.price = _N(((positionNow.Price * positionNow.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function Cover(e, contractType, price) {
|
||||
var insDetail = _C(e.SetContractType, contractType);
|
||||
while (true) {
|
||||
var n = 0;
|
||||
var positions = _C(e.GetPosition);
|
||||
for (var i = 0; i < positions.length; i++) {
|
||||
if (positions[i].ContractType != contractType) {
|
||||
continue;
|
||||
}
|
||||
while (positions[i].FrozenAmount !== 0) {
|
||||
var orders = _C(e.GetOrders);
|
||||
if (orders.length === 0) {
|
||||
break;
|
||||
}
|
||||
for (var j = 0; j < orders.length; j++) {
|
||||
e.CancelOrder(orders[j].Id);
|
||||
if (j < (orders.length - 1)) {
|
||||
Sleep(Interval);
|
||||
}
|
||||
}
|
||||
positions = _C(e.GetPosition);
|
||||
}
|
||||
var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount);
|
||||
var depth;
|
||||
if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
|
||||
depth = _C(e.GetDepth);
|
||||
var pr = price;
|
||||
if (!price) pr = depth.Bids[0].Price;
|
||||
e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
|
||||
e.Sell(pr - SlidePrice, Math.min(amount, depth.Bids[0].Amount), contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
|
||||
n++;
|
||||
} else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) {
|
||||
depth = _C(e.GetDepth);
|
||||
var pr = price;
|
||||
if (!price) pr = depth.Asks[0].Price;
|
||||
e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
|
||||
e.Buy(pr + SlidePrice, Math.min(amount, depth.Asks[0].Amount), contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (n === 0 || price) {
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
Sleep(Interval);
|
||||
var orders = _C(e.GetOrders);
|
||||
if (orders.length === 0) {
|
||||
break;
|
||||
}
|
||||
for (var j = 0; j < orders.length; j++) {
|
||||
e.CancelOrder(orders[j].Id);
|
||||
if (j < (orders.length - 1)) {
|
||||
Sleep(Interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var PositionManager = (function() {
|
||||
function PositionManager(e) {
|
||||
if (typeof(e) === 'undefined') {
|
||||
e = exchange;
|
||||
}
|
||||
if (e.GetName() !== 'Futures_CTP') {
|
||||
throw 'Only support CTP';
|
||||
}
|
||||
this.e = e;
|
||||
this.account = null;
|
||||
}
|
||||
PositionManager.prototype.GetAccount = function() {
|
||||
return _C(this.e.GetAccount);
|
||||
};
|
||||
|
||||
PositionManager.prototype.OpenLong = function(contractType, shares, price) {
|
||||
if (!this.account) {
|
||||
this.account = _C(exchange.GetAccount);
|
||||
}
|
||||
return Open(this.e, contractType, PD_LONG, shares, price, price);
|
||||
};
|
||||
|
||||
PositionManager.prototype.OpenShort = function(contractType, shares, price) {
|
||||
if (!this.account) {
|
||||
this.account = _C(exchange.GetAccount);
|
||||
}
|
||||
return Open(this.e, contractType, PD_SHORT, shares, price);
|
||||
};
|
||||
|
||||
PositionManager.prototype.Cover = function(contractType, price) {
|
||||
if (!this.account) {
|
||||
this.account = _C(exchange.GetAccount);
|
||||
}
|
||||
return Cover(this.e, contractType, price);
|
||||
};
|
||||
|
||||
PositionManager.prototype.Profit = function(contractType) {
|
||||
var accountNow = _C(this.e.GetAccount);
|
||||
return _N(accountNow.Balance - this.account.Balance);
|
||||
};
|
||||
|
||||
return PositionManager;
|
||||
})();
|
||||
|
||||
$.NewPositionManager = function(e) {
|
||||
return new PositionManager(e);
|
||||
};
|
||||
|
||||
function getHolidays(holidaysList) {
|
||||
if (!holidaysList) return {
|
||||
'mon': [],
|
||||
'day': []
|
||||
};
|
||||
var x = holidaysList.split(',');
|
||||
var t = {
|
||||
'mon': [],
|
||||
'day': []
|
||||
};
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
var m = x[i].split('.');
|
||||
t.mon.push(m[0]);
|
||||
t.day.push(m[1]);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
$.judgeTrading = function() {
|
||||
var now = new Date();
|
||||
var day = now.getDay();
|
||||
var mon = now.getMonth() + 1;
|
||||
var min = now.getMinutes();
|
||||
var date = now.getDate();
|
||||
var hours = now.getHours();
|
||||
var isHolidays = false;
|
||||
var holidays = getHolidays(holidaysList);
|
||||
//Log(holidays.mon.length);
|
||||
if (holidays) {
|
||||
for (var i = 0; i < holidays.mon.length; i++) {
|
||||
if (holidays.mon[i] == mon && holidays.day[i] == date) {
|
||||
isHolidays = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (day == 0 || day == 6 || isHolidays) return false;
|
||||
else if ((hours >= 9 && hours <= 11) || (hours >= 13 && hours < 15)) {
|
||||
if (hours == 11 && min >= 30) return false;
|
||||
else if (hours == 13 && min < 30) return false;
|
||||
else if ((hours == 10 && min >= 15) && (hours == 10 && min < 30)) return false;
|
||||
else return true;
|
||||
} else if (nightType == 1 && hours >= 21 && hours < 23) return true;
|
||||
else if (nightType == 2 && ((hours >= 21 && hours < 24) || (hours >= 0 && hours < 1 && day !== 1))) return true;
|
||||
//else if(nightType!==1&&nightType!==2) return true;
|
||||
else return false;
|
||||
};
|
||||
|
||||
//未成功登陆前要多次尝试login,所以写了一个准备交易的函数,可以放到main函数开头
|
||||
$.ready4ctp = function(contractType) {
|
||||
var insDetail;
|
||||
var retry = 0;
|
||||
while (!(insDetail = exchange.SetContractType(contractType)) && retry < 20) {
|
||||
Sleep(2000);
|
||||
retry++;
|
||||
}
|
||||
if (insDetail) Log("合约", insDetail.InstrumentName, "一手", insDetail.VolumeMultiple, "份, 最大下单量", insDetail.MaxLimitOrderVolume, "保证金率:", insDetail.LongMarginRatio, "交割日期", insDetail.StartDelivDate);
|
||||
else throw ('连接超时,请检查账号');
|
||||
return insDetail;
|
||||
};
|
||||
|
||||
function main() {
|
||||
$.ready4ctp('MA609');
|
||||
var isTrading = $.judgeTrading();
|
||||
Log('当前正在交易?:'+isTrading);
|
||||
var p = $.NewPositionManager();
|
||||
p.OpenShort("MA609", 1, 1000);
|
||||
Sleep(60000 * 10);
|
||||
p.Cover("MA609", 1000);
|
||||
p.Cover('MA609');
|
||||
LogProfit(p.Profit());
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
策略出处: https://www.botvs.com/strategy/15524
|
||||
策略名称: 图表模板
|
||||
策略作者: 小小梦
|
||||
策略描述:
|
||||
|
||||
图表模板
|
||||
|
||||
|
||||
参数 默认值 描述
|
||||
-------------- ----- ------
|
||||
indicatorsName 指标轴1 指标轴
|
||||
indicators_1 指标1 指标1
|
||||
indicators_2 指标2 指标2
|
||||
Interval 500 间隔(毫秒)
|
||||
*/
|
||||
|
||||
/*
|
||||
这个是一个图表模板,详细用法见广场帖子。
|
||||
|
||||
*/
|
||||
//图表
|
||||
var ChartObj = {//画图
|
||||
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
|
||||
chart: { zoomType:'x',panning:true },//图表类型
|
||||
title: { text: title}, //标题
|
||||
rangeSelector: {
|
||||
buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
|
||||
selected: 0,
|
||||
inputEnabled: false
|
||||
},
|
||||
subtitle: {text: subtitle},//副标题
|
||||
xAxis:{type: 'datetime'},
|
||||
yAxis: [{
|
||||
title: {text: 'K线'},//标题
|
||||
style: {color: '#4572A7'},//样式
|
||||
opposite: false //生成右边Y轴
|
||||
},
|
||||
{
|
||||
title:{text: indicatorsName},
|
||||
opposite: true //生成右边Y轴 ceshi
|
||||
}
|
||||
],
|
||||
series: [//系列
|
||||
{type:'candlestick',yAxis:0,name:'K',id:'KLine',data:[]},
|
||||
{type:'flags',onSeries:'KLine',data:[]},
|
||||
{name:indicators_1,type:'spline',yAxis:1,data:[]},
|
||||
{name:indicators_2,type:'spline',yAxis:1,data:[]}
|
||||
]
|
||||
};
|
||||
var chart = Chart(ChartObj);
|
||||
var isFirst = true;
|
||||
var preRecordTime = 0;
|
||||
var title = exchange.GetName();
|
||||
var subtitle = indicators_1+"、"+indicators_2+"指标走势";
|
||||
function Draw(records){
|
||||
var strState = "";
|
||||
var fcolor = "";
|
||||
var msg = "";
|
||||
while(!records || records.length < 5){
|
||||
records = exchange.GetRecords();
|
||||
LogStatus("获取K线中...records.length:",records === null ? "records is null" : records.length);
|
||||
Sleep(Interval);
|
||||
}
|
||||
if(isFirst === true){
|
||||
chart.reset();
|
||||
isFirst = false;
|
||||
preRecordTime = records[records.length - 1].Time;
|
||||
}
|
||||
if(preRecordTime === records[records.length - 1].Time){
|
||||
chart.add([0,[records[records.length - 1].Time,records[records.length - 1].Open,records[records.length - 1].High,records[records.length - 1].Low,records[records.length - 1].Close ],-1]);
|
||||
}else{
|
||||
//更新前一柱
|
||||
chart.add([0,[records[records.length - 2].Time,records[records.length - 2].Open,records[records.length - 2].High,records[records.length - 2].Low,records[records.length - 2].Close ],-1]);
|
||||
|
||||
chart.add([0,[records[records.length - 1].Time,records[records.length - 1].Open,records[records.length - 1].High,records[records.length - 1].Low,records[records.length - 1].Close ]]);
|
||||
|
||||
preRecordTime = records[records.length - 1].Time;
|
||||
}
|
||||
chart.update(ChartObj);
|
||||
chart.reset(500);
|
||||
}
|
||||
function SignOP(time,price,amount,state){
|
||||
var msg = "";
|
||||
msg = "均价:"+price+"币数:"+amount;
|
||||
switch(state){
|
||||
case 1:strState = "开多仓";fcolor = "red";break;
|
||||
case 2:strState = "开空仓";fcolor = "green";break;
|
||||
case 0:strState = "平仓";fcolor = "blue";break;
|
||||
}
|
||||
chart.add(1, {x:time, color: fcolor , shape: 'flag', title: strState, text: msg});
|
||||
}
|
||||
$.SignOP = function(time,price,amount,state){
|
||||
if(arguments.length < 4){
|
||||
Log("SignOP 函数 必须传入4个参数 : time、price、amount、state");
|
||||
return;
|
||||
}
|
||||
SignOP(time,price,amount,state);
|
||||
};
|
||||
$.Draw = function(records){
|
||||
Draw(records);
|
||||
};
|
||||
//ceshi
|
||||
function main(){
|
||||
var i = 0;
|
||||
var records = exchange.GetRecords();
|
||||
|
||||
while(i < 50000){
|
||||
if(i===2000){
|
||||
//Sleep(60*60*1000);
|
||||
SignOP((new Date()).getTime(),2900,1,1);
|
||||
}
|
||||
Draw(records);
|
||||
Sleep(20000);
|
||||
records = exchange.GetRecords();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
策略出处: https://www.botvs.com/strategy/15098
|
||||
策略名称: 定时测试微信消息推送
|
||||
策略作者: 小小梦
|
||||
策略描述:
|
||||
|
||||
定时测试微信消息推送 范例~抛砖引玉,方便用户参考学习。
|
||||
|
||||
*/
|
||||
|
||||
function main(){
|
||||
var initTime = (new Date()).getTime() ;
|
||||
Log("程序起始时间:",$.getTimeByNormal(initTime) );
|
||||
var preDif = 0;
|
||||
var str = "";
|
||||
while(true){
|
||||
var nowTime = (new Date()).getTime();
|
||||
if( Math.floor((nowTime - initTime) / (1000*60*10) ) !== preDif ){
|
||||
str = $.getTimeByNormal(nowTime);
|
||||
Log("从程序开始执行,已过10分钟!提醒。"+"--现在时间:"+str+"推送微信@" );
|
||||
preDif = Math.floor((nowTime - initTime) / (1000*60*10) ) ;
|
||||
}
|
||||
Sleep(2000);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ function getTimeByNormal(time){
|
||||
|
||||
//测试
|
||||
function main() {
|
||||
var time1 = $.getTimeByNormal( new Date() );
|
||||
var time1 = $.getTimeByNormal( 1463308260000 );
|
||||
Log("当前时间time1:",time1);
|
||||
Sleep(1000 * 60);
|
||||
var time3 = (new Date()).getTime();
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
策略出处: https://www.botvs.com/strategy/15085
|
||||
策略名称: 非常简单的策略,但是很有效
|
||||
策略作者: jiebang
|
||||
策略描述:
|
||||
|
||||
"Talk is cheap. Show me the code"
|
||||
|
||||
|
||||
注: ` 策略使用了交易模板类库`
|
||||
|
||||
`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响`
|
||||
|
||||
https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png
|
||||
|
||||
|
||||
参数 默认值 描述
|
||||
------------- ----- -------
|
||||
FastPeriod 5 入市快线周期
|
||||
SlowPeriod 30 入市慢线周期
|
||||
EnterPeriod 2 入市观察期
|
||||
PositionRatio true 仓位比例
|
||||
Interval 10 轮询周期(秒)
|
||||
SlidePrice 0.01 滑动值
|
||||
*/
|
||||
|
||||
function main()
|
||||
{
|
||||
var STATE_IDLE = -1;
|
||||
var state = STATE_IDLE;
|
||||
var initAccount = $.GetAccount();
|
||||
var price = 0;
|
||||
Log(initAccount);
|
||||
while (true)
|
||||
{
|
||||
ticker = exchange.GetTicker();
|
||||
var nowAccount = $.GetAccount();
|
||||
|
||||
var n = $.Cross(FastPeriod, SlowPeriod);
|
||||
if (Math.abs(n) >= EnterPeriod && Math.abs(n) < EnterPeriod +1 )
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
price = ticker.Sell;
|
||||
var opAmount = parseFloat((nowAccount.Balance * PositionRatio/(ticker.Sell+SlidePrice)).toFixed(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
price = ticker.Buy;
|
||||
var opAmount = nowAccount.Stocks;
|
||||
}
|
||||
if (opAmount> exchange.GetMinStock())
|
||||
{
|
||||
var obj = n > 0 ? exchange.Buy(price, opAmount) : $.Sell(price, opAmount);
|
||||
if (obj)
|
||||
{
|
||||
opAmount = obj.amount;
|
||||
// state = n > 0 ? PD_LONG : PD_SHORT;
|
||||
Log("开仓详情", obj, "交叉周期", n, "币:", nowAccount.Stocks);
|
||||
LogProfit(nowAccount.Balance + nowAccount.Stocks * ticker.Last , '钱');
|
||||
}
|
||||
/*else
|
||||
{
|
||||
continue;
|
||||
} */
|
||||
}
|
||||
}
|
||||
Sleep(Interval*1000);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user